Forum: Mikrocontroller und Digitale Elektronik Abstandsmessung mit Ultraschall - Verständnis


von Klaus (Gast)


Lesenswert?

Hallo
Ich versuche mit einem Atmega 8 und einem HC-SR04 den Abstand zu einer 
Wand zu messen. Habe alles auf einem Board aufgebaut und versuche die 
Grundlagen zu begreiffen. Gemäss DB ist die Funktionsweise und 
Anschlüsse am SR04 klar und habe entsprecehnden Pins zugeordnet. Dazu 
noch die LEDs.
1
#define LED1_ON PORTA &=~(1<<PINA5);  // LED 4 ein
2
#define LED1_OFF PORTA |=(1<<PINA5);  // LED 4 aus
3
#define LED2_ON PORTA &=~(1<<PINA7);  // LED 3 ein
4
#define LED2_OFF PORTA |=(1<<PINA7);  // LED 3 aus
5
#define LED3_ON PORTB &=~(1<<PINB2);  // LED 2 ein
6
#define LED3_OFF PORTB |=(1<<PINB2);  // LED 2 aus
7
8
#define Trigger_ON PORTA &=~(1<<PINA0);  // A0 ein
9
#define Trigger_OFF PORTA |=(1<<PINA0);  // A0 aus
10
11
#define ECHO PORTA &=~(1<<PINA1);  // Echon an A1 
12
13
#define Abstand
14
15
int16_t cm=0;
16
    Trigger_ON;   // A0 ein
17
    _delay_us(10);
18
    Trigger_OFF;  // A0 aus
Es sollen mal 3 LEDs werden, fange aber mit 2 an.Je dichter die Wand ran 
ist soll eine LED aufleuchten. Gedacht alles für einen Abstandswarner 
für die Garage. Die Auswertung will ich damit machen:
1
if(Abstand > 30000)
2
      {
3
      LED1_ON;
4
      LED2_OFF;
5
      }
6
    else
7
      {
8
      LED1_OFF;
9
      LED2_ON;
10
      }
Kommen wir zum Problem. Habe im Netz gesucht und Beispiel mit 1 oder 2 
Timern gefunden. Bin mir aber nicht sicher was gebraucht wird. Will es 
mit Timer machen, da vielleicht noch ein Attiny auf die Platine kommt.
Dann wird immer 58us erwähnt. Konnte leider noch  nicht verstehen wozu 
das notwendig ist.
In dem Beispiel von Stefan steht drin
- Zuerst sendet man einen Trigger Impuls mit 10ys Dauer
- kurze Zeit später antwortet der Sensor mit einem Echo Impuls
- Nun ermittelt das Programm die Puls Breite in 58us Intervallen
- Die Anzahl der Intervalle ist schon das Messergebnis in Zentimeter
Soweit Stefans Angaben.
Wenn ich das richtig verstehe brauche ich einen Timer mit 58us. Müsste 
als ein 16 Bit Timer sein im CTC Modus. Muss ihn starten wenn der Impuls 
gesendet wird und wie stoppen?
Kennt jemand ein gutes Tut um das zu verstehen?
Die meisten Beispiel im Netz sind mit Anzeige in cm oder inch.
LG Klaus

von steff (Gast)


Lesenswert?

Klaus schrieb:
> In dem Beispiel von Stefan

Ahja. Und wer ist Stefan? Und was ist sein Beispiel?

von Nautilus (Gast)


Lesenswert?

Die 58µs ergeben sich aus der Schallgeschwindigkeit.
Der Timer muss zum ermitteln des Wertes nicht gestoppt werden.
Dieser Timer muss nach dem Ablauf der 58µs einen Interrupt auslosen.
In der Interruptroutine wird abgefragt, ob der Sensor das reflektierte 
Signal empfangen hat. Wenn nein die Zählervariable erhöhen und Routine 
verlassen. Wenn ja Zählervariable erhöhen und das Ergebnis der 
Auswerteroutine zuführen. Danach Zählervariable zurücksetzen, Timer 
stoppen (Timerregister).

von Klaus (Gast)


Lesenswert?

Text von Stefan Frings:
Ultraschall Sensor HC-SR04
Mit diesem Ultraschall Sensor kann man die Distanz zu einem Objekt 
messen. Der Sensor sendet ein klickendes Geräusch im Ultraschall-Bereich 
aus, um anschließend die Verzögerung des Echos zu messen. Je größer die 
Distanz zum nächsten Objekt, umso später kommt das Echo zurück.
Ich bin mit diesem Sensor sehr zufrieden. Er ist mit seinen 2€ pro Stück 
äußerst preisgünstig und liefert trotzdem zuverlässige stabile 
Messergebnisse.
Im obigen Aufbau benutze ich ein Arduino Nano Modul, um den Sensor 
anzusteuern und die Messergebnisse in einem Terminalprogramm auf meinem 
PC anzuzeigen. Der Sensor ist an Port D2 (Trigger) und D3 (Echo) 
angeschlossen.

Technische Daten
•  Spannungsversorgung: 5V 15mA
•  Ruhestromaufnahme: < 2mA
•  Distanz: 2cm - 400cm
•  Erfassungs-Winkel: ca. 45° im Nahbereich und < 15° bei maximaler 
Distanz
•  Eingang Trigger-Impuls: positiv 10µs
•  Ausgang Echo-Impuls: positiv 58µs pro Zentimeter, 148µs pro Inch

Der Ausgangs-Impuls beginnt etwa 500µs nach dem Trigger. Seine Länge ist 
ein Indiz für die Distanz zum nächsten reflektierenden Objekt. Wenn der 
Sensor kein Echo empfängt, ist der Ausgangsimpuls 38ms lang.
Vor dem nächsten Trigger soll man mindestens 50ms abwarten, um 
Refexionen des vorherigen Impulses abklingen zu lassen.

Programmierung
Die Programmierung ist ganz simpel:
•  Zuerst sendet man einen Trigger-Impuls mit 10µs Dauer.
•  Kurze Zeit später antwortet der Sensor mit einem Echo-Impuls.
•  Nun ermittelt das Programm die Puls-Breite in 58µs Intervallen.
•  Die Anzahl der Intervalle ist schon das Messergebnis in Zentimetern.

Wenn man so vorgeht, braucht man keine "teure" Division mit 
Fließkommazahlen.
1
#include <stdio.h>
2
#include <stdint.h>
3
#include <util/delay.h> 
4
#include <avr/io.h>
5
#include "driver/serialconsole.h"
6
// The settings for the serial port are in driver/serialconsole.h
7
8
// The LED is connected to Port B5 and GND.
9
#define LED_ON  { DDRB |= (1<<PB5); PORTB |= (1<<PB5); }
10
#define LED_OFF { PORTB &= ~(1<<PB5);  }
11
12
// The Ultrasonic sensor is connected to Port D2 and D3
13
#define TRIGGER_ON   { DDRD |= (1<<PD2); PORTD |= (1<<PD2); }
14
#define TRIGGER_OFF  { PORTD &= ~(1<<PD2); }
15
#define ECHO_SIGNAL  ( PIND & (1<<PD3) )
16
17
int main(void) 
18
  {   
19
    initSerialConsole();
20
    while(1)
21
      {
22
        int16_t cm=0;
23
        LED_ON;          
24
        // Trigger a measurement
25
        TRIGGER_ON;
26
        _delay_us(10);
27
        TRIGGER_OFF;
28
        // Wait for response
29
        while (!ECHO_SIGNAL);
30
        // Measure pulse width  
31
        while (ECHO_SIGNAL)
32
          {
33
            _delay_us(58);
34
            cm++;
35
          }     
36
        LED_OFF;    
37
        // Output the result     
38
        printf("%i cm\n",cm);         
39
        // Delay 1 second before next loop
40
        _delay_ms(1000);
41
      }
42
  }
Stefan nutzt einen Arduino und zeigt die Ergebnisse auf dem PC. Die .h 
Bib fehlt noch.

von Klaus (Gast)


Lesenswert?

Der Timer 2 sieht so aus:
1
// Timer 2 mit 16 MHz und 58us:
2
void timer2_init()          // Timer 2, 16 Bit, 16MHz, 1ms
3
  {                  // Timer 2 konfigurieren
4
  TCCR2A = (1<<WGM01);      // Auswahl CTC Modus
5
  TCCR2B = (1<<CS01);        // Prescaler auf 64 setzen
6
  OCR2A=115;            // Wert für 58us
7
  TIMSK2|=(1<<OCIE2A);      // Interrupt erlauben
8
  }
9
10
ISR (TIMER2_COMPA_vect)        // ISR für Timer 2
11
  {
12
  // ISR Programm für Timer 2
13
  }
Die Berechnung der Zeit habe ich mit dem AVR Calculator gemacht

von Schlaumaier (Gast)


Lesenswert?

Nautilus schrieb:
> Die 58µs ergeben sich aus der Schallgeschwindigkeit.
> Der Timer muss zum ermitteln des Wertes nicht gestoppt werden.
> Dieser Timer muss nach dem Ablauf der 58µs einen Interrupt auslosen.
> In der Interruptroutine wird abgefragt, ob der Sensor das reflektierte
> Signal empfangen hat. Wenn nein die Zählervariable erhöhen und Routine
> verlassen. Wenn ja Zählervariable erhöhen und das Ergebnis der
> Auswerteroutine zuführen. Danach Zählervariable zurücksetzen, Timer
> stoppen (Timerregister).

Habe ich irgendwie anders verstanden.

Ich gebe ein Signal ab, und warte bis die Antwort kommt. Die Zeit 
dazwischen messe ich, und weiß aufgrund der Schallgeschwindigkeit / 2 
(hin-/ +Rückflug)
 wie hoch die Entfernung ist.

Das erledigt zwar bei mir ein Libs (ich mag nicht mehr Arbeit machen als 
Nötig) aber das ist egal.

Da die Schallgeschwindigkeit ca 1235 km/h beträgt und die Reichweite bei 
den kleinen Modulen kaum 3 Meter sind, dürfte die Antwort nur wenige ms 
dauern wenn überhaupt so lange, müsste ich nachrechnen.

von Klaus (Gast)


Lesenswert?

Habe jetz gesehen, das im Kommentar 64 steht aber der Timer auf 
Prescaler 8 gesetzt ist, Kpommentar falsch.
Nautilus schrieb:
> Die 58µs ergeben sich aus der Schallgeschwindigkeit.

Die 58us sind für die Angabe in cm, wenn ich inch verwende ergibt sich 
was um die 150. ist klar.

Nautilus schrieb:
> Dieser Timer muss nach dem Ablauf der 58µs einen Interrupt auslosen.

Wenn mein Timer stimmt löst er nach 58us einen Interrupt aus.

Nautilus schrieb:
> In der Interruptroutine wird abgefragt, ob der Sensor das reflektierte
> Signal empfangen hat. Wenn nein die Zählervariable erhöhen und Routine
> verlassen. Wenn ja Zählervariable erhöhen und das Ergebnis der
> Auswerteroutine zuführen.

Wie ich das mache ist mir noch unklar. Habe als Variable den " Abstand" 
drin.
Wenn ich das angehe muss ich
1
ISR (TIMER2_COMPA_vect)        // ISR für Timer 2
2
  {
3
  Overflows++
4
  }
und dann kann
1
Abstand = (Overflows * 65536) + EndTime - StartTime;
Muss dann noch EndTime und StartTime suchen.

von Klaus (Gast)


Lesenswert?

Schlaumaier schrieb:
> Das erledigt zwar bei mir ein Libs (ich mag nicht mehr Arbeit machen als
> Nötig) aber das ist egal.

Das mit der Lib finde ich gut, möchte aber erst mal verstehen wie es 
geht.

von Schlaumaier (Gast)


Lesenswert?

Klaus schrieb:
> Abstand = (Overflows * 65536) + EndTime - StartTime;

Komische Formel

Abstand_in_cm = (end_time - Start_time) * laufzeit_in_cm

