// 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 16
#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) {
ws2812_pixel_all(0, 0, 0);
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++ = 0xe0; \
} 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) {
for ( uint16_t i = 0; i < WS2812_NUM_LEDS; ++i) {
ws2812_pixel(i, r, g, b);
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE1));
ws2812_init();
}
void loop() {
static int i = 0;
ws2812_pixel_all(0, 0, 0);
ws2812_pixel(i, 128, 0, 0);
ws2812_send_spi();
delay(100);
ws2812_pixel_all(0, 0, 0);
ws2812_pixel(i, 0, 0, 0);
ws2812_send_spi();
i += 1;
i %= 16;
}