ISR's + Pings

Hi, I'll begin with I've read through several Ping (ultrasonic distance) sensor questions already. To measure the returning pulse use "pulsein" if you're using one sensor. However I am using two, and would like to get the information at (nearly) the same time. I saw a suggestion that checked both pins and kept a counter for each pin, however I don't feel that's very precise.

So I wanted to use the external interrupts (pins 2,3; I'm using the Duemilanove) and the TCNT1 timer to measure the retuning pulse widths.

I think I'm getting tied up in my "while(doneL == false) {}" loop, because the Ping sensor is only active once, then nothing. Anyone see anything blatantly wrong in my code? Particularly about the interrupts? Mucho thanks.

EDIT: for future reference, this allows the while loop to break. However the flaw it still has is that durationL = 64594 always.

 volatile unsigned int doneL = false;
 volatile unsigned int doneR = false;
 volatile unsigned int startL = false;
 volatile unsigned int startR = false;
 
 //int dist =0;          // stores the distance measurement

 void setup() {
   // initialize serial communication:
   Serial.begin(9600);
    pinMode(ledPinL, OUTPUT);     
   TCCR1B = 0x02;            // 16MHz sys clock, div 8, rolls over at 32ms
                             // this guarantees max of 1 overflow since ping
                             // sensor max is ~18ms
}

 void loop()
 {
   unsigned int inchesL, inchesR;
   startL = false;
   doneL = false;
   
   pinMode(pingPinL, OUTPUT);
   // Sending signal to PING))) sensor
   digitalWrite(pingPinL, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPinL, HIGH);
   delayMicroseconds(5);
   digitalWrite(pingPinL, LOW);
   
   pinMode(pingPinL, INPUT);
   interrupts();
   //durationL = pulseIn(pingPinL, HIGH); //what I would use if only 1 ping sensor.
   
   attachInterrupt(0, leftside, CHANGE);
   
   while(doneL == false) 
   {
     // do nothing while waiting for doneL to be set by ISR
   }
   
   Serial.print("duration: ");
   Serial.print(durationL);
   Serial.println();

   // convert the time into a distance
   inchesL = microsecondsToInches(durationL);

   if (inchesL < 5) {
     digitalWrite(ledPinL, HIGH);
   } else {
     digitalWrite(ledPinL, LOW);
   }
   
   Serial.print(inchesL);
   Serial.print("in");
   Serial.println();
   delayMicroseconds(100); // at least 200us between measurements
   
 }
 
 void leftside()
 {
   if(startL == false)
   {
     beginningL = TCNT1;
     startL = true;
   }
   else
   {
     durationL = TCNT1-beginningL;
     doneL = true;
     detachInterrupt(0);
   }
 }

Update, so I changed all the longs to unsigned ints since I noticed I had a type mismatch.

But also, I can confirm that the ISR (leftside()) is being entered twice, and detachInterrupt(0) is executed. However, nothing after the "while(doneL==false){}" loop is being executed.

Looks like the value change of doneL isn't accepted, have you tried declaring doneL as a volatile variable?

Is your doneL variable a global? Because as it is, it should be limited in scope to your loop() function, which means leftside() it will not have access to that variable. If it is, you should add the volatile keyword to it's declaration, which is something you should do with any variable you change with an interrupt. Basically like:

volatile unsigned int doneL

EDIT: duh, of course it's a global variable, I just thought I saw it declared there in the loop() function.

EDIT2: Looks like Imahilus beat me to it. :wink:

Thanks Imahilus, it needed to be volatile. It's breaking out of the while loop now, have a few more flaws to work through, but at least I can move on!