Zitat Zitat von Rabenauge Beitrag anzeigen

So ganz theoretisch _könnte es sogar gehen, als Eingang einen der Hardware-Interrupt-Pins zu benutzen.
Dann ist da definitiv nix blockierend, wenn man es ungefähr so macht:

*notiz an mich selber: das ^^ mal im Hinterkopf behalten, hat was...
Hallo,


ich hab's mal mit dem Interrupt probiert. Klappt aber nur mit einem merkwürdigen Haken.

Prinzip:

stoße alle 500 ms den US-Sensor an, speichere "mikrosanf = micros()" und erwarte mit "attachInterrupt(1, Interruptaktion, FALLING)" das Echo des US's, speichere "mikrosend = micros()".

So weit so gut.

Der Haken ist, dass die von Hand gemessene Entfernung, die sich auch mit der Variante "pulseIn" ergibt, nur dann mit dem Ergebnis in "Entf_int" übereinstimmt, wenn ich von den ermittelten Mikrosekunden "mikrosec = mikrosend - mikrosanf" 540 µs abziehe. Zwischen Start US-Sensor und Interrupt kommen also irgendwo 540 µs dazu. Nur wo???

Das sind die Porgrammteile:

Code:
int Ausg_US_Trigger = 13;
volatile int Eing_US_Signal = 3;

int US_Zykluszeit = 500;   //Messintervall für die Ultraschallmessung

unsigned long millis_alt;
unsigned long mikrosend;

int Entf_int;



void setup() {   //    SETUP   SETUP   SETUP   SETUP   SETUP

  Serial.begin(250000);
  while (!Serial);

  pinMode (Ausg_US_Trigger, OUTPUT);  // Ausgang für das US-Triggersignal

  pinMode (Eing_US_Signal, INPUT);  //   Rückmeldungesignal vom US-Sensor

}    //    ENDE SETUP



void loop() {     //     LOOP     LOOP     LOOP     LOOP     LOOP

  attachInterrupt(1, Interruptaktion, FALLING);    //  1 ist hier das zum Eingang 3 gehörige Interruptsignal

  if ((millis() - millis_alt) >  US_Zykluszeit) {  //   in dieser if wird das UP Entfernung() alle 0,5s aufgerufen
    
    millis_alt = millis();

    Entf_int = Entfernung();             // Ergebnis aus dem UP Entfernung() wird nach Entf_int übertragen

    Serial.print ( " Entf_int  =  ");
    Serial.println (Entf_int);

  }     //   >>>>>   ENDE   if (millis() - millis_alt > US_Zykluszeit)


}   // >>>>   ENDE LOOP

Code:
int Entfernung ()
{
  static unsigned long mikrosec;
  static unsigned long mikrosanf;

  mikrosec = mikrosend - mikrosanf;

  digitalWrite (Ausg_US_Trigger, LOW);        //negative Flanke für Triggersignal

  mikrosanf = micros();         //    micros() beim ersten Durchlauf dieses UP's; der nächste folgt erst nach 500 ms
  mikrosec = mikrosec - 540;         //  540 = Korrektur für eine unerklärbare Zeitverzögerung = Messverfälschung

  return mikrosec / 58;                       //  Entfernung in cm;  sieh Buch Seite 230


}       //   >>>>>   ENDE    int Entfernung()

Code:
void Interruptaktion() {

  mikrosend = micros();
  digitalWrite (Ausg_US_Trigger, HIGH);

}
Gruß

fredyxx