Advertisement
skizziks_53

Photobooth_NanoDuo_LED_Driver

Feb 2nd, 2018
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.11 KB | None | 0 0
  1. /*
  2.    Photobooth NanoDuo LED controller ---- 31 January 2018
  3.    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4.    This sketch uses the current Adafruit Neopixel library.
  5.  
  6.    The NanoDuo is two Arduino Nanos set up to act as a USB adressable-LED controller.
  7.    Using the same Nano to do both jobs seems to result in interrupt conflicts,
  8.        so the task is divided between two Nano boards here.
  9.  
  10.    In the NanoDuo setup, one Nano board receives the USB messages
  11.        and sets eight output pins in a way that represents the current LED settings.
  12.    The second Nano monitors eight input pins, and changes the LED values accordingly.
  13.    The pins used to communicate between the boards are pins D2 through D9, using external 220k pulldown resistors.
  14.  
  15.    This sketch is for the Nano that drives the LEDs based on the state of 8 input pins.
  16.    The sketch for the other Nano is named "Photobooth NanoDuo USB".
  17.  
  18.    This code was tested with a string of 8 and 64 WS2812 LEDs.
  19.  
  20.    ----------------------------
  21.    PATTERNS NEEDED:
  22.    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]
  23.   The 2nd letter represents the speed. s=slow, m=medium, q=fast
  24.   The number [8] represents a color choice: 1=white, 2=red, 3=green, 4=blue, 5=purple, 6=yellow, 7=cyan, 8=orange
  25.   The final letter represents the pattern. z=spinning wheel, x=right fill, c=left fill, v=right ball, b=left ball
  26.  
  27.  
  28. */
  29.  
  30. #include <Adafruit_NeoPixel.h>
  31. #ifdef __AVR__
  32. #include <avr/power.h>
  33. #endif
  34.  
  35. #define PIN            12 // This is the pin that the LED chain is connected to.
  36. #define NUMPIXELS      64
  37.  
  38. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
  39.  
  40. int pinStatus_checkInterval = 250; // This is the interval that the Nano checks its input pins for a state change.
  41. unsigned long checkInterval_beginTime = 0;
  42. unsigned long checkInterval_currentTime = 0;
  43.  
  44.  
  45. int LED_speed = 0; // This is the on/off control and also the speed: 0 = off, 1 = slow, 2 = medium and 3 = fast
  46. int LED_colorSetting = 0; // This is used to check for state changes.
  47. // 1=white, 2=red, 3=green, 4=blue, 5=purple, 6=yellow, 7=cyan, 8=orange
  48.  
  49. int LED_color_red = 0; // These are the three values used by the LEDs.
  50. int LED_color_green = 0; // Do not change these values, they will just get ignored.
  51. int LED_color_blue = 0; // The values used are assigned in the function update_LED_mode().
  52.  
  53. int LED_pattern = 0; // the pattern to use:  z=spinning wheel, x=right fill, c=left fill, v=right ball, b=left ball
  54. // the numerical version is 0=spinning wheel, 1=right fill, 2=left fill, 3=right ball, 4=left ball
  55.  
  56. int LED_master_dim_setting = 10; // This is an optional dimmer setting that is applied to all LEDs.
  57. // It is a factor of 100%, that is-- 100 = 100% of original coded brightness. 50 would mean (50% brightness).
  58.  
  59. int led_pattern_control_1 = 0; // This is a variable used to generate the different patterns.
  60. // The different patterns use it different ways.
  61.  
  62. int LED_animate_speed = 0; // This is the speed that the LED display changes at. Do not change this value!
  63. //                            One of the three values below gets copied into here.
  64. int LED_animate_speed_slow = 500; // milliseconds
  65. int LED_animate_speed_medium = 300;// milliseconds
  66. int LED_animate_speed_fast = 150;// milliseconds
  67.  
  68. unsigned long LED_change_beginTime = 0; // These are timer values for animating the LEDs.
  69. unsigned long LED_change_currentTime = 0;
  70.  
  71. int pinValue_A = 0; // These are three values to make pin reading more convenient.
  72. int pinValue_B = 0;
  73. int pinValue_C = 0;
  74.  
  75.  
  76.  
  77. // function prototypes
  78. void check_pin_status(); // This compares the previous pin status to the current one,
  79. //                          to find out if the LED display status must be updated
  80. void update_LED_mode(); // This updates the mode that the display is set to use, if necessary
  81. void update_LED_animation(); // This updates the LEDs if an animated display is running.
  82. void turn_all_LEDs_off(); // This is used to turn the LEDs off.
  83. int apply_dimmer_value(int colorValue); // This is used to apply the master dimmer value to color values before they are sent to the LEDs.
  84.  
  85. void led_pattern_0(); // These are the fuctions that control the five different display patterns.
  86. void led_pattern_1();
  87. void led_pattern_2();
  88. void led_pattern_3();
  89. void led_pattern_4();
  90.  
  91.  
  92. void setup() {
  93.  
  94.   // pins 2 through 9 are the machine state pins, using external 220k pulldown resistors.
  95.   pinMode(2, INPUT);
  96.   pinMode(3, INPUT);
  97.   pinMode(4, INPUT);
  98.   pinMode(5, INPUT);
  99.   pinMode(6, INPUT);
  100.   pinMode(7, INPUT);
  101.   pinMode(8, INPUT);
  102.   pinMode(9, INPUT);
  103.  
  104.   pixels.begin(); // This initializes the NeoPixel library.
  105.  
  106.   turn_all_LEDs_off();
  107. }
  108.  
  109.  
  110. void loop() {
  111.  
  112.   // This section checks the input pin states at the time interval of pinStatus_checkInterval.
  113.   checkInterval_currentTime = millis();
  114.   if (checkInterval_currentTime > checkInterval_beginTime) {
  115.     if (checkInterval_currentTime > (checkInterval_beginTime + pinStatus_checkInterval)) {
  116.       check_pin_status();
  117.       checkInterval_beginTime = millis(); // reset the previous change time to now.
  118.     }
  119.   }
  120.   else {
  121.     checkInterval_beginTime = millis(); // millis() rollover condition
  122.   }
  123.  
  124.  
  125.   // Below animates the LED display, if any pattern is running.
  126.   if (LED_speed > 0) { // zero = [off]
  127.     LED_change_currentTime = millis();
  128.     if (LED_change_currentTime > LED_change_beginTime) {
  129.       if (LED_change_currentTime > (LED_change_beginTime + LED_animate_speed)) {
  130.         update_LED_animation();
  131.         LED_change_beginTime = millis(); // reset the previous change time to now.
  132.       }
  133.     }
  134.     else {
  135.       LED_change_beginTime = millis(); // millis() rollover condition
  136.     }
  137.   }
  138.  
  139. } // end of main loop
  140.  
  141.  
  142.  
  143.  
  144. void check_pin_status() {
  145.   // This compares the previous pin status to the current one,
  146.   // to find out if the LED display status must be updated
  147.   bool LED_update_required = false;
  148.   int tempSpeedValue = 0;
  149.   pinValue_A = digitalRead(2);
  150.   pinValue_B = digitalRead(3);
  151.   //int LED_speed = 0; // 0 = off, 1 = slow, 2 = medium and 3 = fast
  152.   if (pinValue_A == LOW && pinValue_B == LOW) {
  153.     tempSpeedValue = 0;
  154.   }
  155.   if (pinValue_A == LOW && pinValue_B == HIGH) {
  156.     tempSpeedValue = 1;
  157.   }
  158.   if (pinValue_A == HIGH && pinValue_B == LOW) {
  159.     tempSpeedValue = 2;
  160.   }
  161.   if (pinValue_A == HIGH && pinValue_B == HIGH) {
  162.     tempSpeedValue = 3;
  163.   }
  164.   //LED_speed = tempValue;
  165.   if (LED_speed != tempSpeedValue) {
  166.     LED_update_required = true;
  167.   }
  168.   LED_speed = tempSpeedValue;
  169.  
  170.   //int LEDs_colorSetting = 0; // This is used to check for state changes.
  171.   // 1=white, 2=red, 3=green, 4=blue, 5=purple, 6=yellow, 7=cyan, 8=orange
  172.   int tempColorValue = 0;
  173.   pinValue_A = digitalRead(4);
  174.   pinValue_B = digitalRead(5);
  175.   pinValue_C = digitalRead(6);
  176.   if (pinValue_A == LOW && pinValue_B == LOW && pinValue_C == LOW) {
  177.     tempColorValue = 1;
  178.   }
  179.   if (pinValue_A == LOW && pinValue_B == LOW && pinValue_C == HIGH) {
  180.     tempColorValue = 2;
  181.   }
  182.   if (pinValue_A == LOW && pinValue_B == HIGH && pinValue_C == LOW) {
  183.     tempColorValue = 3;
  184.   }
  185.   if (pinValue_A == LOW && pinValue_B == HIGH && pinValue_C == HIGH) {
  186.     tempColorValue = 4;
  187.   }
  188.   if (pinValue_A == HIGH && pinValue_B == LOW && pinValue_C == LOW) {
  189.     tempColorValue = 5;
  190.   }
  191.   if (pinValue_A == HIGH && pinValue_B == LOW && pinValue_C == HIGH) {
  192.     tempColorValue = 6;
  193.   }
  194.   if (pinValue_A == HIGH && pinValue_B == HIGH && pinValue_C == LOW) {
  195.     tempColorValue = 7;
  196.   }
  197.   if (pinValue_A == HIGH && pinValue_B == HIGH && pinValue_C == HIGH) {
  198.     tempColorValue = 8;
  199.   }
  200.  
  201.   if (LED_colorSetting != tempColorValue) {
  202.     LED_update_required = true;
  203.   }
  204.   LED_colorSetting = tempColorValue;
  205.  
  206.   // int LED_pattern = 0; // the pattern to use:  z=spinning wheel, x=right fill, c=left fill, v=right ball, b=left ball
  207.   // the numerical version is 0=spinning wheel, 1=right fill, 2=left fill, 3=right ball, 4=left ball
  208.   int tempPatternValue = 0;
  209.   pinValue_A = digitalRead(7);
  210.   pinValue_B = digitalRead(8);
  211.   pinValue_C = digitalRead(9);
  212.  
  213.   if (pinValue_A == LOW && pinValue_B == LOW && pinValue_C == LOW) {
  214.     tempPatternValue = 0;
  215.   }
  216.   if (pinValue_A == LOW && pinValue_B == LOW && pinValue_C == HIGH) {
  217.     tempPatternValue = 1;
  218.   }
  219.   if (pinValue_A == LOW && pinValue_B == HIGH && pinValue_C == LOW) {
  220.     tempPatternValue = 2;
  221.   }
  222.   if (pinValue_A == LOW && pinValue_B == HIGH && pinValue_C == HIGH) {
  223.     tempPatternValue = 3;
  224.   }
  225.   if (pinValue_A == HIGH && pinValue_B == LOW && pinValue_C == LOW) {
  226.     tempPatternValue = 4;
  227.   }
  228.  
  229.   if (LED_pattern != tempPatternValue) {
  230.     LED_update_required = true;
  231.   }
  232.   LED_pattern = tempPatternValue;
  233.  
  234.   if (LED_update_required) {
  235.     update_LED_mode();
  236.   }
  237. }
  238.  
  239. int apply_dimmer_value(int colorValue) {
  240.   // This function applies a dimmer value (%) to an int color value and returns an int.
  241.   if (colorValue > 100) {
  242.       colorValue = 100;
  243.   }
  244.   if (colorValue > 0) {
  245.     if (LED_master_dim_setting > 0) {
  246.       int adjustedColorValue = (int) ((colorValue * LED_master_dim_setting) / 100);
  247.       return adjustedColorValue;
  248.     }
  249.     else {
  250.       return 0;
  251.     }
  252.   }
  253.   else {
  254.     return 0;
  255.   }
  256.  
  257. }
  258.  
  259.  
  260. void update_LED_animation() {
  261.   // This updates the LEDs if an animated display is running.
  262.   // Note: I just wrote five different LED patterns here. I didn't try to duplicate the exact photobooth patterns.
  263.  
  264.   if (LED_speed > 0) {
  265.     switch (LED_pattern) {
  266.       case 0:
  267.         led_pattern_0();
  268.         break;
  269.  
  270.       case 1:
  271.         led_pattern_1();
  272.         break;
  273.  
  274.       case 2:
  275.         led_pattern_2();
  276.         break;
  277.  
  278.       case 3:
  279.         led_pattern_3();
  280.         break;
  281.  
  282.       case 4:
  283.         led_pattern_4();
  284.         break;
  285.  
  286.     }
  287.   }
  288.   else {
  289.     turn_all_LEDs_off();
  290.   }
  291. }
  292.  
  293. void led_pattern_0() {
  294.   // This pattern blinks every other light off and on, in two sets.
  295.   if (led_pattern_control_1 == 0) {
  296.     for (int x = 0; x < NUMPIXELS; x = x + 2) {
  297.       pixels.setPixelColor(x, pixels.Color(LED_color_red, LED_color_green, LED_color_blue));
  298.     }
  299.     for (int y = 1; y < NUMPIXELS; y = y + 2) {
  300.       pixels.setPixelColor(y, pixels.Color(0, 0, 0));
  301.     }
  302.     led_pattern_control_1 = 1;
  303.     pixels.show();
  304.   }
  305.   else {
  306.     for (int x = 0; x < NUMPIXELS; x = x + 2) {
  307.       pixels.setPixelColor(x, pixels.Color(0, 0, 0));
  308.     }
  309.     for (int y = 1; y < NUMPIXELS; y = y + 2) {
  310.       pixels.setPixelColor(y, pixels.Color(LED_color_red, LED_color_green, LED_color_blue));
  311.     }
  312.     led_pattern_control_1 = 0;
  313.     pixels.show();
  314.   }
  315. }
  316.  
  317. void led_pattern_1() {
  318.   // This pattern chases one LED in one direction.
  319.   for (int x = 0; x < NUMPIXELS; x++) {
  320.     pixels.setPixelColor(x, pixels.Color(0, 0, 0));
  321.     if (x == led_pattern_control_1) {
  322.       pixels.setPixelColor(x, pixels.Color(LED_color_red, LED_color_green, LED_color_blue));
  323.     }
  324.   }
  325.   led_pattern_control_1++;
  326.   if (led_pattern_control_1 == NUMPIXELS) {
  327.     led_pattern_control_1 = 0;
  328.   }
  329.   pixels.show();
  330. }
  331.  
  332. void led_pattern_2() {
  333.   // This pattern chases one LED in the opposite direction of pattern #1.
  334.   for (int x = 0; x < NUMPIXELS; x++) {
  335.     pixels.setPixelColor(x, pixels.Color(0, 0, 0));
  336.     if (x == led_pattern_control_1) {
  337.       pixels.setPixelColor(x, pixels.Color(LED_color_red, LED_color_green, LED_color_blue));
  338.     }
  339.   }
  340.   led_pattern_control_1--; // <--------- to reverse the direction, only 1 line is changed compared to pattern #1
  341.   if (led_pattern_control_1 == -1) {
  342.     led_pattern_control_1 = (NUMPIXELS - 1);
  343.   }
  344.   pixels.show();
  345. }
  346.  
  347. void led_pattern_3() {
  348.   // This pattern fills the LEDs in one direction.
  349.   for (int x = 0; x < NUMPIXELS; x++) {
  350.     if (x <= led_pattern_control_1) {
  351.       pixels.setPixelColor(x, pixels.Color(LED_color_red, LED_color_green, LED_color_blue));
  352.     }
  353.     else {
  354.       pixels.setPixelColor(x, pixels.Color(0, 0, 0));
  355.     }
  356.   }
  357.   led_pattern_control_1++;
  358.   if (led_pattern_control_1 == NUMPIXELS) {
  359.     led_pattern_control_1 = 0;
  360.   }
  361.   pixels.show();
  362. }
  363.  
  364. void led_pattern_4() {
  365.   // This pattern fills the LEDs in the opposite direction of pattern #3.
  366.   for (int x = 0; x < NUMPIXELS; x++) {
  367.     if (x >= led_pattern_control_1) {
  368.       pixels.setPixelColor(x, pixels.Color(LED_color_red, LED_color_green, LED_color_blue));
  369.     }
  370.     else {
  371.       pixels.setPixelColor(x, pixels.Color(0, 0, 0));
  372.     }
  373.   }
  374.   led_pattern_control_1--;
  375.   if (led_pattern_control_1 == -1) {
  376.     led_pattern_control_1 = (NUMPIXELS - 1);
  377.   }
  378.   pixels.show();
  379. }
  380.  
  381. void turn_all_LEDs_off() {
  382.   // This just turns all the LEDs off.
  383.   for (int x = 0; x < NUMPIXELS; x++) {
  384.     pixels.setPixelColor(x, pixels.Color(0, 0, 0));
  385.   }
  386.   pixels.show();
  387. }
  388.  
  389.  
  390.  
  391. void update_LED_mode() {
  392.   // This updates the mode that the display is set to use, if necessary
  393.   // This function allows you to set up a starting point for an animation,
  394.   // when the display transitions from one animation to a different one.
  395.  
  396.   // The section below updates the animation speed.
  397.   if (LED_speed == 1) {
  398.     LED_animate_speed = LED_animate_speed_slow;
  399.   }
  400.   if (LED_speed == 2) {
  401.     LED_animate_speed = LED_animate_speed_medium;
  402.   }
  403.   if (LED_speed == 3) {
  404.     LED_animate_speed = LED_animate_speed_fast;
  405.   }
  406.   if (LED_speed == 0) {
  407.     turn_all_LEDs_off();
  408.   }
  409.  
  410.  
  411.   // The section below updates the color setting.
  412.   switch (LED_colorSetting) {
  413.     case 1:
  414.       // color = white
  415.       LED_color_red = apply_dimmer_value(255);
  416.       LED_color_green = apply_dimmer_value(255);
  417.       LED_color_blue = apply_dimmer_value(255);
  418.       break;
  419.     case 2:
  420.       // color = red
  421.       LED_color_red = apply_dimmer_value(255);
  422.       LED_color_green = apply_dimmer_value(0);
  423.       LED_color_blue = apply_dimmer_value(0);
  424.       break;
  425.     case 3:
  426.       // color = green
  427.       LED_color_red = apply_dimmer_value(0);
  428.       LED_color_green = apply_dimmer_value(255);
  429.       LED_color_blue = apply_dimmer_value(0);
  430.       break;
  431.     case 4:
  432.       // color = blue
  433.       LED_color_red = apply_dimmer_value(0);
  434.       LED_color_green = apply_dimmer_value(0);
  435.       LED_color_blue = apply_dimmer_value(255);
  436.       break;
  437.     case 5:
  438.       // color = purple
  439.       LED_color_red = apply_dimmer_value(128);
  440.       LED_color_green = apply_dimmer_value(0);
  441.       LED_color_blue = apply_dimmer_value(128);
  442.       break;
  443.     case 6:
  444.       // color = yellow
  445.       LED_color_red = apply_dimmer_value(255);
  446.       LED_color_green = apply_dimmer_value(255);
  447.       LED_color_blue = apply_dimmer_value(0);
  448.       break;
  449.     case 7:
  450.       // color = cyan
  451.       LED_color_red = apply_dimmer_value(0);
  452.       LED_color_green = apply_dimmer_value(255);
  453.       LED_color_blue = apply_dimmer_value(255);
  454.       break;
  455.     case 8:
  456.       // color = orange
  457.       LED_color_red = apply_dimmer_value(255);
  458.       LED_color_green = apply_dimmer_value(64);
  459.       LED_color_blue = apply_dimmer_value(0);
  460.       break;
  461.   }
  462.  
  463.  
  464.   // The section below initializes starting positions for the different patterns:
  465.   switch (LED_pattern) {
  466.     case 0:
  467.       // This pattern blinks every other light off and on, in two sets.
  468.       // It doesn't really have a direction that it moves.
  469.       // The led_pattern_control_1 is only used to switch back and forth between the two sets of lights to turn on.
  470.       turn_all_LEDs_off();
  471.       led_pattern_control_1 = 0;
  472.       break;
  473.     case 1:
  474.       // This pattern chases one LED in one direction.
  475.       turn_all_LEDs_off();
  476.       led_pattern_control_1 = 0;
  477.       break;
  478.     case 2:
  479.       // This pattern chases one LED in the opposite direction of pattern #1.
  480.       turn_all_LEDs_off();
  481.       led_pattern_control_1 = (NUMPIXELS - 1);
  482.       break;
  483.     case 3:
  484.       // This pattern fills the LEDs in one direction.
  485.       turn_all_LEDs_off();
  486.       led_pattern_control_1 = 0;
  487.       break;
  488.     case 4:
  489.       // This pattern fills the LEDs in the opposite direction of pattern #3.
  490.       turn_all_LEDs_off();
  491.       led_pattern_control_1 = (NUMPIXELS - 1);
  492.       break;
  493.   }
  494.  
  495.   // The pattern itself is updated in check_pin_status().
  496.  
  497.   update_LED_animation();
  498.   LED_change_beginTime = millis();
  499. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement