
Zitat von
Rabenauge
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
Lesezeichen