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);
}
asked May 9, 2017 at 10:54
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. 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. 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. 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. 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
}
answered May 9, 2017 at 14:41
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.

answered May 9, 2017 at 11:01
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. Commented May 9, 2017 at 12:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.