Hello, I am trying to accomplish something relatively simple but can not seem to

gplus
(Tom Schubert) #1

Hello, I am trying to accomplish something relatively simple but can not seem to wrap my head around how to implement a delay without a delay in one of my current projects. Its a game where you run towards the arrows on the field and when you reach a certain point, an arrow turns green and you must run around the obstacle.

Project details:
(3) mini lidar sensors actively receiving serial data on a players distance
(2) FastLED ran 'arrow’s with 3 segments of LEDs inside each

Issue:
Once the player reaches a certain point (triggerValue) I want the arrows to randomly choose a direction and stay a color until it time outs (currently using a 10 second delay() in my code.)

The video doesn’t really show it that well but I have everything working- but the delay() makes the arduino either double trigger, or act erratic for a few seconds afterwards. As this is a permanent, public display, I would like to eliminate the use of the delay and basically move to a function that does nothing for a certain amount of time without disrupting the running average or LED output. After I get this issue resolves I also need to add and override button to immediately jump to the trigger function, regardless of its current location in the code. As I said- its a very simple concept but I have tried a few iterations and cant seem to have it “BwoD” in a sense. Thanks in advance guys\gals.

-Tom

Code Link:

Video Link:

(Tom Schubert) #2

Photo of the inside of the arrow to show the baffles and the reason behind the use CRGBSets:
Google Photos

(Stuart Taylor) #3

Hi Tom.

The erratic behaviour you are seeing, i think this is not because of the delay() per se, but a lack of damping for range data coming from the lidar.

My guess is that once an arrow is lit, the lidar continues to send data to the arduino, then when the delay() is finished and processing continues, the serial buffer is full of lidar data, which is parsed very quickly. Could you flush the serial buffer after the delay()?

cool project BTW.

stuart

(Marc Miller) #4

Once the trigger value is tripped save the current millis() value to variable and also set a Boolean variable to true. While that Boolean variable is true keep the arrow on, and also run a check that compares the new current millis to the saved millis. Once enough time has passed (your 10 seconds) set the Boolean back to false (which will reset the arrow, and stop checking the time comparison).

[I wrote the above before looking at your code so hopefully you can figure out how to incorporate something like that.]

(Marc Miller) #5

Btw, thanks for sharing the photo of the inside. Cool design!

(Ken White) #6

@Tom_Schubert - If you want to eliminate delays from a loop, the following code shows how to do that:

I would recommend that you delete the color wheel – lines 350 – 364 (NeoPixel library way to do colors) and I recommend that you use the better FastLED way to do that by changing line 367 to:

Return CHSV(random8(256),255,255);

Also, put this line in your loop at the beginning (line 161):

random16_add_entropy( random() );

the random16 line ensures that random8 is really random.

Thank you for the credit in the top of your code for the CRGBSet assist, i.e. Chemdoc77.

Finally, great looking project!!!

(Tom Schubert) #7

@Stuart_Taylor @marmil @Ken_White , thank you for your input.

Initially I used a “every_N” solution from Ken but noticed it was independent of the trigger- so I then moved onto Marc’s idea. I had a bit of trouble with HIGH vs true but after a night of sleep I tried to attack it a bit more this morning. Short version- it works. I still can’'t really wrap my head around a state machine but the use of a counter did eliminate my hard delay(). Also, thank you Stuart- I tried looking into a buffer flush but it seems unlikely that I could flush it with the correct timing needed to restart the serial input when needed.

I have updated my code if anyone is interested, located: https://gist.github.com/Kodekat84/e141cbd306b51bf1913d487e10748a5b

I still don’t believe I have mastered the actual timer usage but I may have hacked way way through this one by watching the serial monitor and trial and error. I’ll be updating this code before the Superbowl with sponsor colors on the arrows but for now the mechanics work and that was the most difficult part for me.

Thanks again. I have a few more surprise projects due before Feb I’ll be sure to have more questions.

-Tom

Updated arrow video: https://photos.app.goo.gl/vtNyFXhPuu7fh11i7

(Ken White) #8

@Tom_Schubert - I am glad you got things running. You might need to use EVERY_N_MILLIS_I instead of EVERY_N_MILLIS. See the following for a good description of EVERY_N_MILLIS_I:

I used it in the following sketch in the Chase.h file: