SevSeg icon indicating copy to clipboard operation
SevSeg copied to clipboard

Issue with delay()

Open SlevenCalevra opened this issue 8 years ago • 6 comments

Hi, is there no way to use this correctly when you have delays in your program???

SlevenCalevra avatar May 06 '17 19:05 SlevenCalevra

It would be possible to run the update function on an interrupt rather than through the loop() function. I have not included this in the library because the timers available to set up interrupts are different on each micro-controller, so it gets complicated fairly quickly when considering all possible devices.

You could set up a timer-driven interrupt that repeatedly runs refreshDislay() in the background. If you do this, make sure to configure the library to NOT use delays.

DeanIsMe avatar May 07 '17 10:05 DeanIsMe

@DeanIsMe Could you please elaborate a bit on this? Maybe an example?

MehdiGol avatar Jan 29 '21 21:01 MehdiGol

You need to set up a regular timed interrupt, running @ at least 500Hz (every 2 ms or less). Here's an Instructable for the arduino Uno: https://www.instructables.com/Arduino-Timer-Interrupts/ Call refreshDisplay inside ISR(TIMER0_COMPA_vect){}. Don't call refreshDisplay from anywhere else. Make sure to configure the SevSeg library to NOT use delays (updateWithDelaysIn=0). Doing this properly would require making several library variables volatile, but I think that it will work fine without library modifications.

DeanIsMe avatar Jan 30 '21 02:01 DeanIsMe

@MehdiGol @SlevenCalevra something to try... you can use a PWM output as a nearly 500Hz clock (one of the PWMs is 490Hz by default on some Arduinos, and others get you close or better, I think). Plug a 1k resistor from the PWM output to a digital input and setup the digital input to interrupt on the rising edge. Create a function that calls the refreshDisplay() method and in your setup() use that new function as the interrupt handler. Turn on the PWM output to a value that's about 50% of maximum, which would give you a 50% duty cycle on the output (duty cycle doesn't matter too much as long as you trigger on the rising edge). I've used this technique successfully for other recurring tasks.

mbratch avatar Mar 14 '21 20:03 mbratch

@mbratch not to be offensive or anything but that's a really roundabout way of doing this. I'd sudgest looking into timer interrupts or other kinds of internal interrupts. In short however, basically you can use one of the timers that create the WM signal to instead of (or while) generating PWM issue an internal interrupt which forces the processor to jump into some other part of code and execute it (like refreshing the display).

machmar avatar Nov 15 '22 11:11 machmar

@machmar meh, no offense taken. That was 2 years ago. A fun little idea I had on my breadboard when I first got my Arduino before I determined how to tap into the timer interrupts. A little round-about but it was very easy to do. I certainly wasn't touting it as the best approach (I had prefaced my suggestion as "something you can try...")

mbratch avatar Nov 15 '22 11:11 mbratch