// This version uses bit-banged SPI.
// If you see tearing (jagged edges on the circles) try the version
// which uses AVR's hardware SPI peripheral:
// https://wokwi.com/arduino/projects/318868939929027156
#include <SPI.h>
#define MOSI 51
#define WS2812_NUM_LEDS 8
#define WS2812_RESET_PULSE 60
#define WS2812_BUFFER_SIZE (WS2812_NUM_LEDS * 24 + WS2812_RESET_PULSE)
uint8_t ws2812_buffer[WS2812_BUFFER_SIZE];
void ws2812_init(void) {
memset(ws2812_buffer, 0, WS2812_BUFFER_SIZE);
ws2812_send_spi();
}
void ws2812_send_spi(void) {
SPI.transfer(ws2812_buffer, WS2812_BUFFER_SIZE);
}
#define WS2812_FILL_BUFFER(COLOR) \
for( uint8_t mask = 0x80; mask; mask >>= 1 ) { \
if( COLOR & mask ) { \
*ptr++ = 0xfc; \
} else { \
*ptr++ = 0x80; \
} \
}
void ws2812_pixel(uint16_t led_no, uint8_t r, uint8_t g, uint8_t b) {
uint8_t * ptr = &ws2812_buffer[24 * led_no];
WS2812_FILL_BUFFER(g);
WS2812_FILL_BUFFER(r);
WS2812_FILL_BUFFER(b);
}
void ws2812_pixel_all(uint8_t r, uint8_t g, uint8_t b) {
uint8_t * ptr = ws2812_buffer;
for( uint16_t i = 0; i < WS2812_NUM_LEDS; ++i) {
WS2812_FILL_BUFFER(g);
WS2812_FILL_BUFFER(r);
WS2812_FILL_BUFFER(b);
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
ws2812_init();
}
void loop() {
ws2812_pixel(0, 128, 0, 0);
ws2812_send_spi();
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(MOSI, LOW);
delay(100);
}