RC Receiver und ISR

Hallo zusammen,
ich versuche einen Kanal an einem RC Receiver auszuwerten. Da gibt es haufenweise Code Schnipsel auf dem Internet. Aber ich stosse immer an das gleiche Problem.

Hier mal der Code mit dem ich teste:

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm_out = Adafruit_PWMServoDriver(0x40);

// Ports
int K1 = 2;

volatile unsigned long tStart, tStop;
unsigned long tus, ttStop, ttStart;

void setup() {
  pwm_out.begin();
  pwm_out.setPWMFreq(49);
  Serial.begin(19200); while (!Serial) {}
  attachInterrupt(digitalPinToInterrupt(K1), get_PWM, CHANGE);
  
}

void get_PWM()  // ------------------------- ISR
{
  if (bitRead(PIND, 2)) tStart = micros();
  else                  tStop  = micros();
    
}


void zdelay(int pause) // ------------------ Pause ohne delay
{
  volatile unsigned long ms;
  ms = millis() +pause;
  do
  {

  } while (ms > millis());
}


void loop() {
  detachInterrupt(digitalPinToInterrupt(K1));
  ttStop = tStop; // -------------------------------------------------------- Variablen vor dem überschreiben retten (ist das richtig so)?                                     
  ttStart = tStart;
  attachInterrupt(digitalPinToInterrupt(K1), get_PWM, CHANGE);   //  <------- muss ich das so machen oder gibt es eine andere Methode?
  tus = ttStop -ttStart;
  Serial.print("ttStop: ");
  Serial.print(ttStop);
  Serial.print("  ");
  Serial.print("ttStart: ");
  Serial.print(ttStart);
  Serial.print("  ");
  
  
  if (tus < 2000 && tus > 1000)   // -------------------------------------------- Plausibilitätskontrolle
  {
    pwm_out.writeMicroseconds(0, tus);  // -------------------------------------- steuert Servo
    Serial.print("us: ");
    Serial.println(tus);
  } else {
    Serial.print("us: ");
    Serial.println(tus);
    Serial.println("Fehler --------------------------");
  }
  
  zdelay(200);
}

Ausgabe von Serial.print:

ttStop: 2458316  ttStart: 2457220  us: 1096
ttStop: 2658324  ttStart: 2657228  us: 1096
ttStop: 2858328  ttStart: 2857232  us: 1096
ttStop: 3058336  ttStart: 3057240  us: 1096
ttStop: 3258344  ttStart: 3257248  us: 1096
ttStop: 3478352  ttStart: 3477256  us: 1096
ttStop: 3678360  ttStart: 3677264  us: 1096
ttStop: 3878368  ttStart: 3877272  us: 1096
ttStop: 4078372  ttStart: 4077276  us: 1096
ttStop: 4278380  ttStart: 4277284  us: 1096
ttStop: 4478388  ttStart: 4477292  us: 1096
ttStop: 4678396  ttStart: 4677300  us: 1096
ttStop: 4878400  ttStart: 4877304  us: 1096
ttStop: 5078408  ttStart: 5077312  us: 1096
ttStop: 5278416  ttStart: 5297320  us: 4294948392
Fehler --------------------------
ttStop: 5498424  ttStart: 5497328  us: 1096
ttStop: 5698428  ttStart: 5697332  us: 1096
ttStop: 5898436  ttStart: 5897340  us: 1096
ttStop: 6098444  ttStart: 6097348  us: 1096
ttStop: 6298448  ttStart: 6297352  us: 1096
ttStop: 6518456  ttStart: 6517360  us: 1096
ttStop: 6718464  ttStart: 6717368  us: 1096
ttStop: 6918472  ttStart: 6917376  us: 1096
ttStop: 7118476  ttStart: 7117380  us: 1096
ttStop: 7318484  ttStart: 7317388  us: 1096
ttStop: 7518492  ttStart: 7517396  us: 1096
ttStop: 7718496  ttStart: 7717400  us: 1096
ttStop: 7918508  ttStart: 7917412  us: 1096
ttStop: 8118512  ttStart: 8117416  us: 1096
ttStop: 8318520  ttStart: 8337420  us: 4294948396
Fehler --------------------------
ttStop: 8538524  ttStart: 8537428  us: 1096
ttStop: 8738532  ttStart: 8737436  us: 1096
ttStop: 8938536  ttStart: 8937440  us: 1096
ttStop: 9138544  ttStart: 9137448  us: 1096
ttStop: 9338552  ttStart: 9337456  us: 1096
ttStop: 9538560  ttStart: 9557468  us: 4294948388
Fehler --------------------------
ttStop: 9758572  ttStart: 9757476  us: 1096
ttStop: 9958576  ttStart: 9957480  us: 1096
ttStop: 10158584  ttStart: 10157488  us: 1096
ttStop: 10358588  ttStart: 10357492  us: 1096
ttStop: 10558596  ttStart: 10577500  us: 4294948392
Fehler --------------------------
ttStop: 10778604  ttStart: 10777508  us: 1096
ttStop: 10978612  ttStart: 10977516  us: 1096
ttStop: 11178616  ttStart: 11177520  us: 1096
ttStop: 11378624  ttStart: 11377528  us: 1096
ttStop: 11578632  ttStart: 11597536  us: 4294948392
Fehler --------------------------
ttStop: 11798636  ttStart: 11797540  us: 1096
ttStop: 11998644  ttStart: 11997548  us: 1096
ttStop: 12198648  ttStart: 12197552  us: 1096
ttStop: 12398660  ttStart: 12397564  us: 1096
ttStop: 12618668  ttStart: 12617572  us: 1096
ttStop: 12818672  ttStart: 12817576  us: 1096

Funktionieren tut das ganze, aber:
Warum erhalte ich sporadisch Fehler. Ist der Prozessor einfach zu langsam.(glaube kaum). Zum Testen verwende ich einen Arduino Duemilanove. Oder was mache ich falsch?

Gruss Thomas

(deleted)

Das ist ein Trugschluß:

void zdelay(int pause) // ------------------ Pause ohne delay

Was Du da gemacht hast, ist 'delay()' selbst nachprogrammieren. Da kannst Du auch gleich bei delay bleiben. Und daher kommen dann auch deine langen Pausen, in denen nichts ausgewertet wird.

die Pause ist nur drin, dass nicht alles so schnell durchflitzt am Monitor. Serial.print und delay’s kommen später raus. Ist nur zum Testen. Ich hatte schon delay() drin. Meinte nur, dass ich irgendwo gelesen habe, dass delay() die ISR stört. Aber das ist vermutlich nur innerhalb einer ISR (Timer Interrupt). Kann mich nicht mehr genau daran erinnern.

Mit oder ohne delay() oder zdelay. Die Ausreisser sind genau gleich da. :confused:

ttStop: 713304144  ttStart: 713323048  us: 4294948392

ttStop - ttStart = -18904 negativ ist nicht so toll für eine unsigned long Variable. Der verheddert sich irgendwie. Aber warum und was könnte man tun dagegen.

jetzt läuft es :slight_smile:

Die Auswertung von tus muss einfach in die ISR

void get_PWM()  // ------------------------- ISR
{
  if (bitRead(PIND, 2)) tStart = micros();
    else tus = micros() -tStart;
}

Es braucht dann auch kein detachInterrupt usw.

Gruss Thomas