0

im trying to make a speedometer with arduino Nano Board but when i use interrupt im getting "strange" number on variables t1 or t2 going under 0 there is the code:

volatile int impulsi =  0;
int impulsiOld = 0;
volatile int appoggio = 0;
//static int inizioDiNuovo = 0;
volatile unsigned int deltaT[3];
long t1=0;
long t2=0;  




void setup() {
  Serial.begin(9600);

  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, definisciTempi, RISING);

}

void loop() {

  Serial.println(impulsi);
  if (impulsi == impulsiOld || impulsi > impulsiOld)
  {
    ;
  }
  //Serial.print("N IMPULSI: ");
  //Serial.println(impulsi);
  if (appoggio == 3) {
    appoggio = 0;
    Serial.print("DELTA T 0 : ");
    Serial.println(deltaT[0]);
    Serial.print("DELTA T 1 : ");
    Serial.println(deltaT[1]);
    Serial.print("DELTA T 2 : ");
    Serial.println(deltaT[2]);

    t1 = (deltaT[1] - deltaT[0]);
    if (t1 == 0) {
      t1 = 1;
    }
    t2 = (deltaT[2] - deltaT[1]);
    if (t2 == 0) {
      t2 = 1;
    }
    int t = t1 + t2;

    Serial.print("TEMPO T1 ");
    Serial.println(t1);
    Serial.print("TEMPO T2 ");
    Serial.println(t2);

  }

}


void definisciTempi() {
  impulsi++;
  switch(appoggio){

    case 2:
    //Serial.println("ASSEGNO DELTA T 2");
    deltaT[2] = millis();
    //Serial.println(deltaT[2]);
    appoggio = 3;
    break;

    case 1:
    //Serial.println("ASSEGNO DELTA T 1");
    deltaT[1] = millis();
    appoggio = 2;
    break;

    case 0:
    //Serial.println("ASSEGNO DELTA T 0");
    deltaT[0] = millis();
    appoggio = 1;
    break;

  }
}

how suggest i changed

unsigned int t1=0; unsigned int t2=0; into `long t1=0; long t2=0;` 

output on Serial now have negative number it's for the interrupt??:

DELTA T 0 : 8785
DELTA T 1 : 8666
DELTA T 2 : 8706
TEMPO T1 40
TEMPO T2 -119  <------how 8706-8666= -119 ?

this is my pulse generator code:

const int pin = 2;
void setup() {
  pinMode(pin,OUTPUT);

}

void loop() {
 digitalWrite(pin,HIGH);
 delay(40);
 digitalWrite(pin,LOW);
 delay(40);
}
7
  • appoggio Isn't defined as volatile. All variables that get changed in the interrupt, and used in the main loop need to be volatile.
    – Gerben
    Commented May 9, 2017 at 12:20
  • thanks i made appoggio volatile but don't change the result , every time negative number , thanks Commented May 9, 2017 at 12:22
  • Move "appoggio = 0;" to after al the serial.prints.
    – Gerben
    Commented May 9, 2017 at 12:28
  • After you set appoggio = 0; and interrupt might fire, and change the variables you are currently working on.
    – Gerben
    Commented May 9, 2017 at 12:35
  • What will happens if you get an interrupt between printing the deltas and calculating the t values? You'll end up with the t values being calculated with the new delta values (or half with the old ones, half with the new ones) . You need to disable interrupts, make a copy of the delta values and then re-enable them. You then base all your outputs and calculations on the copies.
    – Andrew
    Commented May 9, 2017 at 13:55

2 Answers 2

0

The interrupt may be triggering between the Serial.print and the actual calculations, as stated by @Andrew.

Evidence supporting that fact is that your deltas are recorded in order 0, 1, 2 (ie: delta 0 < delta 1 < delta 2), However in the example output delta 0 is larger than delta 2, which suggests that a new round of delta recordings had started but not yet completed.

Updating this section as follows should fix the issue:

if (appoggio == 3) {

  noInterrupts(); // Disable interrupts while calculating

  appoggio = 0;
  Serial.print("DELTA T 0 : ");
  Serial.println(deltaT[0]);
  Serial.print("DELTA T 1 : ");
  Serial.println(deltaT[1]);
  Serial.print("DELTA T 2 : ");
  Serial.println(deltaT[2]);

  t1 = (deltaT[1] - deltaT[0]);
  if (t1 == 0) {
    t1 = 1;
  }
  t2 = (deltaT[2] - deltaT[1]);
  if (t2 == 0) {
    t2 = 1;
  }
  int t = t1 + t2;

  Serial.print("TEMPO T1 ");
  Serial.println(t1);
  Serial.print("TEMPO T2 ");
  Serial.println(t2);

  interrupts(); // re-enable interrupts

}
0
unsigned int t1=0;
unsigned int t2=0; 

Integers on an 8 bit system can only store 16 bits of data. For unsigned that is 0 - 216-1, or 0 - 65535.

Make them unsigned long and they can store 0 - 232-1, or 0 - 4294967295.

Also, since they are unsigned, any negative value will wrap around to the maximum again. An unsigned can't store a negative value.

3
  • I'm simulating the pulse with another arduino board, how an impulse timing be negative? i have setted the time to 40ms for each pulse(sorry for my english) Commented May 9, 2017 at 12:05
  • now i make the change to` unsigned int` to` unsigned long` but now this the output: DELTA T 0 : 3269 DELTA T 1 : 3309 DELTA T 2 : 3349 TEMPO T1 4294967096 TEMPO T2 40 Commented May 9, 2017 at 12:07
  • You may well be suffering from a lack of critical sections which I mentioned in your previous question.
    – Majenko
    Commented May 9, 2017 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.