Interrupts Messing With digitalRead()

falagan

Member
I have a small project (quite big for me anyway) where I need the ADC in my teensy 4.1 to continuously take measurements. Meanwhile, the main loop should be waiting for a pin to go low. The way I have structured everything, there is a timer that periodically throws interrupts which start the ADC conversions, and the ISR called by the ADC when a conversion is complete, moves the result to a buffer.
Meanwhile, the main is using the following function to wait for the pin to go low:

Code:
void waitForPin(uint8_t triggerPin) {
  bool keep = true;

  while (keep) {
    keep &= digitalRead(triggerPin);
  }
}

Now, this was not working, and so, after some trial and error, I've reached the conclusion that the interrupts interfere with the digitalRead(), as it starts working properly when I lower the interrupt frequency (ideally there is an interrupt thrown every 3us, and, from what I've gathred, digitalRead() takes a bit longer).

Now, I know there are different ways of approaching this program, but this is the most optimal way I thought of, and am more interessted in learning why this does not work than in changing the way the program works.

It is my understanding that, whenever an interrupt ends, the processor returns to the point where it was when the interrupt was thrown, so it should not affect the correct execution of a function for an interrupt to be thrown midway through the execution. I'd like to know what I'm getting wrong for digitalRead() not to work.

Thanks in advance for any help :)
 
Last edited:
I've reached the conclusion that the interrupts interfere with the digitalRead(), as it starts working properly when I lower the interrupt frequency (ideally there is an interrupt thrown every 3us, and, from what I've gathred, digitalRead() takes a bit longer).

It is my understanding that, whenever an interrupt ends, the processor returns to the point where it was when the interrupt was thrown, so it should not affect the correct execution of a function for an interrupt to be thrown midway through the execution. I'd like to know what I'm getting wrong for digitalRead() not to work.

Your understanding of how interrupts work is correct. You don't say which Teensy you are using, but with an interrupt every 3 us, your program may be spending 100% of its time in the ISR.

Just as an aside, your statement "keep &= digitalRead(triggerPin)" may be doing what you want, but keep in mind that "&" is a bit-wise operator, so you are doing a bit-wise AND of a boolean (keep) and an integer returned by digitalRead(). This will work if "true" equals 1 and digitalRead() returns 1 or 0, but that is not guaranteed, and it would be better to use && (logical AND), such as "keep = keep && digitalRead()". You actually don't need "keep" at all. The statement below is equivalent to your function, and digitalReadFast() is much faster than digitalRead(), so you might be able to keep your 3 us ADC update.

Code:
while (digitalReadFast(triggerPin) == HIGH) {}
 
It never ceases to amaze me how many things I think I know that I just assumed at one point. Both digitalRead() and digitalReadFast() return uint8_t, so yeah, that was the problem. As you suggested, I changed the line "keep &= digitalRead(triggerPin)" for "keep = keep && digitalRead(triggerPin)" and it works flawlessly now.

With regards to that last part, the reason for having the "keep" part is that I'd like to add some data processing in the future inside that wait, and so it's going to be much cleaner if anything inside the while loop can terminate the wait by setting "keep" to zero.

You are right, I forgot to post I'm using the Teensy 4.1 board. As far as I know, its fast, and I tried to make my ISRs as light as possible, so despite there being a lot of interrupts, they do not use up much processor time. I tried to benchmark it by finding primes (using my quick and probably horribly inefficient implementation to find primes), and the performance hit when the timer and ADC are both doing their things is about 20-25%. Again, I'm nothing close to an expert and so this could be the wrong conclusion, especially with such good results, but as I understand it, I have processor time to spare.

Anyway, thanks for your help, I'm quite an amateur programmer, and It's really encouraging to have such assistance at my disposal for when I don't know what else to do. :)
 
I intend to try and use DMA to move the output from the ADC to the buffer, but for the moment, I'm trying to get the signal processing part of the project working, so in the meantime this will do.

Thanks again for the help, it's much appreciated.
 
Back
Top