Updating Arduino Broke my Code!! FAIL

preview_player
Показать описание
This goes back to my WS2812 code from this video:

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:


Thanks to all the Patrons for dropping a few bucks in the tip jar to help make these videos happen!

For inquiries or design services:
Рекомендации по теме
Комментарии
Автор

Idk if you like Atmel studio but it gives you detailed file of what it did to your code and gives you the assembly equivalen for every line of your code and how many clock cycles it takes . So I bet you could find the difference in there.

EdwinFairchild
Автор

The problem is not the compiler. The problem is your use of nops to guarantee timing between loop iterations. Interrupts can delay instructions, including nops. In order to enforce accurate timing, you need to disable interrupts prior to nopping, or redesign your code to poll elapsed time.

You may use "DELAY_CYCLES" to delay accurately, and you may also use the hardware timer to ensure that a set amount of processor time has passed between iterations.

aaro
Автор

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.

viniciusnoyoutube
Автор

It didn't break your code, your code was already broken...the update just brought this to light...

Centar
Автор


TO sum it up in simple terms:

up counting for loop : subtract -> compare ->branch

down counting for loop : subtract->branch

EdwinFairchild
Автор

Interesting. What happens if you count backwards under 1.6.7? Is it even faster than 0.442uS?

davidcourtney
Автор

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.

shadowwalker
Автор

Hi Kevin, How to make 1 LED turn on, and the other 95 to stay off
in a panel of 96 addressable WS2812B LEDs,
but in an automatic fashion? Can one write 96 RGB_update functions
and Call a particular function (within another Arduino code) to fire a specific LED?
Thanks a lot for your help!

bkrljanac
Автор

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...

bonzaihb
Автор

You should repair that dead seven-segment on the wall. It bugs me :)

zaprodk
Автор

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.

tobi_n
Автор

I'd love to see you do a video on this For loop quirk, plus other ways to optimise loops :D

azyfloof
Автор

(RGB[i] & && 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 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] & or ((RGB[i] & == or even ((RGB[i] & && 1) all of which will provide the correct result but better convey the semantics of what you are intending.

bobtausworthe
Автор

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.

CarltonDodd
Автор

Do you know that you can use also the Adafruits Neopixel library? Its a way more comfortable then the Way you've done!
With Adafruit you only need 1 line of code to initialize and one for the updating and one to let the led strip show the updates!

seba_
Автор

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!

jotchava
Автор

I need to bite the bullet and switch to Atmel Studio. My codes are getting too complicated to debug with print statements.

ufohunter
Автор

I knew it was coming. Backward compatibility is never sustainable.

jp
Автор

Sounds crazy.
But thanks for explaining the fact.

TechnoAutomation
Автор

What occurred to me is that maybe the test to see if something is equal to zero (now) takes fewer cycles than testing it against another value?
Edit: OK, you said that at the end, if so using... for( i = bitstream; i; i-- ) might be fastest if that is the case.

rickgraham