So wird ein Schuh draus.

von HildeK (Gast)


Lesenswert?

Schlaumaier schrieb:
> Abstand_in_cm = (end_time - Start_time) * laufzeit_in_cm

Noch komischere Formel 🙄.
Wenn schon, dann:
Abstand_in_cm = (end_time - Start_time)[s] * Schallgeschwindigkeit in 
cm/s

von Mops (Gast)


Lesenswert?

HildeK schrieb:
> Schlaumaier schrieb:
>> Abstand_in_cm = (end_time - Start_time) * laufzeit_in_cm
>
> Noch komischere Formel 🙄.
> Wenn schon, dann:
> Abstand_in_cm = (end_time - Start_time)[s] * Schallgeschwindigkeit in
> cm/s

Vergaßt Du zwei Klammern?

von Klaus (Gast)


Lesenswert?

Jetzt komme ich aber durcheinadner. Was stimmt den nun?

Schlaumaier schrieb:
> Abstand_in_cm = (end_time - Start_time) * laufzeit_in_cm

oder

HildeK schrieb:
> Abstand_in_cm = (end_time - Start_time)[s] * Schallgeschwindigkeit in
> cm/s

Die Schallgeschwindigkeit ist ein relativ feststehender Wert, nur 
beeinflusst durch Temp und Feuchtigkeit.
Die Laufzeit ist abhängig von der Entfernung.

von malsehen (Gast)


Lesenswert?

Schlaumaier schrieb:
> laufzeit_in_cm

Alles klar.

von Sebastian W. (wangnick)


Lesenswert?

Ich benutze den ICP für die Abstandsmessung:
1
static const uint8_t ticksperus = clockCyclesPerMicrosecond() / 8;
2
static const uint32_t halfsos = 17145; // 171.45 2m/s = 17145 2cm/s
3
TCCR1A = 0;
4
TCCR1B = (1<<CS11);         // Prescaler 8
5
TCCR1C = 0;
6
Trigger/Echo -> LOW
7
delayMicroseconds(10);
8
Trigger/Echo -> HIGH
9
delayMicroseconds(10);
10
Trigger/Echo -> LOW
11
delayMicroseconds(10);
12
Trigger/Echo -> INPUT
13
delayMicroseconds(10);
14
TCNT1 = 0;
15
TCCR1B |= (1<<ICES1);            // Capture on rising edge of ICP1. 
16
TIFR1 |= (1<<ICF1) | (1<<TOV1);
17
while ((TIFR1 & ((1<<ICF1)|(1<<TOV1))) == 0) continue;
18
if (TIFR1 & (1<<ICF1)) {
19
  uint16_t stick = ICR1;
20
  TCCR1B &= ~(1<<ICES1);        // Capture on falling edge of ICP1
21
  TIFR1 |= (1<<ICF1);
22
  while ((TIFR1 & ((1<<ICF1)|(1<<TOV1))) == 0) continue;
23
  if (TIFR1 & (1<<ICF1)) {
24
    uint16_t etick = ICR1;
25
    uint32_t dus = (etick-stick)*10/ticksperus; // decimicroseconds
26
    uint16_t dmm = (dus*halfsos+50000UL)/100000UL; // Distance in decimillimeter  
27
  }
28
}

Ich spare mir auch einen Pin des uC indem ich Trigger mit ICP1 verbinde 
und Echo über 1k mit Trigger/ICP1 verbinde.

LG, Sebastian

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Klaus schrieb:
> Zuerst sendet man einen Trigger Impuls mit 10ys Dauer
> - kurze Zeit später antwortet der Sensor mit einem Echo Impuls
> - Nun ermittelt das Programm die Puls Breite in 58us Intervallen

eher den Abstand zwischen den beiden Pulsen

> - Die Anzahl der Intervalle ist schon das Messergebnis in Zentimeter
> Soweit Stefans Angaben.

Ja. Schall braucht in Luft 2,9 ms pro Meter, also 29 µs pro cm. Da man 
ja einmal hin und wieder zurück muss, braucht der Schall doppelt so viel 
Zeit, also entsprechen 58 µs einem Zentimeter Abstand.


Klaus schrieb:
> Jetzt komme ich aber durcheinadner. Was stimmt den nun?
>
> Schlaumaier schrieb:
>> Abstand_in_cm = (end_time - Start_time) * laufzeit_in_cm

Diese Formel ergibt keinerlei Sinn.

> oder
>
> HildeK schrieb:
>> Abstand_in_cm = (end_time - Start_time)[s] * Schallgeschwindigkeit in
>> cm/s
>
> Die Schallgeschwindigkeit ist ein relativ feststehender Wert, nur
> beeinflusst durch Temp und Feuchtigkeit.

Ja. Natürlich muss sie aber in die Formel eingehen, da du den Abstand ja 
darüber ermitteln willst, wie lange der Schall braucht. Diese Dauer ist 
selbstverständlich von der Schallgeschwindigkeit abhängig.

> Die Laufzeit ist abhängig von der Entfernung.

Und was ist end_time - Start_time?

Die Formeln oben stimmen also beide nicht. Die zweite ergibt aber 
zumindest einen Sinn und hat nur den Faktor 2 wegen hin und zurück 
vergessen.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Klaus schrieb:
> Text von Stefan Frings

Warum setzt du nicht einfach einen Link auf die Webseite, anstatt sie 
komplett abzuschreiben? http://stefanfrings.de/hc-sr04/index.html

Je mehr Seiten thematisch passend miteinander verknüpft werden, umso 
besser wird das Netz. OK, das klingt nach 80er Jahre Mentalität - ist es 
auch, aber trotzdem noch richtig.

von Stefan F. (Gast)


Lesenswert?

Schlaumaier schrieb:
> Ich gebe ein Signal ab, und warte bis die Antwort kommt. Die Zeit
> dazwischen messe ich

Nein. Du gibst das Startsignal und wartest ab, bis der Sensor antwortet. 
Dann misst du die Breite (Dauer) des Antwort-Impulses.

Die Zeit zwischen Startsignal und Antwort sagt nichts über die Distanz 
aus.

