Matthijs Theelen

Blocking delay: fading LEDs

Blocking delay is a very common problem within the Arduino programming world. Delays can be used to extent a certain state of the system (e.g. keeping an LED on for a couple seconds before turning it off). This can come in very handy sometimes, but has one main disadvantage: it blocks any other input. During the time the delay is taking, the system is frozen and cannot perform any other actions.

When fading the LEDs inside the system, the two for-loops I initially programmed uses this delay. For every step the brightness of the LED increases or decreases there is a delay of 30 milliseconds. This is so that the fading of the LED is visible. Would I not do this, the for-loop would directly run through all steps and the glowing effect would not be visible. In this case, the for-loop looks like this when transalted to pseudo-code:

FOR each increment of LED intensity
 WRITE analog value of intensity to LED
 WAIT 30ms
FOR each reduction of LED intensity
 WRITE analog value of intensity to LED
 WAIT 30ms

For the third prototype I wanted to rewrite this code because, although it works, the system is not possible to register multiple touches at once. During the user tests of the second prototype I observed that the system for some users reacts to slow and this makes the learning curve of the system steeper than it needs to be.

The most common replacement of the delay-function makes use of millis(). This millis-function returns a value related to the time the Arduino has been active, it is in essence a timer. And since all Arduino code runs in a giant loop, you can use this timer function to calculate when you want a certain action to be performed without losing other inputs.

Rewriting the code requires for one extra step to consider. With the old for-loops, the system registers sensor input and fades the LED accordingly. Then for the next turn it awaits new sensor input. But, since we are getting rid of these blocking delays, the system has to have two different states for every of the five sensors.  Namely a state when it is open to new input and a state when it is blocking the input of the vertebrate that has already been triggered for the period the LED is fading. Would we not include the latter state, the user would have to keep applying force on the sensor in order to see the LED turned on.

So when we look at the code now, it would look like this if translated to pseudo-code:

SET lastTimeItHappened TO 0

SET direction TO up

SET ledCounter TO 0



MAIN LOOP

    SET howLongItsBeen TO millis() - lastTimeItHappened

    IF howLongItsBeen >= 20

        IF direction = up

            INCREASE ledCounter

            IF it is the last run

                SET direction TO down

            ENDIF

        ELSE

            DECREASE ledCounter

            IF it is the last run

                RESET sensor reading

                SET direction TO up

                INCREASE score

            ENDIF

        WRITE ledCounter TO LED

        SET lastTimeItHappened TO millis()

    ENDIF

END MAIN LOOP

 

Next Post

Previous Post

© 2018 Matthijs Theelen