bigjosh / SimpleNeoPixelDemo

A demonstration showing how easy it can be to drive WS2812 NeoPixels
MIT License
223 stars 59 forks source link

Tram frequency issue #21

Closed AdriGuillaume closed 2 years ago

AdriGuillaume commented 2 years ago

Hello,

I'm working with an Attiny85 and I use your code directly into my application code because I have more than 500 sk6812 RGBW to drive in one string. But i'm facing to a weird issue, when I send tram, SK6812 start to display randomly color pattern even if i would like just display only 1 color. So i have perfom a measurement on tram and ... suprise, I get a 423kHz signal instead of 400kHz... i thing issue come from here.

But, i have set: -Fcpu to 8000000L -fuses to desabling clk/8 -internal divider to 1:1 -Calibrate RC oscillaor with Osccal register And finaly check the output CPU clock on PB4 with a frequency meter (after set the good fuses) and frequency seems to be ok: 8,002000MHz (about)

I know that i have change timer0 parameters for another peripherical, but I thing your code is based on CPU instruction clock, so timer0 doesent matter.

Moreover something strange too, I use _delay_ms() at the begining of my program, and where i set : _delay_ms(1000) and expect 1 Second, i get 1,5 second ! And for 2000ms, i get 3 second etc...

I dont know really where is the problem, maybe my both issues (delay and tram frequency) are dissociated, i dont know... I will try to run only your code separetly to see if the issue is always here.

Someone have an idea ?

BR Thanks !!!

Adrien

bigjosh commented 2 years ago

This repo is hand coded to run on an Arduino Uno, which runs at 16Mhz. While it is certainly possible to modify this code to run at 8Mhz, it would take some work since you need to hand count the cycles to make sure all the timing constraints are met (mostly just the T0H constraint).

As far as your signal measurement goes, the Neopixel waveform is usually not just a square wave so you can not just measure the frequency. What really matters is the width of the T0H part of the waveform, and you'll have to manually go in and look at that to see how long it is.

As far as unexpected timings for _delay_ms(), that is probably just that you have F_CPU defined wrong someplace. Track it down, or instead use __delay_cycles() and I bet you get expected timings.

AdriGuillaume commented 2 years ago

Hi Bigjosh,

thanks a lot for your reply

ok understood, so I have perform measurement of T1H/T1L/T0H/T0L

T1H 900 => obtain 900nS about ok T0H 400 => obtain 400nS about ok

but... T1L 600 => obtain 1280nS about T0L 900 => obtain 1860nS about

and of course if I div by 2 T1L and T0L I don't get the good timing, for example if I write T1L 300 instead of 600, I obtain a delay of 1000nS not 600nS and I cannot lower T1L to 150, I got an error from compiler.

I thing I have a really issue with CPU clock but i don't understand because High level are good, only low level have the issue and output CPU frequency is good too. I don't know read ASM instructions but i don't thing that issue come from your code honestly.

I have try to let TIMER 0 with default value, but it change nothing, so issue definitely doesn't come from here.

BR Adrien

AdriGuillaume commented 2 years ago

Ok, i thing i have understood what is happening. This is my "for" loop + my "if" which introduce a delay. If i write directly all the ASM code without "for" loop for 1 Led (4 colors x 8 bits) it work with the good timing ! The code looks now ugly but it works...

Br Adrien