123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /*
- * Adafruit NeoPixel RGB-LED strand UART controller
- *
- * This simple sketch controls an RGB LED strand via data received over UART.
- * The protocol works as follows:
- *
- * A single 'frame' that can be displayed, on our N LED strand, is defined as:
- * uint8_t data[N * 3] = { r0, g0, b0, r1, g1, b1, r2, g2, b2, ... };
- * With consecutive 24-bit RGB pixels.
- * This is simply transferred, as is, from the PC to the Arduino. To distinguish
- * between start and end of different frames, a magic string is used, defined below.
- * Hopefully it won't appear in the data stream... :)
- */
-
- #include <Adafruit_NeoPixel.h>
- #ifdef __AVR__
- #include <avr/power.h>
- #endif
-
- #define DEBUG
-
- #ifdef DEBUG
- #define debugPrint(x) Serial.print(x)
- #define debugPrintln(x) Serial.println(x)
- #else
- #define debugPrint(x)
- #define debugPrintln(x)
- #endif
-
- #define LED_PIN 2
- #define LED_COUNT 156
- #define BAUDRATE 115200
- #define MAGIC "xythobuzRGBled"
-
- // Optional auto-turn-off after no data received
- //#define TURN_OFF_TIMEOUT 60000l // in ms
-
- Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
-
- void setup() {
- Serial.begin(BAUDRATE);
-
- strip.begin();
- strip.show(); // Initialize all pixels to 'off'
-
- debugPrintln("RGB LED controller ready!");
- debugPrint("Config: ");
- debugPrint(LED_COUNT);
- debugPrintln(" LEDs...");
- debugPrint("Magic-Word: \"");
- debugPrint(MAGIC);
- debugPrintln("\"");
-
- // Blink LED as init message
- strip.setPixelColor(0, 0x20, 0x20, 0x20);
- strip.show();
- delay(100);
- strip.setPixelColor(0, 0x00, 0x00, 0x00);
- strip.show();
- }
-
- #define WAIT_FOR_START 0
- #define RECEIVING_START 1
- #define RECEIVING_DATA 2
-
- uint8_t state = WAIT_FOR_START;
- uint8_t startPos = 0;
- uint16_t dataPos = 0;
- uint8_t frame[LED_COUNT * 3];
-
- #ifdef TURN_OFF_TIMEOUT
- unsigned long lastTime = millis();
- #endif
-
- static void setNewFrame() {
- for (uint16_t i = 0; i < LED_COUNT; i++) {
- strip.setPixelColor(i, frame[i * 3], frame[(i * 3) + 1], frame[(i * 3) + 2]);
- }
- strip.show();
- }
-
- void loop() {
- if (!Serial.available()) {
- #ifdef TURN_OFF_TIMEOUT
- if ((millis() - lastTime) >= TURN_OFF_TIMEOUT) {
- for (int i = 0; i < (LED_COUNT * 3); i++) {
- frame[i] = 0;
- }
- setNewFrame();
- }
- #endif
- return;
- }
-
- #ifdef TURN_OFF_TIMEOUT
- lastTime = millis();
- #endif
-
- uint8_t c;
- Serial.readBytes(&c, 1);
-
- if (state == WAIT_FOR_START) {
- if (c == MAGIC[0]) {
- state = RECEIVING_START;
- startPos = 1;
- debugPrintln("f");
- } else {
- debugPrintln("");
- }
- } else if (state == RECEIVING_START) {
- if (startPos < strlen(MAGIC)) {
- if (c == MAGIC[startPos]) {
- startPos++;
- debugPrintln("g");
- if (startPos >= strlen(MAGIC)) {
- state = RECEIVING_DATA;
- dataPos = 0;
- debugPrintln("w");
- }
- } else {
- state = WAIT_FOR_START;
- debugPrintln("x");
- }
- } else {
- // Should not happen
- state = RECEIVING_START;
- debugPrintln("s");
- }
- } else if (state == RECEIVING_DATA) {
- frame[dataPos++] = c;
- if (dataPos >= (LED_COUNT * 3)) {
- debugPrintln("d");
- setNewFrame();
- state = WAIT_FOR_START;
- }
- }
- }
|