von Wolfgang (Gast)


Lesenswert?

Schlaumaier schrieb:
> Da die Schallgeschwindigkeit ca 1235 km/h beträgt und die Reichweite bei
> den kleinen Modulen kaum 3 Meter sind, dürfte die Antwort nur wenige ms
> dauern wenn überhaupt so lange, müsste ich nachrechnen.

Was willst du uns mit deinem Palaver sagen?
Du hättest wirklich wenigstens nachrechnen können.
Meist wird die Schallgeschwindigkeit in m/s angegeben. Das macht das 
Kopfrechnen leichter. Damit hättest du dir deine peinlichen Zweifel 
"wenn überhaupt so lange" erspart.
Bei ziemlich genau 6 ms pro Entfernungsmeter sind es immerhin fast 18 
ms.

von Klaus (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Warum setzt du nicht einfach einen Link auf die Webseite, anstatt sie
> komplett abzuschreiben? http://stefanfrings.de/hc-sr04/index.html

Finde deine Antwort vollkommen zutreffend. Leider habe ich auch schon 
Antworten gesehen, die sich beklagen was sie noch alles im Netz suchen 
sollen und das Programm nicht gleich angeben. Egal wie man es macht, es 
ist verkehrt. Du benutzt eine Auswertung am PC. Ich versuche eine 
Anzeige per LEDs zu machen, Beipiel dazu "Einparkhilfe für Garage".

von Stefan F. (Gast)


Lesenswert?

Klaus schrieb:
> Ich versuche eine Anzeige per LEDs zu machen,
> Beipiel dazu "Einparkhilfe für Garage".

Dazu kannst du doch auch einfach Warteschleifen (delay) benutzen. Oder 
soll dein µC nebenbei noch die Waschmaschine steuern?

von Hugo H. (hugo_hu)


Lesenswert?

Klaus schrieb:
> Du benutzt eine Auswertung am PC. Ich versuche eine
> Anzeige per LEDs zu machen, Beipiel dazu "Einparkhilfe für Garage".

Was hindert Dich daran, statt
1
       LED_OFF;    
2
        // Output the result     
3
        printf("%i cm\n",cm);         
4
        // Delay 1 second before next loop
5
        _delay_ms(1000);

einfach
1
     if(cm > 300)     //oder wieviel auch immer
2
      {
3
      LED1_ON;
4
      LED2_OFF;
5
      }
6
    else
7
      {
8
      LED1_OFF;
9
      LED2_ON;
10
      }
11
      // Delay 1 second before next loop
12
      _delay_ms(1000);

zu schreiben?

Der Rest passt doch, wenn Du nicht noch Rechenzeit für das SETI-Projekt 
abgeben willst.

: Bearbeitet durch User
von Otto (Gast)


Lesenswert?

Schlaumaier schrieb:
> Abstand_in_cm = (end_time - Start_time) * laufzeit_in_cm
>
> So wird ein Schuh draus.

"Zeit_in_cm" - ne, einen Schuh gibt das nicht, noch nicht mal löchrige 
Schlappen. Ich erklärs dir ein ander mal: Meine Uhr zeigt schon 112cm, 
bin dann mal weg...

von Klaus (Gast)


Lesenswert?

Habe das Programm jetzt so geschrieben. Es lässt sich ohne Fehler 
übersetzen.
1
#define F_CPU 16000000UL    // Angabe der Frequenz, wichtig für die Zeit
2
#include "util/delay.h"      // Einbindung Datei Pause
3
#include "avr/io.h"        // Einbindung Datei Ausgänge
4
#include "avr/interrupt.h"
5
6
#define LED1_ON PORTA &=~(1<<PINA5);  // LED 4 ein grün
7
#define LED1_OFF PORTA |=(1<<PINA5);  // LED 4 aus grün
8
#define LED2_ON PORTA &=~(1<<PINA7);  // LED 3 ein gelb
9
#define LED2_OFF PORTA |=(1<<PINA7);  // LED 3 aus gelb
10
#define LED3_ON PORTB &=~(1<<PINB2);  // LED 2 ein rot
11
#define LED3_OFF PORTB |=(1<<PINB2);  // LED 2 aus rot
12
13
#define Trigger_ON PORTA &=~(1<<PINA0);  // A0 ein
14
#define Trigger_OFF PORTA |=(1<<PINA0);  // A0 aus
15
16
#define ECHO PORTA &=~(1<<PINA1);    // Echo an A1 
17
18
volatile unsigned int Abstand = 0;
19
20
volatile unsigned char Overflows = 0;  // Anzahl Timer Overflows die während der Messung passiert sind
21
volatile unsigned int StartTime = 0;  // ICR Wert bei 1. High Flanke speichern
22
23
ISR (TIMER1_CAPT_vect)          // ISR für Timer 1
24
  {
25
  static unsigned char Erste_Flanke;
26
  if (Erste_Flanke)
27
    {
28
    StartTime = ICR1;
29
    TCCR1A = (0<<ICES1);    
30
    }
31
  else
32
    {
33
    Overflows = ICR1-StartTime;
34
    TCCR1A = (1<<ICES1); 
35
    Abstand = Overflows;
36
    }
37
  }
38
39
int main(void)
40
  {
41
  DDRA=0b10100000;      // DDR A auf Ausgang schalten
42
  PORTA=0b10100000;      // Port A auf aus
43
  DDRB=0b00000100;      // DDR B auf Ausgang schalten
44
  PORTB=0b00000100;      // Port B auf aus
45
  
46
  TCCR1A = (1<<ICES1)|(1<<WGM12);  // steigende Flanke, Auswahl CTC Modus, Mode 2
47
  TCCR1B = (1<<CS01);        // Prescaler auf 8 setzen
48
  OCR1A=115;            // Wert für 58us
49
  TIMSK1 =(1<<TOIE1)|(1<<OCIE1A);  // überlauf freigabe, Interrupt freigabe
50
  PCMSK1 =(1<<PCINT11);      // Angabe des PA1 als Eingang Echo
51
  
52
  sei();            // Interrupt ein
53
  while(1)          // Programmschleife
54
    {
55
    Abstand = 0;  
56
    Trigger_ON;   // A0 ein
57
    _delay_us(10);
58
    Trigger_OFF;  // A0 aus
59
    
60
    if(Abstand >= 10000)
61
      {
62
      LED1_ON;      // A5
63
      LED2_OFF;      // A7
64
      }
65
    else
66
      {
67
      LED1_OFF;      // A5
68
      LED2_ON;      // A7
69
      } 
70
      _delay_ms(100);
71
    }
72
  }
Die gelbe LED leuchtet ständig. Da habe ich noch einen Denkfehler drin. 
Hat jemand eine Idee dazu?

von Heiner (Gast)


Lesenswert?

Du fragst in der ISR "Erste_Flanke" ab (ist ja static) - wo soll denn 
dieses Flag gesetzt bzw rückgesetzt werden?
Wie fkt denn Deine "else" Abfrage in der ISR??

von Heiner (Gast)


Lesenswert?

Und die grüne LED wird korrekt gesetzt??

von Cyblord -. (cyblord)


Lesenswert?

Mein Gott, jetzt sind diese Sensoren schon so popelig. Trigger setzen. 
Zeit messen.
Wie einfach darf es noch sein?
Wie kann man sich anstellen?
Wie wärs mit Denken statt Code-Schnipsel zusammenzusetzen?
Die Auswertung ist in ein paar Minuten from Scratch geschrieben.
Es gibt überall Input-Capture Funktionen in den Timern. Wie dafür 
gemacht.

Es gibt auch I2C Versionen. Die Speichern den Abstand in einem Register.
Sogar für Multi-Echos.
Das gibt dann aber wieder Stress weil man den I2C Bus nicht kapiert und 
nicht nutzen kann.

: Bearbeitet durch User
von Heiner (Gast)


Lesenswert?

Cyblord -. schrieb:
> Mein Gott, jetzt sind diese Sensoren schon so popelig. Trigger
> setzen.
> Zeit messen.
> Wie einfach darf es noch sein?
> Wie kann man sich anstellen?
> Wie wärs mit Denken statt Code-Schnipsel zusammenzusetzen?

> Das gibt dann aber wieder Stress weil man den I2C Bus nicht kapiert und
> nicht nutzen kann.

Ne, Klaus kennt sich schon recht gut mit dem I2C Bus aus, da er ja 
ständig damit arbeitet und schon etliche “Tuts” in einem anderen Forum 
veröffentlicht hat 😉

von Cyblord -. (cyblord)


Lesenswert?

Heiner schrieb:
> Ne, Klaus kennt sich schon recht gut mit dem I2C Bus aus, da er ja
> ständig damit arbeitet und schon etliche “Tuts” in einem anderen Forum
> veröffentlicht hat 😉

Ich frage wie er neben der Promotion in Theoretischer Physik und seinem 
Job als Astronaut und Call-Boy, dafür noch Zeit findet.

von Heiner (Gast)


Lesenswert?

Cyblord -. schrieb:

> Ich frage wie er neben der Promotion in Theoretischer Physik und seinem
> Job als Astronaut und Call-Boy, dafür noch Zeit findet.

Na wenn die 24 Stunden des Tages nicht reichen, werden die 12 Stunden 
der Nacht hinzugenommen 😂

von Klaus (Gast)


Lesenswert?

Leider sind für mich einige Sachen nicht so poplig. Jedes Teil, egal ob 
Sensor oder Display, hat für mich einiges an Anforderungen. Mit Timer 
arbeite ich schon länger, aber nicht mit der Zeitmessung. Was für dich 
leicht fällt und du nur ein paar Zeilen brauchst, ist für mich eine ganz 
schöne Herausforderung.

von Heiner (Gast)


Lesenswert?

Heiner schrieb:
> Du fragst in der ISR "Erste_Flanke" ab (ist ja static) - wo soll denn
> dieses Flag gesetzt bzw rückgesetzt werden?
> Wie fkt denn Deine "else" Abfrage in der ISR??

Ich vermisse Deine Antwort auf obige Fragen.
"...Mit Timer arbeite ich schon länger, aber nicht mit der Zeitmessung. 
..."
Wo hast Du DA ein Problem?
Überhaupt empfehle ich Dir, doch mal Papier und Stift zu nehmen und 
aufzumalen, was denn das Programm machen soll...

von Hugo H. (hugo_hu)


Lesenswert?

Klaus schrieb:
> Jedes Teil, egal ob
> Sensor oder Display, hat für mich einiges an Anforderungen

Und warum willst Du dann für Deine kleine Anforderung unbedingt mit 
Timern arbeiten? Du weisst scheinbar überhaupt nicht, was Du da tust. 
Bringe doch erstmal die einfache Lösung von Stefan zum Laufen.

Außerdem bist Du ein Witzbold - Dein ATMega8 hat keinen Port A.

Aus Mitleid - weil ich heute meinen sozialen Tag habe :-) - mit Port D:
1
#define  F_CPU 16000000UL
2
#include <stdio.h>
3
#include <util/delay.h>
4
#include <avr/io.h>
5
6
#define LED_GREEN_ON  { DDRD  |=  (1<<PD4); PORTD |= (1<<PD4); }
7
#define LED_GREEN_OFF  { PORTD &= ~(1<<PD4);             }
8
9
#define LED_YELLOW_ON  { DDRD  |=  (1<<PD3); PORTD |= (1<<PD3); }
10
#define LED_YELLOW_OFF  { PORTD &= ~(1<<PD3);       }
11
12
#define LED_RED_ON    { DDRD  |=  (1<<PD2); PORTD |= (1<<PD2); }
13
#define LED_RED_OFF    { PORTD &= ~(1<<PD2);       }
14
15
// The Ultrasonic sensor is connected to Port D2 and D3
16
#define TRIGGER_ON    { DDRD  |=  (1<<PD0); PORTD |= (1<<PD0); }
17
#define TRIGGER_OFF    { PORTD &= ~(1<<PD0);       }
18
  
19
#define ECHO_SIGNAL    ( PIND  &   (1<<PD1) )
20
21
22
int main(void)
23
{
24
  while(1)
25
  {
26
    int16_t cm=0;
27
    
28
    // Trigger a measurement
29
    TRIGGER_ON;
30
    _delay_us(10);
31
    TRIGGER_OFF;
32
    
33
    // Wait for response
34
    while (!ECHO_SIGNAL);
35
    
36
    // Measure pulse width
37
    while (ECHO_SIGNAL)
38
    {
39
      _delay_us(58);
40
      cm++;
41
    }
42
    
43
    if(cm > 100)
44
    {
45
      LED_GREEN_ON;
46
      LED_YELLOW_OFF;
47
      LED_RED_OFF;
48
    }
49
    else if((cm <= 100) && (cm > 30))
50
    {
51
      LED_GREEN_OFF;
52
      LED_YELLOW_ON;
53
      LED_RED_OFF;
54
    }
55
    else if(cm <= 15)
56
    {
57
      LED_GREEN_OFF;
58
      LED_YELLOW_OFF;
59
      LED_RED_ON;
60
    }
61
    // Delay 0.1 second before next loop
62
    _delay_ms(100);
63
  }
64
}

von Heiner (Gast)


Lesenswert?

Jetzt hab' ich's - der Klaus ist der Paul oder der Henry oder der ... - 
der mit dem ATTiny841 (der ja immer wieder hier im Forum aufschlägt)!!

