Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Photobooth NanoDuo LED controller ---- 31 January 2018
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This sketch uses the current Adafruit Neopixel library.
- The NanoDuo is two Arduino Nanos set up to act as a USB adressable-LED controller.
- Using the same Nano to do both jobs seems to result in interrupt conflicts,
- so the task is divided between two Nano boards here.
- In the NanoDuo setup, one Nano board receives the USB messages
- and sets eight output pins in a way that represents the current LED settings.
- The second Nano monitors eight input pins, and changes the LED values accordingly.
- The pins used to communicate between the boards are pins D2 through D9, using external 220k pulldown resistors.
- This sketch is for the Nano that receives the USB signals.
- The sketch for the other Nano is named "Photobooth NanoDuo LED".
- This code was tested with a string of 8 and 64 WS2812 LEDs.
- ----------------------------
- PATTERNS NEEDED:
- The 1st letter I assume starts and stops the LEDS. When I run the command in the software for "stop LED", it just sends one message: #0=101 [e]
- The 2nd letter represents the speed. s=slow, m=medium, q=fast
- The number [8] represents a color choice: 1=white, 2=red, 3=green, 4=blue, 5=purple, 6=yellow, 7=cyan, 8=orange
- The final letter represents the pattern. z=spinning wheel, x=right fill, c=left fill, v=right ball, b=left ball
- */
- char inputLetter;
- char messageLetters[4];
- int messageCounter = 0;
- int serialMessage_timeOut = 500; // This is the milliseconds that a USB control message must complete in before it is reset.
- // I just guessed at this value, 9600 baud is about 960 characters per second.
- // Note that the length of this waiting period is how long it will take to turn off the lights.
- unsigned long serialMessage_beginTime = 0;
- unsigned long serialMessage_currentTime = 0;
- bool messageIncoming = false;
- bool charOutOfRange = false; // This is a value to indicate if a character was not within range (if it was not one of the accepted values)
- // function prototypes
- void beginMessageTimer();
- void resetMessage();
- void turnAllLedsOff();
- void performMessage();
- bool perform_character_filter(char);
- bool returnMessage = true; // test variable to enable the echo function below.
- void echoMessage() { // This is a function to return the sent message, only for testing. Set returnMessage to false to disable it.
- Serial.print(messageLetters[0]);
- Serial.print(messageLetters[1]);
- Serial.print(messageLetters[2]);
- Serial.println(messageLetters[3]);
- }
- void setup() {
- Serial.begin(9600);
- // pins 2 through 9 are the machine state pins, using external 220k pulldown resistors.
- pinMode(2, OUTPUT);
- pinMode(3, OUTPUT);
- pinMode(4, OUTPUT);
- pinMode(5, OUTPUT);
- pinMode(6, OUTPUT);
- pinMode(7, OUTPUT);
- pinMode(8, OUTPUT);
- pinMode(9, OUTPUT);
- for (int x = 0; x < 4; x++) {
- messageLetters[x] = 0; // init the message array to nothing
- }
- turnAllLedsOff(); // This really turns I/O pins off, there is no LEDs connected to this board.
- }
- void loop() {
- // This section gets characters off the serial connection, if any are there to get.
- if (Serial.available()) {
- while (Serial.available() > 0) {
- if (messageCounter < 4) {
- inputLetter = Serial.read();
- if (perform_character_filter(inputLetter)) {
- // If the input character is a recognized one, it is stored here.
- messageLetters[messageCounter] = inputLetter;
- messageCounter++;
- if (messageCounter == 1) {
- beginMessageTimer();
- }
- }
- }
- else { // if (messageCounter >= 4)
- // If an incoming USB message reaches four [recognized] characters in length, then the function to perform it is called.
- // If the message is just the single 'e' command, that waits for the message timeout to occur and is performed then.
- //Serial.println("message sent?");
- performMessage();
- }
- }
- }
- // This section resets a partial message, if it takes too long to complete.
- // -Which is not very likely to happen really, but just in case...
- if (messageIncoming == true) {
- serialMessage_currentTime = millis();
- if (serialMessage_currentTime > serialMessage_beginTime) {
- if (serialMessage_currentTime > (serialMessage_beginTime + serialMessage_timeOut)) {
- // The single 'e' letter to shut off the LEDs is caught and performed here.
- // You cannot catch it in performMessage() because performMessage() is only called when the message is 4 valid characters long.
- // If you called performMessage() on either 1 or 4 characters, then it would get called on the first 'e' every time and never reach 4 characters.
- // This messaging system is kinda lousy because whoever wrote it used the same letter 'e' for both commands-
- // (the 1-letter STOP command, and the 4-letter display commands).
- // If they would have used a different letter (k) to signal to turn off the LEDs, this would have been a lot easier.
- if (messageCounter == 1) {
- if (messageLetters[0] == 'e') {
- // If the message is only one character long and it is the letter 'e',
- // The the control pins are all turned off and the message is reset.
- messageIncoming = false;
- turnAllLedsOff();
- resetMessage();
- }
- }
- else {
- // If the message was more than one letter but less than four letter long,
- // then it did not complete in the allowed time, and is reset here.
- resetMessage();
- }
- }
- }
- else {
- // This bit is to handle the millis() rollover condition, should it ever occur.
- serialMessage_beginTime = millis();
- }
- }
- } // end of main loop
- void beginMessageTimer() {
- // This is used to set a time limit for sending a message to the USB arduino. {in serialMessage_timeOut}
- // At the end of the time limit, whatever message has been received is attempted.
- // This is the only way to catch the single 'e' used to shut off the lights.
- messageIncoming = true;
- serialMessage_beginTime = millis();
- }
- void resetMessage() {
- if (returnMessage == true) { // This is for testing only.
- echoMessage();
- }
- for (int x = 0; x < 4; x++) {
- messageLetters[x] = 0; // Wipe out the old message.
- }
- messageCounter = 0; // Reset the message character counter.
- messageIncoming = false; // Disable the message timing section.
- }
- void turnAllLedsOff() {
- // This function turns off the LEDs by setting all the communication pins to LOW.
- // Really only the first two pins need to be set low to turn off, but anyway.
- digitalWrite(2, LOW);
- digitalWrite(3, LOW);
- digitalWrite(4, LOW);
- digitalWrite(5, LOW);
- digitalWrite(6, LOW);
- digitalWrite(7, LOW);
- digitalWrite(8, LOW);
- digitalWrite(9, LOW);
- }
- void performMessage() {
- // If this function is called, then the message is four valid letters long.
- bool messageCheck = true;
- if (messageLetters[0] == 'e') { // The first char must be 'e'.
- // The 2nd char represents the speed. s=slow, m=medium, q=fast
- switch (messageLetters[1]) {
- case 's':
- case 'm':
- case 'q':
- // do nothing if the char is an acceptable value
- break;
- default:
- messageCheck = false;
- }
- //Serial.println(messageLetters[1]);
- //Serial.println(messageCheck);
- // third number is a color indicator: 1=white, 2=red, 3=green, 4=blue, 5=purple, 6=yellow, 7=cyan, 8=orange
- switch (messageLetters[2]) {
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- // do nothing if the char is an acceptable value
- break;
- default:
- messageCheck = false;
- }
- //Serial.println(messageLetters[2]);
- //Serial.println(messageCheck);
- // The fourth char represents the pattern. z=spinning wheel, x=right fill, c=left fill, v=right ball, b=left ball
- switch (messageLetters[3]) {
- case 'z':
- case 'x':
- case 'c':
- case 'v':
- case 'b':
- // do nothing if the char is an acceptable value
- break;
- default:
- messageCheck = false;
- }
- //Serial.println(messageLetters[1]);
- //Serial.println(messageCheck);
- }
- else {
- messageCheck = false;
- }
- // The section above verified that the message has valid characters in all four positions.
- // If it passes that test, then the section below writes the values to the output pins.
- // If the message has valid characters in each position, then it can be used:
- if (messageCheck == true) {
- // The first letter isn't used, since it's always 'e'.
- // The 2nd char represents the speed. s=slow, m=medium, q=fast
- // The first two communication pins (D2 and D3) represent the speed.
- switch (messageLetters[1]) {
- case 's':
- digitalWrite(2, LOW);
- digitalWrite(3, HIGH);
- break;
- case 'm':
- digitalWrite(2, HIGH);
- digitalWrite(3, LOW);
- break;
- case 'q':
- digitalWrite(2, HIGH);
- digitalWrite(3, HIGH);
- break;
- }
- // third number is a color indicator: 1=white, 2=red, 3=green, 4=blue, 5=purple, 6=yellow, 7=cyan, 8=orange
- // The next three communication pins (D4, D5, D6) represent the color.
- switch (messageLetters[2]) {
- case '1':
- digitalWrite(4, LOW);
- digitalWrite(5, LOW);
- digitalWrite(6, LOW);
- break;
- case '2':
- digitalWrite(4, LOW);
- digitalWrite(5, LOW);
- digitalWrite(6, HIGH);
- break;
- case '3':
- digitalWrite(4, LOW);
- digitalWrite(5, HIGH);
- digitalWrite(6, LOW);
- break;
- case '4':
- digitalWrite(4, LOW);
- digitalWrite(5, HIGH);
- digitalWrite(6, HIGH);
- break;
- case '5':
- digitalWrite(4, HIGH);
- digitalWrite(5, LOW);
- digitalWrite(6, LOW);
- break;
- case '6':
- digitalWrite(4, HIGH);
- digitalWrite(5, LOW);
- digitalWrite(6, HIGH);
- break;
- case '7':
- digitalWrite(4, HIGH);
- digitalWrite(5, HIGH);
- digitalWrite(6, LOW);
- break;
- case '8':
- digitalWrite(4, HIGH);
- digitalWrite(5, HIGH);
- digitalWrite(6, HIGH);
- break;
- }
- // The fourth char represents the pattern. z=spinning wheel, x=right fill, c=left fill, v=right ball, b=left ball
- // The next three communication pins (D7, D8, D9) represent the color.
- switch (messageLetters[3]) {
- case 'z':
- digitalWrite(7, LOW);
- digitalWrite(8, LOW);
- digitalWrite(9, LOW);
- break;
- case 'x':
- digitalWrite(7, LOW);
- digitalWrite(8, LOW);
- digitalWrite(9, HIGH);
- break;
- case 'c':
- digitalWrite(7, LOW);
- digitalWrite(8, HIGH);
- digitalWrite(9, LOW);
- break;
- case 'v':
- digitalWrite(7, LOW);
- digitalWrite(8, HIGH);
- digitalWrite(9, HIGH);
- break;
- case 'b':
- digitalWrite(7, HIGH);
- digitalWrite(8, LOW);
- digitalWrite(9, LOW);
- break;
- default:
- // nothing here.
- break;
- }
- // Once the message has been performed, the message array is reset:
- resetMessage();
- } // if (messageCheck == true)
- else {
- // If the message cannot be performed because it is incorrect, then it is reset.
- resetMessage();
- }
- } // performMessage()
- bool perform_character_filter(char tLetter) {
- // This function is for checking the input letters as they are received.
- // Only the desired letters will return TRUE, any others will return FALSE.
- bool letterInRange = false;
- if (tLetter == 'e') {
- letterInRange = true;
- }
- if (tLetter == 's') {
- letterInRange = true;
- }
- if (tLetter == 'm') {
- letterInRange = true;
- }
- if (tLetter == 'q') {
- letterInRange = true;
- }
- if (tLetter == '1') {
- letterInRange = true;
- }
- if (tLetter == '2') {
- letterInRange = true;
- }
- if (tLetter == '3') {
- letterInRange = true;
- }
- if (tLetter == '4') {
- letterInRange = true;
- }
- if (tLetter == '5') {
- letterInRange = true;
- }
- if (tLetter == '6') {
- letterInRange = true;
- }
- if (tLetter == '7') {
- letterInRange = true;
- }
- if (tLetter == '8') {
- letterInRange = true;
- }
- if (tLetter == 'z') {
- letterInRange = true;
- }
- if (tLetter == 'x') {
- letterInRange = true;
- }
- if (tLetter == 'c') {
- letterInRange = true;
- }
- if (tLetter == 'v') {
- letterInRange = true;
- }
- if (tLetter == 'b') {
- letterInRange = true;
- }
- return letterInRange;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement