This goes back to my WS2812 code from this video:
https://youtu.be/VAa4duqMrgs
That was when v1.67 was out, but for some reason on 1.8.x, it no longer works. No worries though, just a simple fix to the for loop in there to speed things back up to how they were… strange though, huh? Maybe a computer science guy can tell me why this broke in the first place. I tried running a diff on some of the core files, but nothing stood out to me. Kind of cool that you can speed up for loops by counting down to zero, so at least I found that out through this troubleshooting effort.
Here’s that updated code:
http://kevindarrah.com/download/arduino_code/WS1812_V4_FOR_VIDEO_FIXED.ino
Check out my Tindie store (trigBoard is available) https://www.tindie.com/stores/kdcircuits/
Thanks to all the Patrons for dropping a few bucks in the tip jar to help make these videos happen!
https://www.patreon.com/kdarrah
Twitter: https://twitter.com/KDcircuits
For inquiries or design services:
https://www.kdcircuits.com
I’d love to see you do a video on this For loop quirk, plus other ways to optimise loops 😀
Interesting. What happens if you count backwards under 1.6.7? Is it even faster than 0.442uS?
I have seen code ” break” when certain arduino module libraries have been updated. Backward compatibility is not as respected in the open source world as much as in business world. When you create a project you got to document all your software, dependences and libraries versions numbers, and assume if any of these change there is a probability of breakage.
assembly or it didn’t happen 🙂
Did you try “for (int i=0; i < bitstream; ++i)"? Normally, this should be optimized by the compiler itself, but in case of i++ rather than ++i the value of i is actually evaluated before incrementing it (even though not being used for anything), so that might be an issue as well. Example: "int i=1; int a = i++;" gives a==1, while "int i=1; int a = ++i;" gives a == 2...
With your original code, it would have to determine the bitstream size each time it compared. With the new code, it just compares to zero each time.
You should repair that dead seven-segment on the wall. It bugs me 🙂
I need to bite the bullet and switch to Atmel Studio. My codes are getting too complicated to debug with print statements.
How funny. I just got these last week and used your previous video to get them working.. but yeah I had to downgrade.. Thanks for the update!
(RGB[i] & B10000000) && B10000000 doesn’t make sense. Because && is boolean logic this will be 0 if the left operand is 0 and 1 if the left operand is non-0. It has nothing to do with the right operand being B10000000. It could be any non-0 value. The semantics are misleading and could lead to a programming error someday. I would suggest either !!(RGB[i] & B10000000) or ((RGB[i] & B10000000) == B10000000) or even ((RGB[i] & B10000000) && 1) all of which will provide the correct result but better convey the semantics of what you are intending.
When doing a normal comparison the hardware has to do a memory fetch for the value to compare, and do a subtraction, then test the flags (less then, greater then, equal too, etc.). When counting down to zero there’s no need for the additional memory fetch and the subtraction for the flags is part of the increment/decrement part of the for loop.
Very good video!
I love when people get direct to the point on the beginning of the video and for those who wants the explanation just stay watching.
Nicely analysed.
I don’t think that the for-loop is to blame. Normally the time to branch back from the end to the start of the loop shouldn’t have any influence on the execution of the inner code i.e. on the length of your bits.
I believe that the way you write the loop has a side effect on the code optimization of the inner parts of the loop. I reckon that the loading of the RGB[i] value into a working register somehow moved from before the “PORTB = WS2821pinHIGH” instruction to the location where it is first used. Hence the length of the first bit is increased by this additional operation.
The best way to avoid such surprises in time critical parts of your code would be to write the whole section in pure assembly. Then the compiler won’t change or optimize it.
Good stuff, Kevin!
Why the code only works on pin 8?
They’ve been breaking stuff for years… a lot of the older skeeetcheees on the net don’t work with the newer IDEs. I keep 4 different virgins of the IDE on my computer. Variety is the spies of life.