#include "FastLED.h" #define NUM_LEDS 8 #define DATA_PIN PIN_D6 #define BRIGHTNESS 255 #define FRAMES_PER_SECOND 120 #define HEARTBEAT_MILLIS 5000 #define HEARTBEAT_CHAR "A" bool DEBUG = 0; CRGB leds[NUM_LEDS]; String inputCmd = ""; boolean cmdComplete = false; unsigned long previousMillis = 0; void p(char *fmt, ... ) { char tmp[128]; va_list args; va_start (args, fmt ); vsnprintf(tmp, 128, fmt, args); va_end (args); Serial.print(tmp); } void setup() { delay(3000); // 3 second delay for recovery FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS); FastLED.setBrightness(BRIGHTNESS); for (int i = 0; i < NUM_LEDS; i++) leds[i] = CRGB::Black; FastLED.show(); //Serial.begin(230400); Serial.begin(115200); inputCmd.reserve(200); } /* SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available. */ void serialEvent() { unsigned char bytecount = 0; while (Serial.available() && bytecount < 10) { // get the new byte: char inChar = (char)Serial.read(); // if the incoming character is a newline, set a flag // so the main loop can do something about it: // if (inChar == '\n') { if (inChar == '\n' || inChar == '!') { // ! for puredata cmdComplete = true; } else { if (inChar == '_') inputCmd += " "; else inputCmd += inChar; } bytecount++; } } byte LED = 0, R = 0, G = 0, B = 0; unsigned long LEDstate [8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned long newstate = 0; int len = 0; char * pch; void processCommand(String command) { if (command.substring(0, 4) == "led ") { if (DEBUG) p("is led command.\n"); LED = (byte) command.substring(4, 5).toInt(); if (DEBUG) p("for LED %d\n", LED); command.remove(0, 6); // if (command.substring(0, 4) == "name") { // command.remove(0, 5); // if (DEBUG) p("has Color name: %s\n", command.c_str()); // // FastLED/pixeltypes.h: // if (command == "white") newstate = CRGB::White; // else if (command == "black") newstate = CRGB::Black; // else if (command == "red") newstate = CRGB::Red; // else if (command == "darkred") newstate = CRGB::DarkRed; // else if (command == "lightred") newstate = CRGB::Pink; // else if (command == "pink") newstate = CRGB::Pink; // // else if (command == "green") newstate = CRGB::Green; // else if (command == "dakrgreen") newstate = CRGB::DarkGreen; // else if (command == "lightgreen") newstate = CRGB::LightGreen; // else if (command == "orange") newstate = CRGB::Orange; // else if (command == "darkorange") newstate = CRGB::DarkOrange; // else if (command == "lightorange") newstate = CRGB::OrangeRed; // // else if (command == "blue") newstate = CRGB::Blue; // else if (command == "darkblue") newstate = CRGB::DarkBlue; // else if (command == "lightblue") newstate = CRGB::LightBlue; // // // else if (command == "cyan") newstate = CRGB::Cyan; // else if (command == "darkcyan") newstate = CRGB::DarkCyan; // else if (command == "lightcyan") newstate = CRGB::LightCyan; // else if (command == "grey") newstate = CRGB::Grey; // else if (command == "darkgrey") newstate = CRGB::DarkGrey; // else if (command == "lightgrey") newstate = CRGB::LightGrey; // else if (command == "gray") newstate = CRGB::Grey; // else if (command == "darkgray") newstate = CRGB::DarkGrey; // else if (command == "lightgray") newstate = CRGB::LightGrey; // // else if (command == "brown") newstate = CRGB::Brown; // else if (command == "purple") newstate = CRGB::Purple; // else if (command == "yellow") newstate = CRGB::Yellow; // else if (command == "lime") newstate = CRGB::Lime; // else if (command == "magenta") newstate = CRGB::Magenta; // else if (command == "teal") newstate = CRGB::Teal; // else if (command == "turquoise") newstate = CRGB::Turquoise; // else if (command == "violet") newstate = CRGB::Violet; // else { // newstate = LEDstate[LED-1]; // if (DEBUG) p("unknown color: %s\n", command.c_str()); // } // } // else { if (DEBUG) p("Assuming has RGB or 0|>0 state\n"); R = (byte) atoi(strtok((char*)command.c_str(), " ")) & 0xff; pch = strtok(NULL, " "); if (pch == NULL) { if (DEBUG) p("Is on/off 0 or >0 state or white\n"); if (R > 0) newstate = CRGB::White; else newstate = CRGB::Black; } else { G = (byte) atoi(pch); B = (byte) atoi(strtok(NULL, " ")) & 0xff; newstate = (unsigned long)R << 16 | (unsigned long)G << 8 | B; // bloody hell } if (DEBUG) Serial.println(newstate); // printf has some issues it appears with %x and %lu if (DEBUG || 1) Serial.println(newstate, HEX); // } if (LEDstate[LED-1] != newstate) { if (DEBUG) p("Setting LED to 0x%08X %lu - ", ((unsigned long) newstate) & 0xffffff, ((unsigned long)newstate)& 0xffffff); if (DEBUG) Serial.println(newstate); LEDstate[LED-1] = newstate; leds[LED-1] = newstate; FastLED.show(); } } else if (command.substring(0, 5) == "debug") { DEBUG = !DEBUG; p("change debug state to: %s\n", DEBUG ? "true" : "false"); } } unsigned long currentMillis; void loop() { // send heartbeat currentMillis = millis(); if (currentMillis - previousMillis >= HEARTBEAT_MILLIS) { // save the last time you sent heartbeat previousMillis = currentMillis; Serial.println(HEARTBEAT_CHAR); } // process command if (cmdComplete) { processCommand(inputCmd); // clear the string: inputCmd = ""; cmdComplete = false; } serialEvent(); // teensy main.cpp doesn't have this after loop() call so, we call it // Turn the LED on, then pause // for (int i = 0; i < NUM_LEDS; i++) // leds[i] = CRGB::White; // FastLED.show(); // delay(500); // // Now turn the LED off, then pause // for (int i = 0; i < NUM_LEDS; i++) // leds[i] = CRGB::Black; // FastLED.show(); // delay(500); }