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