Er wollte/will nur nicht zugeben, dass er wieder ein Tut für den 
ATTIny841 zusammenpinseln will, aber zu unfähig dafür ist.

Schande!!

von Cyblord -. (cyblord)


Lesenswert?

Hugo H. schrieb:
> Aus Mitleid - weil ich heute meinen sozialen Tag habe :-) - mit Port D:

Wär ja alles schön und gut, wenn sowas auch mal was bringen würde.

Aber selbst minimaler funktionierender Code bringt solche Leute nicht 
auf die Spur.

von Hugo H. (hugo_hu)


Lesenswert?

Heiner schrieb:
> Er wollte/will nur nicht zugeben, dass er wieder ein Tut für den
> ATTIny841 zusammenpinseln will, aber zu unfähig dafür ist.

Du meinst

https://playground.boxtec.ch/lib/exe/fetch.php/tutorials/ati-841_avr_studio.pdf 
?

Achim (AS)! Jetzt verstehe ich - er nutzt seinen Namen wohl aus gutem 
Grund hier nicht mehr :-)

Daher auch die Ports und die verkrampfte Timer-Nutzung. Ich wusste gar 
nicht, dass Achim noch aktiv ist ... . Mir kam der Sprachstil irgendwie 
bekannt vor - ich habe aber nicht mit ihm gerechnet :-/

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Hugo H. schrieb:
> Und warum willst Du dann für Deine kleine Anforderung unbedingt mit
> Timern arbeiten?

Wenn du eine wirklich sinnvolle Alternative kennst - nur raus damit.

von Klaus (Gast)


Lesenswert?

Hatte die Frage gestellt ob ein Timer poder 2 nötig sind. Dazu habe ich 
eine Antwort von K.H. Buchegger gefunden. Kennt ihn gern um Rat dazu 
fragen.
1
uint16_t startCount;
2
3
ISR( Timer Capture )
4
  {
5
    if( Flanke == ansteigend ) 
6
      {
7
        startCount = ICR1;
8
        Flanke umstellen;
9
      }
10
    else 
11
      {
12
        Timerticks = ICR1 - startCount;
13
        Flanke umstellen;
14
        Ergebnis Timerticks bearbeiten;
15
      }
16
  }
Ob ich einen Attiny84, 2313 oder 841 nehm ist doch im Grund egal. Es 
geht hauptsächlich darum die Funktion zu verstehen und anzuwenden

Hugo H. schrieb:
> Jetzt verstehe ich - er nutzt seinen Namen wohl aus gutem
> Grund hier nicht mehr :-)

Leider ist es hier so, das Leute die versuchen etwas zu lernen oder nach 
Problemen fragen sehr oft mit Kritik (oder mehr) zugeschüttet werden.
Ich freue mich immer wieder auf Menschen zu treffen die sich damit 
auskennen. Warum dürfen andere sowas nicht lernen? Geheimwissen?
Die Technik ist so billig geworden, das sich auch andere damit 
beschäftigen ohne vorher einen Ing. darauf zu machen.

Wolfgang schrieb:
>> Und warum willst Du dann für Deine kleine Anforderung unbedingt mit
>> Timern arbeiten?
>
> Wenn du eine wirklich sinnvolle Alternative kennst - nur raus damit.

Die Angabe mit den Timern stammt von K.H. Buchegger, frage ihn warum so. 
Warum eigentlich nicht. Wenn der Proz. einen hat kann man ihn auch 
nutzen.
Eine Alternative dazu ist das Programm von Stefan Frings.
Was besser ist, müsst ihr schon selber beantworten.

von Klaus (Gast)


Lesenswert?

Wenn du schon die Seite angibst, dann schaut bitte nach rechts. Dort 
steht wie oft es vom Netz geladen wurde. Wenn das alles so schlecht ist, 
warum wird es so oft gelesen?

von Hugo H. (hugo_hu)


Lesenswert?

Wolfgang schrieb:
> Wenn du eine wirklich sinnvolle Alternative kennst - nur raus damit.

Für den Pille-Palle-Kram die Lösung von Stefan, wie bereits geschrieben. 
Ein Timer, richtig eingesetzt, ist etwas genauer - aber für die geplante 
Anwendung spielt das wohl keine Rolle.

: Bearbeitet durch User
von Hugo H. (hugo_hu)


Lesenswert?

Klaus schrieb:
> Wenn der Proz. einen hat kann man ihn auch
> nutzen.

Ja, wenn man es kann.

von Heiner (Gast)


Lesenswert?

Hallo Klaus bzw Achim S.

