#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h> // For rand()
#define NEO_PIN PB0 // Use PB0 (Pin 0)
#define NEO_PORT PORTB
#define NEO_DDR DDRB
#define PIXEL_COUNT 16 // Number of NeoPixels (adjust as needed)
uint8_t pixelData[PIXEL_COUNT * 3]; // Array to store RGB data for all pixels
// Function to send one byte to the NeoPixel
void NEO_sendByte(uint8_t byte) {
for (uint8_t bit = 8; bit; bit--) {
asm volatile(
"sbi %[port], %[pin] \n\t" // Set pin HIGH
"sbrs %[byte], 7 \n\t" // Skip next if MSB is 1
"cbi %[port], %[pin] \n\t" // Set pin LOW if MSB is 0
"rjmp .+0 \n\t" // 2-cycle delay
"add %[byte], %[byte] \n\t" // Shift byte left by 1
"cbi %[port], %[pin] \n\t" // Set pin LOW
:
: [port] "I" (_SFR_IO_ADDR(NEO_PORT)),
[pin] "I" (NEO_PIN),
[byte] "r" (byte)
);
}
}
// Function to send a pixel color in GRB format
void sendPixelColor(uint8_t green, uint8_t red, uint8_t blue) {
NEO_sendByte(green);
NEO_sendByte(red);
NEO_sendByte(blue);
}
// Function to send all pixel data
void sendPixels() {
for (uint8_t i = 0; i < PIXEL_COUNT; i++) {
sendPixelColor(pixelData[i * 3], pixelData[i * 3 + 1], pixelData[i * 3 + 2]);
}
}
// Initialize all pixels to black
void clearPixels() {
for (uint8_t i = 0; i < PIXEL_COUNT * 3; i++) {
pixelData[i] = 0x00;
}
}
// Add random color to a specific pixel
void setPixelRandom(uint8_t index) {
pixelData[index * 3] = (uint8_t)(rand() % 256); // Random green
pixelData[index * 3 + 1] = (uint8_t)(rand() % 256); // Random red
pixelData[index * 3 + 2] = (uint8_t)(rand() % 256); // Random blue
}
int main(void) {
// Set NEO_PIN as output
NEO_DDR |= (1 << NEO_PIN);
clearPixels(); // Start with all pixels black
uint8_t currentPixel = 0;
uint8_t allFilled = 0; // Flag to indicate all pixels have been assigned colors
while (1) {
if (!allFilled) {
// Add a random color to the next pixel
setPixelRandom(currentPixel);
currentPixel++;
if (currentPixel >= PIXEL_COUNT) {
currentPixel = 0; // change to allFilled = 1 to randomise pixel filling
}
} else {
// Randomly change one pixel at a time
setPixelRandom(rand() % PIXEL_COUNT);
}
sendPixels(); // Send updated colors to NeoPixels
_delay_ms(500); // Adjust delay as needed for animation speed
}
}