// ======================================================================= // Arduino sketch // This is a test of controlling simulated IoT devices (LEDs) using // the serial port. Code has been borrowed/combined from various // existing Arduino sketches. // ----------------------------------------------------------------------- // Commands: cascadeon, cascadeoff, cascade, // randomon, randomoff, random, // rgbon, rgboff, rgb, // reset, doc // Note: all input commands are converted to lowercase // ----------------------------------------------------------------------- // Things to do: // 1. make the Serial port input generate a real interrupt? // 2. make commands MQTT messages over WIFI // 3. create request status commands that are MQTT messages - // responses are MQTT messages // 4. add random LED blinking // 5. make each cascade blink , RGB color, random blink a separate thread? // 6. convert to event driven? // ======================================================================= // un-comment this line if using a Common Anode RGB LED //#define COMMON_ANODE // seriaL port baud rate // Use: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, // 28800,38400, 57600, 115200 #define BAUDRATE 19200 // command string maximum (includes ending '\0') #define CMDMAX 64 // ----------------------------------------------------------------------- // ---- global data - pins, flags, etc. // ----------------------------------------------------------------------- // ---- flags bool cascadeFlag = false; // flag - blink LEDs - serial cascade bool randomFlag = false; // flag - blink LEDs - randomly bool rgbColorFlag = false; // flag - display RGB LED colors // ---- (random and cascade commands) array of GIOs and LEDs #define RCGIOLEN 4 int RCGIO[RCGIOLEN] = { 5,6,7,13 }; // GIO pins int RCLED[RCGIOLEN]; // led status (on/off) // --- GIOs for RGB LED int redPin = 11; // RGB GIO pin int greenPin = 10; // RGB GIO pin int bluePin = 9; // RGB GIO pin // ---- command buffer for serial port input char cmd[CMDMAX]; // incoming command buffer // ----------------------------------------------------------------------- // ---- display documentation // ----------------------------------------------------------------------- void doc() { Serial.println("Commands: cascadeon, cascadeoff, cascade,"); Serial.println(" randomon, randomoff, random,"); Serial.println(" rgbon, rgboff, rgb,"); Serial.println(" reset, doc"); Serial.flush(); } // ----------------------------------------------------------------------- // ---- set RGB LED color (common anode LED?) // ----------------------------------------------------------------------- void setColor(int red, int green, int blue) { #ifdef COMMON_ANODE red = 255 - red; green = 255 - green; blue = 255 - blue; #endif analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue); } // ----------------------------------------------------------------------- // ---- reset pins (everything off) // ----------------------------------------------------------------------- void resetRCPins() { for (int i; i < RCGIOLEN; i++) // LEDs for random/cascade commands { digitalWrite(RCGIO[i], LOW); } } void resetAllPins() { resetRCPins(); // random/cascade LEDs setColor(0,0,0); // RGB LED } // ----------------------------------------------------------------------- // ---- initialize GIO pin mode // ----------------------------------------------------------------------- void initPins() { for (int i; i < RCGIOLEN; i++) // LEDs for random/cascade commands { pinMode(RCGIO[i], OUTPUT); } pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); resetAllPins(); } // ----------------------------------------------------------------------- // ---- turn LED on // ----------------------------------------------------------------------- void turnLedOn(int led) { digitalWrite(led, HIGH); // turn a LED on } // ----------------------------------------------------------------------- // ---- turn LED off // ----------------------------------------------------------------------- void turnLedOff(int led) { digitalWrite(led, LOW); // turn a LED off } // ----------------------------------------------------------------------- // ---- blink a LED // ----------------------------------------------------------------------- void blinkLed(int led) { turnLedOn(led); // turn the LED on delay(300); // wait 3/10 second turnLedOff(led); // turn the LED off } // ----------------------------------------------------------------------- // ---- blink Cascade LEDs // ----------------------------------------------------------------------- void blinkCascadeLEDs() { blinkLed(13); delay(500); blinkLed(5); delay(500); blinkLed(6); delay(500); blinkLed(7); delay(500); } // ----------------------------------------------------------------------- // ---- blink random LEDs // ----------------------------------------------------------------------- void blinkRandomLEDs() { // ---- turn on random LEDs for(int i = 0; i < RCGIOLEN; i++) { int r = random(2); if (r) { turnLedOn(RCGIO[i]); RCLED[i] = 1; } else { RCLED[i] = 0; } } // ---- pause with LEDs on delay(500); // ---- turn off LEDs for(int i = 0; i < RCGIOLEN; i++) { if (RCLED[i] == 1) { turnLedOff(RCGIO[i]); } } // ---- pause between blinking LEDs delay(1000); } // ----------------------------------------------------------------------- // ---- display RGB colors // ----------------------------------------------------------------------- void displayColors() { setColor(255, 0, 0); // red delay(500); setColor(0, 255, 0); // green delay(500); setColor(0, 0, 255); // blue delay(500); setColor(255, 255, 0); // yellow delay(500); setColor(255, 0, 255); // magenta delay(300); setColor(0, 255, 255); // aqua delay(500); setColor(0, 0, 0); // off delay(500); } // ----------------------------------------------------------------------- // ---- empty serial input buffer // ----------------------------------------------------------------------- void emptySerialInputBuffer() { while(Serial.read() != -1); } // ----------------------------------------------------------------------- // ---- return char converted to lowercase // ----------------------------------------------------------------------- char convertToLowercase(char c) { if (c >='A' and c <= 'Z') { c |= 0b100000; } return c; } // ----------------------------------------------------------------------- // ---- read and process serial port input // ----------------------------------------------------------------------- void processCommandStrings() { // ---- wait for the complete message delay(200); // ---- get the command (string) int i = 0; char c; while(i < CMDMAX-1) { c = Serial.read(); if (c == '\t' or c == '\n' or c == '\0') { break; } cmd[i] = convertToLowercase(c); i++; } cmd[i] = '\0'; // ---- work with individual characters ---- //i = 0; //while(cmd[i] != '\0') //{ // Serial.print(cmd[i]); // i++; //} // ----------------------------------------- // ---- echo what was received //Serial.print("Received: "); //Serial.println(cmd); //Serial.flush(); // ---- test for legal command if (strcmp(cmd,"cascadeon") == 0) { cascadeFlag = true; randomFlag = false; resetRCPins(); Serial.println("Received cascadeon command"); Serial.flush(); } else if (strcmp(cmd,"cascadeoff") == 0) { cascadeFlag = false; resetRCPins(); Serial.println("Received cascade off command"); Serial.flush(); } else if (strcmp(cmd,"cascade") == 0) // toggle cascade flag { if (cascadeFlag) { cascadeFlag = false; } else { cascadeFlag = true; } resetRCPins(); Serial.println("Received toggle cascade command"); Serial.flush(); } else if (strcmp(cmd,"randomon") == 0) { randomFlag = true; cascadeFlag = false; resetRCPins(); Serial.println("Received random on command"); Serial.flush(); } else if (strcmp(cmd,"randomoff") == 0) { randomFlag = false; resetRCPins(); Serial.println("Received cascade off command"); Serial.flush(); } else if (strcmp(cmd,"random") == 0) // toggle random flag { if (randomFlag) { randomFlag = false; } else { randomFlag = true; } resetRCPins(); Serial.println("Received toggle random command"); Serial.flush(); } else if (strcmp(cmd,"rgbon") == 0) { rgbColorFlag = true; setColor(0,0,0); Serial.println("Received a RGB on command"); Serial.flush(); } else if (strcmp(cmd,"rgboff") == 0) { rgbColorFlag = false; setColor(0,0,0); Serial.println("Received a RGB off command"); Serial.flush(); } else if (strcmp(cmd,"rgb") == 0) { if(rgbColorFlag) { rgbColorFlag = false; } else { rgbColorFlag = true; } setColor(0,0,0); Serial.println("Received toggle RGB command"); Serial.flush(); } else if (strcmp(cmd,"reset") == 0) { cascadeFlag = false; randomFlag = false; rgbColorFlag = false; resetAllPins(); Serial.println("Received a reset command"); Serial.flush(); } else if (strcmp(cmd,"doc") == 0) { doc(); } else { Serial.print("Say what? ("); Serial.print(cmd); Serial.println(")"); Serial.flush(); } // ---- remove remaining characters in the buffer (if any) emptySerialInputBuffer(); } // ----------------------------------------------------------------------- // ---- setup - runs once when you press reset or power the board // ----------------------------------------------------------------------- void setup() { Serial.begin(BAUDRATE); // initialize serial port initPins(); // initialize GIO pins doc(); } // ----------------------------------------------------------------------- // ---- loop forever // ----------------------------------------------------------------------- void loop() { if(Serial.available()) { processCommandStrings(); } if (cascadeFlag) { blinkCascadeLEDs(); } if(Serial.available()) { processCommandStrings(); } if (randomFlag) { blinkRandomLEDs(); } if(Serial.available()) { processCommandStrings(); } if (rgbColorFlag) { displayColors(); } }