2

I just started to use the unusual part of Arduino language (avr) like interrupts, accessing registers, etc in Arduino IDE. I wrote a program to calculate the frequency of a digital signal using external interrupts.

The following code is to calculate timeperiod of a digital signal, the output of the color sensor (TCS3200) which depends on the color filter choosen via S2 and S3 pins, as in the code. That is, color sensor produces 50% duty cycle square pulses of frequency dependent on the power of the light incident on it. So when sensor faces red color, output signal's frequency in red color mode (by setting S2, S3 pins) is more than the frequency in blue and green modes. Thus we can detect the likeliness of the color which it faces w.r.t R,G,B.

When this code is uploaded in the Arduino, it failed to print the values as expected in the serial monitor i.e. its stuck in while loops. But when Serial.print(e) statement in the while loops are uncommented, it is able to print the required time periods. I am unable to figure out the problem here, which is making Arduino to be inside the while loop when no statements are in it.

// INT0 interupt is used i.e. digital pin 2
int ti=0,tim=0,e=0,S2=4,S3=5;

void Interruptinit() //initializing interrupt INT0
{
  cli();
  EICRA =  0x02; //Control register
  EIMSK =  0x01; //Mask register
  sei();
}

void setup()
{
  pinMode(2,INPUT);
  digitalWrite(2,HIGH); //enabling pull up register
  pinMode(S2,OUTPUT);
  pinMode(S3,OUTPUT);
  Interruptinit();
  Serial.begin(9600);
}

ISR(INT0_vect)
{
  tim=micros()-ti;
  ti=micros();
  e++;
}

void loop()
{ 
  digitalWrite(S2,0); digitalWrite(S3,0); //switching over red filtered photodiodes
  e=0;
  while(e<2)
  //Serial.print(e) //waiting till interrupt is addressed 2 times     
  ;
  Serial.print("red:");
  Serial.print(tim);

  digitalWrite(S2,0); digitalWrite(S3,1); //switching over blue filtered photodiodes
  e=0;
  while(e<2)
  //Serial.print(e)
  ;
  Serial.print(" blue:");
  Serial.print(tim);

  digitalWrite(S2,1); digitalWrite(S3,1); //switching over green filtered photodiodes
  e=0;
  while(e<2)
  //Serial.print(e)
  ;
  Serial.print(" green:");
  Serial.println(tim);

}
1
  • 2
    Watch the semicolon right after the //Serial.print, even if it's intentional, I wouldn't use it to keep the loop spinning, an empty brackets are much more readable
    – Omer
    Commented Jan 3, 2015 at 16:39

1 Answer 1

3

Whenever you modify non-local variables in an ISR, it's important that they are declared as volatile. This tells the compiler that the contents may change unexpectedly, ensuring it doesn't use out-of-date cached copies somewhere else. If you don't do this, the code can behave in unpredictable ways, such as outputting the wrong value under some circumstances.

Since the variables are bigger than 1 byte, it's also necessary to disable interrupts around non-ISR code which uses them (e.g. in loop()). This is because interrupts could be triggered at any time, potentially half way through an operation which reads/writes them.

You can use noInterrupts() and interrupts() to disable/enable interrupt handling.

3
  • The main problem here is that when while loops are accessing variable "e" here, to check whether e<2.... program's unable to come out of loop (ISR is not changing "e").. but when some code like "Serial.print(e)" is kept in while loop...i.e. it spent some time not accessing "e" to communicate serially, its able to come out of the loop. Actually this must not be a problem as when ISR are addressed the main stack remains as it is n returns where it left. Commented Jan 4, 2015 at 18:04
  • 1
    @Wupadrasta I suspect the ISR is executing correctly, but the while loop is simply operating on a different (cached) copy of e. Declaring it as volatile should solve that. Commented Jan 4, 2015 at 21:36
  • 1
    Thanks a lot... I learned about volatile qualifiers but didn't know where to use them.It worked... Thanq. Commented Jan 10, 2015 at 7:53

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.