Dein hirnloses Zusammenkopieren von Codeschnipseln, die Du im Netz 
gefunden hast, bringen Dich nur dann weiter, wenn Du verstehst, was Du 
da aus dem Netz “gesaugt” hast.
Das Verstehen ist Dein Problem. Da hapert es.

Und was eigentlich unversch*** ist - wenn Du dann ein “Tut” erstellst 
und es als Deine geistige Leistung ausgibst, nachdem Dir hier mehr oder 
weniger breit erklärt wurde, was Du zu tun hast, damit Dein Programm 
funktioniert.
Dein geistiger Beitrag zur Lösung Deines Problems ist gelinde gesagt 
minimal.

Dennoch muss ich zugeben, dass ich Deine Penetranz bewundern muss.
👍

von PittyJ (Gast)


Lesenswert?

Klaus schrieb:
> Ich freue mich immer wieder auf Menschen zu treffen die sich damit
> auskennen. Warum dürfen andere sowas nicht lernen? Geheimwissen?

Quatsch. Die Techniken, die Algorithmen sind seit 40 Jahren bekannt. Es 
gibt Bücher und Anleitungen zu Hauf.
Was mir an den Leuten heutzutage fehlt, ist der Wille sich das mal 
strukturiert reinzuziehen.
Früher gab es kein Internet. Da hat man sich das Buch genommen. Das 
Beispiel nach programmiert. Mal ein paar Zeilen geändert. Mit print() 
nachverfolgt, was da passiert. Das erfordert Ruhe, und auch etwas Härte 
gegen sich selbst. Man brauchte eine Woche länger, aber man hat es 
kapiert.
So habe ich das vor 40 Jahren auch gemacht.

Heute wollen die Leute alles fertig aus dem Internet haben. Möglichst 
noch für den richtigen Prozessor. Und wenns nicht geht: ein printf() 
einbauen?? Nö, dafür gibt es doch genug Foren, wo die Arbeit für einen 
erledigt wird.
Es will doch keiner mehr lernen. Was zählt ist ein Copy&Paste Programm 
in 5 Minuten mit NULL Aufwand.

von malhier (Gast)


Lesenswert?

PittyJ schrieb:
> Es will doch keiner mehr lernen. Was zählt ist ein Copy&Paste Programm
> in 5 Minuten mit NULL Aufwand.

Mach die Jugend nicht soo schlecht - sie muss doch für unsere Rente 
arbeiten, da können wir auch mal ein bisschen nachhelfen ;-)

von Heiner (Gast)


Lesenswert?

malhier schrieb:

>
> Mach die Jugend nicht soo schlecht - sie muss doch für unsere Rente
> arbeiten, da können wir auch mal ein bisschen nachhelfen ;-)

Erstens ist der TO kein Jugendlicher mehr (eher Rentner), und zweitens 
wird “die Jugend” schon genügend gepampert - wieviel willst da noch 
nachhelfen 😉.

Wenn Du nachhelfen willst dann “Hilfe zur Selbsthilfe” und nicht z.B. 
den Schulranzen in’s Klassenzimmer tragen.

von Heiner (Gast)


Lesenswert?

Aber wieder zurück zum Hauptproblem - dem Thread von Achim (oder Klaus)…

Also Klaus - wie sieht es nun aus mit Deinem Programm?

Schön da informativ wäre zu wissen, ob Dein Programm nun funktioniert 
oder ob es noch “klemmt” 🤔

von Hugo H. (hugo_hu)


Lesenswert?

Heiner schrieb:
> Schön da informativ wäre zu wissen, ob Dein Programm nun funktioniert
> oder ob es noch “klemmt” 🤔

Wie soll es funktionieren, wenn er einen Ping absetzt, genau einmal 
unmittelbar danach (!) das Messergebnis (so denn dann schon eines 
vorliegt) abfragt und dann zum nächsten Ping samt einmaliger Abfrage 
schreitet etc.?
Für Wunder sind höhere Mächte zuständig :-)

: Bearbeitet durch User
von Heiner (Gast)


Lesenswert?

Hugo H. schrieb:
> Heiner schrieb:
>> Schön da informativ wäre zu wissen, ob Dein Programm nun funktioniert
>> oder ob es noch “klemmt” 🤔
>
> Wie soll es funktionieren, wenn er einen Ping absetzt, genau einmal
> unmittelbar danach (!) das Messergebnis (so denn dann schon eines
> vorliegt) abfragt und dann zum nächsten Ping samt einmaliger Abfrage
> schreitet etc.?
> Für Wunder sind höhere Mächte zuständig :-)

Naja, vielleicht hatte er ja eine Eingebung 😉 und er hat seine Fehler 
gefunden und behoben (was ich aber stark bezweifle)

von Klaus (Gast)


Lesenswert?

PittyJ schrieb:
> Früher gab es kein Internet. Da hat man sich das Buch genommen. Das
> Beispiel nach programmiert.

Genau so mach ich es auch, nehme mir ein Beispiel aus dem Netz, 
vorhandene Tuts oder Programme und teste was passiert wenn ich was 
ändere. Leider stehen in den Büchern meist nur Grundlagen drin und ein 
paar kleine Anwendungen.

PittyJ schrieb:
> Heute wollen die Leute alles fertig aus dem Internet haben. Möglichst
> noch für den richtigen Prozessor. Und wenns nicht geht: ein printf()
> einbauen?? Nö,

Leider habe ich in dieser Version kein Display angeschlossen und kann 
damit es nicht überprüfen.
Da ihr nicht alle Programme von mir kennt urteilt ihr sehr schnell.
Verwende teilweise sogar 2 Displays in einem Programm um die Anwendung 
und die Prüfsumme zu sehen. In diesen Programmen werden bis zu 20 
Parameter im Bus übergeben.
Nein, das Programm läuft noch nicht. Wenn die Lösung von Stefan so 
einfach und ungenau ist, wie geht es ohne Timer besser. Was sagt ihr zu 
dem Vorschlag von Karl Heinz? Ist das eine Lösung?

von Heiner (Gast)


Lesenswert?

