0

I am working with an Arduino on a project for which timing is very important. I use TimerOne to trigger timer interrupts and use micros() for delays (delayMicroseconds() was causing problems worse than the one explained below). The program is sending a manual PWM signal to an LED and it is very important that the signal is sent with an error that is less than 8 microseconds (ideally, the signal is sent at the same time in each period). My test code is shown below:

#include <TimerOne.h>
#include <SPI.h>

const int LED_PIN = 3;
const int CHIP_SELECT = 12;

const int PERIOD = 4000;
const double DUTY_CYCLE = .5;
const int HIGH_TIME = PERIOD * DUTY_CYCLE;
const int LOW_TIME = PERIOD - HIGH_TIME;
const int INITIAL_SIGNAL_DELAY = LOW_TIME / 2;
const int HIGH_TIME_TOTAL_DELAY = INITIAL_SIGNAL_DELAY + HIGH_TIME;

const int RESISTOR_VALUE = 255;

boolean triggered = false;
boolean data = false;

unsigned long triggeredTime;
unsigned long s;
unsigned long e;

boolean found;
int i = 0;

void setup()
{
  s = micros();

  Timer1.initialize(PERIOD);
  Timer1.attachInterrupt(trigger);

  pinMode(LED_PIN, 3);
  pinMode(CHIP_SELECT, OUTPUT);

  SPI.begin();

  digitalWrite(CHIP_SELECT, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(RESISTOR_VALUE);
  digitalWrite(CHIP_SELECT, HIGH);

  e = micros();

  Serial.begin(115200);
  Serial.print("s: ");
  Serial.println(s);
  Serial.print("e: ");
  Serial.println(e);
}

void loop()
{
  if(triggered)
  {
    while(micros() - triggeredTime < INITIAL_SIGNAL_DELAY)
    { }
    s = micros();
    digitalWrite(LED_PIN, data);
    while(micros() - triggeredTime < HIGH_TIME_TOTAL_DELAY)
    { }
    digitalWrite(LED_PIN, LOW);

    data = !data;
    triggered = false;

    e = micros();
    //micros();

    if(s % 100 > 28 || s % 100 < 12)
    {
     found = true; 
    }

    if(!found)
    {
      Serial.print("s: ");
      Serial.println(s);
    }
    else
    {
      Serial.print("ERROR: ");
      Serial.println(s);
    }
    //Serial.print("e: ");
    //Serial.println(e);
  }
}

void trigger()
{
  triggeredTime = micros();
  triggered = true;
}

(it should be noted that the first signal sent is always xx20, usually 5020).

So, with this code, I eventually get an error. I am not sure why, but this error occurs at the same point every single time:

.
.
.
s: 1141020
s: 1145020
s: 1149020
ERROR: 1153032
ERROR: 1157020
ERROR: 1161020
.
.
.

Now, the really weird part is if I remove the comments before micros() (the micros() right after e = micros()), there is no error (or at least there is not an error within the first 30 seconds). I was wondering if anybody could provide an explanation for why this happens. I have dedicated many hours trying to get the timing working properly and everything was working well until I encountered this error. Any help would be very much appreciated. Thank you!

dts
  • 121
  • 6
  • I noticed that if I print a constant (5) instead of s inside of the if statement (with conditional !found), the problem does not occur which suggests to me that something significant is happening in s's transition from 1149020 to 1153032 (perhaps something having to do with size?) – dts Jan 16 '17 at 05:23
  • I'm not sure what is the problem, But don't use the while statement, Use Finite State Machine. – YoavShtainer Jan 16 '17 at 05:51
  • Replacing the s inside of the if statement with a constant eliminates the problem, so the code works now. I was just wondering if there was any logical explanation for the problem I encountered. I have never heard of Finite State Machine, though. Do you have any resources that I could learn more about if from? – dts Jan 16 '17 at 06:07
  • https://hackingmajenkoblog.wordpress.com/2016/02/01/the-finite-state-machine/ – YoavShtainer Jan 16 '17 at 06:33

0 Answers0