C HC-SR04 ohne Flanken Interrupt auswerten?!

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Mal wieder ein herzliches Hallöchen,

ich werde das Gefühl nicht los, dass ich hier der einzige bin der Fragen stellt :p

Habe vorgestern meinen "Ultraschallsensor HC-SR04" bekommen.
Im Internet ließt man nur (ich zumindest), dass die meisten den Sensor via. Flanken Interrupt auswerten.
Da der Sensor mir eine PWM ausgibt, müsste es doch auch möglich sein, den Pegel via. Timer Overflow oder noch genauer über einen CompareMatch Interrupt auszulesen.

Würde das funktionieren? Wenn ich ihn auf ca. 10µS konfiguriere?
 
Wie soll das sonst funktionieren?
Außer vielleicht hardwareseitig dass du das PWM mittels Spulen und Kondensatoren zu einer Gleichspannung machst und die auf den ADC legst.
Aber dann würdest du natürlich sämtliche Zuordnungen die im Datenblatt stehen verlieren / umrechnen müssen.

Ich gehe mal stark davon aus dass der Sensor den Wert dann per Duty Cycle ausgibt statt per wechselnder Frequenz.
Bei ersterem wüsste ich keine Alternative, bei letzterem, ja, könnte man so in der Art machen, aber das würde dann gleich 2 Timer/Counter belegen (du brauchst ja trotzdem eine feste Zeitbasis).

Ist doch aber kein Problem. Lass n Timer rennen, PWM an nen Interrupt. Fallende Flanke: Wert speichern, steigene Flanke: Wert speichern und Timer auf 0 setzen. Anhand der Differenz der 2 Werte kannste die % berechnen. Der Timer darf natürlich nur so schnell laufen dass er nicht überläuft während der Messung.


p.s.: was holst du dir auch immer für komische Bauteile? ^^'
 
Hi @TommyB,

Wieso komische Bauteile? Ist das ein komisches Bauteil? :p
Also den Sensor triggere ich mit einer Fallenden Flanke an, danach dauert es 200ms und dann geht es los.
Der US Sender senden in 48kHz Burst ein Signal und der Empfänger (wenn ich Glück habe) empfängt es.

Die Entfernung entspricht der High Zeit des Echo Signals (in µS) des Sensors. Wozu zwei Timer?
 
Argh!

Ich verlinke hier mal das Datenblatt:
http://www.micropik.com/PDF/HCSR04.pdf

Der Sensor gibt dir kein PWM aus!
Du musst lediglich die Zeit messen zwischen Senden und Empfangen. Also kein Auswerten des Duty Cycle.
Also Timer laufen lassen um eine Zeitbasis zu haben und den stoppen wenn der Sensor das Signal gibt. Timer Overflow oder Compare Match wäre hier doch … kontraproduktiv. Verstehe auch ehrlich gesagt den Gedankengang nicht.

Sensor an INT0/1 dran (PCINT geht zur Not auch), Start senden, Timer1 starten. Auf Interrupt warten (also die Antwort), Timer stoppen und Wert auswerten. Im Idealfall noch Timer Overflow Interrupt einbinden (Fehler: Echo nicht empfangen). Das wars doch schon ;)
 
Habe es jetzt so auf meinem MEGA2560 gelöst:



CodeBox C
int main(void)
{
  
   DDRB |= ((1<<PB7));
   DDRD |= (1<<PD0);
   
   /* Timer0 works @ CompareMatch Interrupt (no port operation) */
   TIMSK0 = (1<<OCIE0A); // enable interrupt
   TCCR0A |= (1<<WGM01);
   TCCR0B |= ((1<<CS00)); // no prescaler
   OCR0A   = 0x9F; // 10µS
  
   EICRA |= ((1<<ISC10)); // every change
   EIMSK |= (1<<INT1); // enable int1
    
   sei();
    
  while (1)
  {  
    
     if (SR04.trigger >= 60000) // every 60ms
     {
       SR04.trigger = 0;
       trigger_sr04();
     }
    
     if (SR04.state & 0x03)
     {
       SR04.time = SR04.falling;
       SR04.state = 0x00;
     }
    
     if (microsecondsToCentimeters(SR04.time) <= 4)
     {
       PORTB |= (1<<PB7);
     }
     else
     {
       PORTB &= ~(1<<PB7);
     }
    
  }
}

ISR(TIMER0_COMPA_vect)
{
   Time_Base.us++;
   SR04.trigger++;
}

ISR(INT1_vect)
{
   if (ECHO_SIGNAL) // echo signal @input pin (pb0)
   {
     Time_Base.us = 0;
     SR04.state |= (1<<0);
   }
   else
   {
     SR04.falling = Time_Base.us;
     SR04.state |= (1<<1);
   }
}
 
Zuletzt bearbeitet:
@Janiiix3 : wäre einfacher nachzuvollziehen, wenn Du den konfigurierten Timermode dazukommentierst - oder zumindest den verwendeten Controller (muß man halt selbst im DB suchen).

Du verwendest wahrscheinlich den CompareA zur Generation einer (frequenzkorrekten) Zeitbasis, und zählst die verstrichene Zeit in "Überläufen" (CompareMatch) des Timers. Die Zeitbasis kannst Du natürlich auch anderweitig nutzen, verfügbar wäre noch der eventuelle 2te Kanal als PWM (wobei die Frequenz feststeht).

Alternativ könnte man einen Timer mit InputCapture nehmen. Den IC-Interrupt vorher auf steigende Flanke stellen. Löst der aus, steht im ICR der Startzeitpunkt -> auslesen. Overflow-Flag löschen, IC-Interrupt auf fallende Flanke.
Löst er das 2te mal aus, ICR und das Overflow-Flag auslesen.
Der Timer kann durchlaufen, nebenbei PWM erzeugen, 'ne langsamere Zeitbasis etc...

Edit: für @TommyB 's NoEcho müßte man hier auch den ÜberlaufIRQ nutzen

Noch'n Edit: grad noch das gefunden...
You only need to supply a short 10uS pulse to the trigger input to start the ranging
Zehn µSiemens??? Das ergibt keinen Sinn...
Wenn die Mikrosekunden meinen - das wären bei 20MHz Taktfrequenz 200 Takte. Kurz??
(also mal kurz den Pin high und wieder low-setzen reicht nicht... da mußte noch'n Haufen Takte warten zwischendurch)
 
Zuletzt bearbeitet:
@Janiiix3 : wäre einfacher nachzuvollziehen, wenn Du den konfigurierten Timermode dazukommentierst - oder zumindest den verwendeten Controller (muß man halt selbst im DB suchen).

Du verwendest wahrscheinlich den CompareA zur Generation einer (frequenzkorrekten) Zeitbasis, und zählst die verstrichene Zeit in "Überläufen" (CompareMatch) des Timers. Die Zeitbasis kannst Du natürlich auch anderweitig nutzen, verfügbar wäre noch der eventuelle 2te Kanal als PWM (wobei die Frequenz feststeht).

Alternativ könnte man einen Timer mit InputCapture nehmen. Den IC-Interrupt vorher auf steigende Flanke stellen. Löst der aus, steht im ICR der Startzeitpunkt -> auslesen. Overflow-Flag löschen, IC-Interrupt auf fallende Flanke.
Löst er das 2te mal aus, ICR und das Overflow-Flag auslesen.
Der Timer kann durchlaufen, nebenbei PWM erzeugen, 'ne langsamere Zeitbasis etc...

Edit: für @TommyB 's NoEcho müßte man hier auch den ÜberlaufIRQ nutzen

Noch'n Edit: grad noch das gefunden...
Zehn µSiemens??? Das ergibt keinen Sinn...
Wenn die Mikrosekunden meinen - das wären bei 20MHz Taktfrequenz 200 Takte. Kurz??
(also mal kurz den Pin high und wieder low-setzen reicht nicht... da mußte noch'n Haufen Takte warten zwischendurch)

Das sollen 10 m(µ)icroSekunden sein. Klappt aber nach den ersten Tests schon mal ganz gut.

P.S

Habe es noch mal besser kommentiert.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)