Skip to content

SAMD21 micros() problem #684

@Peter28357

Description

@Peter28357

Hello all,
this is my first time here and I am not sure that my assumption is correct.
The aim of the program is to decode a Manchester signal. The LED_BULITIN indicates a failure and gives a trigger for the oscilloscope.
From time to time the calculation of the „intervalBahnsignalMicros“ goes wrong and the decoding of the signal is corrupted!
This failure was never seen on a NANO_Every platform, but on different SAMD21 platforms like NANO 33 IoT, ARDUINO_Zero, MKR_Zero and MKR WIFI 1010.
Thanks for your help.

ArduinoSamd21_MicrosProblem_v2_Overview
ArduinoSamd21_MicrosProblem_v2_Zoom

Sketch:

/* for arduino:
*/

volatile const unsigned long UnsignedLongMax = 4294967295;


volatile const int pinISR = 10;
volatile const int pinISR_Interval = 9;

volatile const int interruptPin_Bahnsignal = 12;


volatile word BahnsignalWord = 0;
volatile bool Calculate = false;


volatile const word SW_Car = 32;                                    // SW=SpurWechsel
volatile word SW_CarArray[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};

volatile word BahnWordArray[11] = {0, 4096, 512, 128, 512, 514, 516, 518, 520, 128, 522};
volatile int BahnWordArrayBitLength[11] = {1, 13, 10, 8, 10, 10, 10, 10, 10, 8, 10};


volatile unsigned long intervalWhileWaitMicros = 0;
volatile unsigned long previousWhileWaitMicros = 0;
volatile unsigned long currentWhileWaitMicros  = 0;

volatile unsigned long intervalBahnsignalMicros = 0;
volatile unsigned long previousBahnsignalMicros = 0;
volatile unsigned long currentBahnsignalMicros  = 0;

volatile unsigned long intervalCalculateMicros = 0;
volatile unsigned long previousCalculateMicros = 0;
volatile unsigned long currentCalculateMicros  = 0;


volatile int BahnWord = 1;
volatile bool BahnWordSync = false;
volatile word BahnWords[11];


// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------


void setup() {

  pinMode(interruptPin_Bahnsignal, INPUT);
  attachInterrupt(digitalPinToInterrupt (interruptPin_Bahnsignal), ISR_BahnsignalDecodePur, CHANGE);

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(pinISR, OUTPUT);
  pinMode(pinISR_Interval, OUTPUT);

}


// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------


void loop() {
  digitalWrite(pinISR, LOW);
  digitalWrite(pinISR_Interval, LOW);

  if (Calculate == true) {
    currentCalculateMicros = micros();
    if (currentCalculateMicros < previousCalculateMicros) {
      intervalCalculateMicros = currentCalculateMicros + (UnsignedLongMax - previousCalculateMicros);
    }
    else {
      intervalCalculateMicros = currentCalculateMicros - previousCalculateMicros;
    }

    if (intervalCalculateMicros > 2000) {

      if (BahnWord == 4) {
        SW_CarArray[1] = (BahnWordArray[4] & SW_Car) >> 5;

        if (SW_CarArray[1] == 0) {
          digitalWrite(LED_BUILTIN, HIGH);
        }
        else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }

      if (BahnWord == 6) {
        SW_CarArray[2] = (BahnWordArray[6] & SW_Car) >> 5;

        if (SW_CarArray[2] == 0) {
          digitalWrite(LED_BUILTIN, HIGH);
        }
        else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }


      if (BahnWord == 8) {
        SW_CarArray[3] = (BahnWordArray[8] & SW_Car) >> 5;

        if (SW_CarArray[3] == 0) {
          digitalWrite(LED_BUILTIN, HIGH);
        }
        else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }


      if (BahnWord == 10) {
        SW_CarArray[4] = (BahnWordArray[10] & SW_Car) >> 5;

        if (SW_CarArray[4] == 0) {
          digitalWrite(LED_BUILTIN, HIGH);
        }
        else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }


      if (BahnWord == 5) {
        SW_CarArray[5] = (BahnWordArray[5] & SW_Car) >> 5;

        if (SW_CarArray[5] == 0) {
          digitalWrite(LED_BUILTIN, HIGH);
        }
        else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }


      if (BahnWord == 7) {
        SW_CarArray[6] = (BahnWordArray[7] & SW_Car) >> 5;

        if (SW_CarArray[6] == 0) {
          digitalWrite(LED_BUILTIN, HIGH);
        }
        else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }

      Calculate = false;
    }
  }

}


// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------


void ISR_BahnsignalDecodePur() {
  digitalWrite(pinISR, HIGH);

  currentBahnsignalMicros = micros();

  if (currentBahnsignalMicros < previousBahnsignalMicros) {
    intervalBahnsignalMicros = currentBahnsignalMicros + (UnsignedLongMax - previousBahnsignalMicros);
  }
  else {
    intervalBahnsignalMicros = currentBahnsignalMicros - previousBahnsignalMicros;
  }


  if ((intervalBahnsignalMicros > 85) && (intervalBahnsignalMicros < 135)) {
    digitalWrite(pinISR_Interval, HIGH);

    previousBahnsignalMicros = currentBahnsignalMicros;
    BahnsignalWord = BahnsignalWord << 1;
    
    if (digitalRead(interruptPin_Bahnsignal) == LOW) {
      bitSet(BahnsignalWord, 0);
    }

    if (BahnsignalWord >= 4096) {
      BahnWordSync = true;
    }
    return;
  }


  if (intervalBahnsignalMicros > 5700 ) {
    if (BahnWordSync == true) {
      if (BahnsignalWord >= 4096) {
        BahnWord = 1;
      }
      BahnWordArray[BahnWord] = BahnsignalWord;
      BahnsignalWord = 0;
      bitSet(BahnsignalWord, 0);
      Calculate = true;
      BahnWord = BahnWord + 1;
      if (BahnWord >= 11) {
        BahnWord = 1;
      }
      previousBahnsignalMicros = currentBahnsignalMicros;
      previousCalculateMicros = currentBahnsignalMicros;
      return;
    }
    else {
      previousBahnsignalMicros = currentBahnsignalMicros;
      previousCalculateMicros = currentBahnsignalMicros;
      BahnsignalWord = 0;
      bitSet(BahnsignalWord, 0);
      Calculate = false;
      BahnWord = 1;
      return;
    }
  }

}


// -------------------------------------------------------------------------------------


void WhileWaitMicros(unsigned long WaitMicros) {
  previousWhileWaitMicros = micros();
  do {
    currentWhileWaitMicros  =  micros();

    if (currentWhileWaitMicros < previousWhileWaitMicros) {
      intervalWhileWaitMicros = currentWhileWaitMicros + (UnsignedLongMax - previousWhileWaitMicros);
    }
    else {
      intervalWhileWaitMicros = currentWhileWaitMicros - previousWhileWaitMicros;
    }

  } while ( intervalWhileWaitMicros < WaitMicros );
}

// -------------------------------------------------------------------------------------

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions