# “light_ws2812” library 10x slower than required (AVR C, ATMega328p int. 8Mhz)

So I'm trying to run some SK6812 (WS2812 clones) on a standalone ATMega328p.

The output signal is too slow! I define F_CPU as 8000000 (8Mhz), both in the code and in the Atmel Studio Symbols, but my signal is slow by a factor of 10. The LED is always white, instead of red as the code intends.

#ifndef F_CPU
#define F_CPU 8000000UL // 8 MHz clock speed
#endif

#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "light_ws2812.h"

struct cRGB led[1];

int main(void)
{

while(1)
{
led[0].r=25;led[0].g=00;led[0].b=0;    // Write red to array
ws2812_setleds(led,1);
_delay_ms(500);                         // wait for 500ms.

//led[0].r=0;led[0].g=25;led[0].b=0;            // green
//ws2812_setleds(led,1);
//_delay_ms(500);

//led[0].r=0;led[0].g=00;led[0].b=25;       // blue
//ws2812_setleds(led,1);
//_delay_ms(500);
}
}


Fuses are l:0xA2, h:0xD9, e:0x07. This should correspond to an internal 8Mhz clock (verified on B0 with oscilloscope). Here's what I get for a data signal on B4:

The data looks fine (00000000 for green, then 00011001 (25d) for red). However the period is about 12µs, but according to the SK6812 datasheet, the period must be 1.25µs ± 150ns:

There's not much to show on the schematic, but to be thorough:

And like I said before, the intended header for data (D6) didn't output anything, so I had to use B4 since it was also broken out to a header.(Connectivity issue, I figured it out)

Any help is appreciated!

• I'm a little confused. Are you using library code? Or are you directly programming the chip yourself to get the hardware configured and operating correctly? This phrase, "according to the datasheet," bothers me. A datasheet is about the MCU. It tells you nothing about a library. – jonk May 18 '18 at 21:30
• @jonk I'm using example code from the library, modified slightly to simplify troubleshooting (just commenting out those few lines). The datasheet is for the SK6812 LED, sorry if that wasn't clear, I'll edit it in. The library is made to drive the specific timing of those LEDs. – Orotavia May 18 '18 at 21:35
• Setting #define F_CPU 8000000UL only calibrates the standard library busy loops. You have to flip the fuses when programming the AVR to select the clock source and frequency (also, do not forget the CLKDIV8 fuse!) – Janka May 18 '18 at 22:12
• @Janka I've got the fuses set for 8Mhz: "Fuses are l:0xA2, h:0xD9, e:0x07. This should correspond to an internal 8Mhz clock (verified on B0 with oscilloscope)" Am I missing something more? – Orotavia May 19 '18 at 16:29
• You do realise that 1.25usec is only 10 machine cycles at 8MHz? You might struggle to achieve a toggle at that rate even with hand crafted assembly. – Peter Smith May 19 '18 at 17:11

• @ChrisStratton This is not correct. #define A B means "From now on, replace any A by B in the following code". Since #include foo means "Paste the content of file foo here", a define is valid also in files included after, and defines inside included files are valid in the current file below the include directive. – sweber Jan 25 '19 at 17:06