Klaus schrieb:
> Was sagt ihr zu dem Vorschlag von Karl Heinz? Ist das eine Lösung?

Kommt drauf an, was Du daraus machst 😉

von PittyJ (Gast)


Lesenswert?

Klaus schrieb:
> Leider habe ich in dieser Version kein Display angeschlossen und kann
> damit es nicht überprüfen.

Das ist vielleicht der Hauptfehler. Ohne eine Ausgabemöglichkeit 
programmiert man doch blind. Da kann man gar nichts testen, weder an 
Werten, noch an Kontrollfüssen.

Wenn ich eine neue CPU (AVR/NXP/STM) nehme, dann wird als erstes der 
UART etabliert.
Alle meine Platinen haben einen UART-Ausgang, damit man etwas sehen 
kann.
Bei vielen CPUs gibt es Bibliotheken dafür, so dass man schnell ein 
Zeichen oder einen String ausgeben kann. Damit kann man das weitere 
Debug-Bibliotheken bauen.
An den Uart kommt dann ein USB-Seriell Adapter und man kann auch jedem 
PC mit Putty was sehen.

Wer selbst auf diese Möglichkeit verzichtet, ist entweder ein 
Programmiergott oder ein Trottel.

von Hugo H. (hugo_hu)


Lesenswert?

Klaus schrieb:
> Genau so mach ich es auch, nehme mir ein Beispiel aus dem Netz,
> vorhandene Tuts oder Programme und teste was passiert wenn ich was
> ändere. Leider stehen in den Büchern meist nur Grundlagen drin und ein
> paar kleine Anwendungen.

Du bist in den letzten 8 Jahren nicht wirklich viel weiter gekommen:

Beitrag "Toggeln einer LED"

von Heiner (Gast)


Lesenswert?

Hugo H. schrieb:
> Klaus schrieb:
>> Genau so mach ich es auch, nehme mir ein Beispiel aus dem Netz,
>> vorhandene Tuts oder Programme und teste was passiert wenn ich was
>> ändere. Leider stehen in den Büchern meist nur Grundlagen drin und ein
>> paar kleine Anwendungen.
>
> Du bist in den letzten 8 Jahren nicht wirklich viel weiter gekommen:
>
> Beitrag "Toggeln einer LED"

Das Problem von Achim alias Klaus ist, dass er sich nie intensiv mit 
Programmierung bzw. den Prozessoren beschäftigt hat sondern nur 
irgendwelche Programmschnipsel aus dem Internet zusammenkopiert hat in 
der Hoffnung, dass er dieses Konglomerat schon irgendwie mit Hilfe von 
Foren zum Laufen bringt.
Die Härte ist aber, wenn er dann Tutorials in das Internet stellt als 
seine eigene geistige Leistung.

von Stefan F. (Gast)


Lesenswert?

Klaus schrieb:
> Leider stehen in den Büchern meist nur Grundlagen
> drin und ein paar kleine Anwendungen.

Logisch. Denn für eigene Programme braucht man Talent, das können Bücher 
nicht vermitteln.

Klaus schrieb:
> Wenn die Lösung von Stefan so einfach und ungenau ist ...

Du bist der erste, der hier das Wort "ungenau" eingebracht hat. Ich 
frage mich nur, warum?

Meine "einfache" Methode ist auf jeden Fall um ein vielfaches genauer, 
als was der Sensor und die Physik hergeben. Was ist dir denn da zu 
ungenau?

von Stefan F. (Gast)


Lesenswert?

PittyJ schrieb:
> Das ist vielleicht der Hauptfehler. Ohne eine Ausgabemöglichkeit
> programmiert man doch blind.

Korrekt. Deswegen hat mein Beispiel eine serielle Ausgabe. Das ist doch 
das mindeste, was man immer beim Entwickeln braucht.

Den Tx-Pin kann man übrigens auch prima mit einer "Power" LED 
kombinieren. Wenn sie aus bleibt, ist das Gerät ganz tot.

von Klaus (Gast)


Lesenswert?

Hugo H. schrieb:
> Für den Pille-Palle-Kram die Lösung von Stefan, wie bereits geschrieben.
> Ein Timer, richtig eingesetzt, ist etwas genauer - aber für die geplante
> Anwendung spielt das wohl keine Rolle.

Hugo hat das geschrieben

von Hugo H. (hugo_hu)


Lesenswert?

Klaus schrieb:
> Hugo hat das geschrieben

Steht da etwas von ungenau?

Klaus schrieb:
> Wenn die Lösung von Stefan so
> einfach und ungenau ist, wie geht es ohne Timer besser.

Lesen kannst Du?

Hugo H. schrieb:
> Für den Pille-Palle-Kram die Lösung von Stefan, wie bereits geschrieben.

Mit "Pille-Palle-Kram" ist Deine Anforderung gemeint. Beim 
Einpark-Signal kommt es nicht auf den Millimeter an - oder?

Wenn es Dir auf Genauigkeit ankommt, dann solltest Du Dich mal besser 
belesen. Da spielen auch noch Luftdruck und -temperatur eine Rolle. Ganz 
genau bekommst Du es mit einem solchen Ultraschall-Schätzeisen sowieso 
nicht hin.

Wenn Du das Datenblatt lesen möchtest ...:

Min Range 2cm - und das dürfte noch geprahlt sein :-)

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Hugo H. schrieb:
> Mit "Pille-Palle-Kram" ist Deine Anforderung gemeint. Beim
> Einpark-Signal kommt es nicht auf den Millimeter an - oder?
>
> Wenn es Dir auf Genauigkeit ankommt, dann solltest Du Dich mal besser
> belesen. Da spielen auch noch Luftdruck und -temperatur eine Rolle. Ganz
> genau bekommst Du es mit einem solchen Ultraschall-Schätzeisen sowieso
> nicht hin.

Wo willst du den Sensor denn einbauen?
Solange der Sensor nicht am Heck des Fahrzeuges eingebaut ist, während 
man vorwärts einparkt, dürfte die Abhängigkeit von Druck und Temperatur 
von untergeordneter Bedeutung sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.