Guest User

berkana_v2_2_non_blocking

a guest
Dec 9th, 2014
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.84 KB | None | 0 0
  1. /***************************************************************************/
  2. //LED sign for our home using RadioShack Tricolor LED Strip
  3. //  By Richard Bailey
  4. //
  5. // Version 2.2.3
  6. // User interface fixed for now, brightness implemented.
  7. // Future updates from this point will most likely to clean up the code and reduce size.
  8. //
  9. // Version 2.2.2
  10. // Start implementation of menu options to adjust brightness and frame speed
  11. // frame delay adjustment implemented, need to tweak user interface to be more
  12. // user friendly.
  13. //
  14. // Version 2.2.1
  15. // move kelley pattern out of main loop into subroutine as prep for menu system.
  16. //
  17. // Version 2.2.0
  18. // physical prototyping board with  LED connector, analog color selector and circuits on it built.
  19. // incorporate LCD sample code to begin working on menu system.
  20. // reorganize code to be closer to standard practices.
  21. //
  22. //  Version 2.1.1
  23. //  complete restucture to stop using delay()
  24. //
  25. // Version 2.1.0
  26. // convert colors from RGB to HSV to allow simple addition of color picker
  27. //
  28. // Version 2.0.4
  29. // June 24, 2014
  30. // implement use of high_intensity variable, move blanking to subroutine, and bug fixes
  31. //
  32. //
  33. // Version 2.0.3
  34. // June 20, 2014
  35. // setup color codes into two dimensional array and a code option to
  36. // have random colors. Currently set to cycle through the preprogrammed colors.
  37. // Need to get the display shield to program the
  38. // interface for stand alone operation as well as a 12vdc power supply
  39. // of at least 2 amps.
  40. //
  41. //
  42. // Version 2.0.2
  43. // June 20, 2014
  44. // converted from using hex color codes to individual RGB colors
  45. // to allow custom color selection with on board controls planned
  46. // for later versions.
  47. // now includes output to serial for debugging use.
  48. //
  49. //
  50. // Version 2.0.1
  51. // complete rebuild using FastLED library instead of the RadioShack code.
  52. /***************************************************************************/
  53. #include <avr/pgmspace.h>
  54. #include <FastLED.h>
  55. #include <Wire.h>
  56. #include <Adafruit_MCP23017.h>
  57. #include <Adafruit_RGBLCDShield.h>
  58.  
  59. // Variable definitions start here
  60.  
  61. // How many leds are in the strip?
  62. #define NUM_LEDS 12
  63.  
  64. // Data pin that led data will be written out over
  65. #define DATA_PIN 11
  66.  
  67. // start points for frames  DO NOT CHANGE, THE CURRENT CODE WILL BREAK.
  68. #define xstart 1
  69. #define ystart 2
  70.  
  71.  
  72. // define analog color pins for color selector output
  73. #define REDPIN   5
  74. #define GREENPIN 6
  75. #define BLUEPIN  3
  76. // These #defines make it easy to set the backlight color
  77. #define RED 0x1
  78. #define YELLOW 0x3
  79. #define GREEN 0x2
  80. #define TEAL 0x6
  81. #define BLUE 0x4
  82. #define VIOLET 0x5
  83. #define WHITE 0x7
  84.  
  85. // define the delay between frames in milliseconds.
  86. long frame_delay = 50;
  87.  
  88. // define intensity levels
  89. uint8_t high_intensity = 128;
  90. uint8_t med_intensity = high_intensity * .66;
  91. uint8_t low_intensity = high_intensity * .33;
  92. // This is an array of leds.  One item for each led in your strip.
  93. CRGB leds[NUM_LEDS];
  94.  
  95. // predefined color arrays
  96. PROGMEM unsigned int colors[][2] = {
  97.     {
  98.     64,255                                    }
  99.     , // yellow
  100.     {
  101.     0,255                                    }
  102.     , //red
  103.     {
  104.     160,255                                    }
  105.     , //blue
  106.     {
  107.     96,255                                    }
  108.     , //green
  109.     {
  110.     192,255                                    }
  111.     , //purple
  112.     {
  113.     255,0                                    }
  114.     , //white
  115. };
  116.  
  117. // define menus
  118.  
  119. // main menu
  120.  
  121. char* main_menu[] = {"Kelley Yellow","Kelley Red","Kelley Blue","Kelley Green","Kelley Purple","Kelley White","Kelley dial","Rainbow chase", "Rainbow cycle", "Frame Delay", "Brightness"};
  122. int menu_count = 11;
  123.  
  124. const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
  125. int sensorValue = 0;        // value read from the pot
  126.  
  127. //initialize variables
  128.  
  129. int x; // variable for first group, counts down and wraps around.
  130. int y; // variable for second group, counts up.
  131. unsigned int led_color[2];  //array that holds the current color codes for the LEDS
  132. int c = 0;
  133. long last_millis;
  134. long current_millis;
  135. int frame_count;
  136. static uint8_t hue;
  137. bool kpattern_selected = true;
  138. bool chase_selected = false;
  139. bool cycle_selected = false;
  140. bool idle = true;
  141. int kelley_menu_selection = 0;
  142. int menu_active=0;
  143. int menu_current = menu_active;
  144. int menu_previous = menu_current;
  145. long last_button;
  146.  
  147. // The shield uses the I2C SCL and SDA pins. On classic Arduinos
  148. // this is Analog 4 and 5 so you can't use those for analogRead() anymore
  149. // However, you can connect other I2C sensors to the I2C bus and share
  150. // the I2C bus.
  151. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
  152.  
  153. // ***********************************************************************************************************
  154. // *
  155. // *                            Power Up Init.
  156. // *
  157. // *
  158. // ***********************************************************************************************************
  159. void setup() {
  160.  
  161.     //  Serial.begin(115200);
  162.  
  163.     // sanity check delay - allows reprogramming if accidently blowing power w/leds
  164.     delay(3000);
  165.  
  166.     // set up the LCD's number of columns and rows:
  167.     lcd.begin(16, 2);
  168.     // Print a message to the LCD. We track how long it takes since
  169.     // this library has been optimized a bit and we're proud of it :)
  170.     //  int time = millis();
  171.     lcd.print(F("Berkana"));
  172.     //  time = millis() - time;
  173.     //  Serial.print(F("Took "));
  174.     //  Serial.print(time);
  175.     //  Serial.println(F(" ms"));
  176.     lcd.setBacklight(WHITE);
  177.  
  178.  
  179.  
  180.     // Change this line as needed to match the LED string type, control chip and color sequence
  181.     FastLED.addLeds<TM1803, DATA_PIN, GBR>(leds, NUM_LEDS); // RadioShack LED String
  182.  
  183.     // turn off all leds
  184.     fill_solid ( &(leds[0]), NUM_LEDS, CRGB::Black);
  185.     FastLED.show();
  186.     delay (200);
  187.  
  188.     pinMode(REDPIN,   OUTPUT);
  189.     pinMode(GREENPIN, OUTPUT);
  190.     pinMode(BLUEPIN,  OUTPUT);
  191.  
  192.     // Flash the "hello" color sequence: R, G, B, black.
  193.     colorBars();
  194.     last_millis=millis();
  195.     last_button=millis();
  196.     frame_count=0;
  197.     led_color[0] = pgm_read_dword_near(&colors[c][0]);
  198.     led_color[1] = pgm_read_dword_near(&colors[c][1]);
  199.  
  200. }
  201.  
  202. // ***********************************************************************************************************
  203. // *
  204. // *                            Main Loop
  205. // *
  206. // *
  207. // ***********************************************************************************************************
  208. void loop()
  209. {
  210.     // read the analog in value: and display on sample LED
  211.     sensorValue = analogRead(analogInPin);
  212.     hue = map(sensorValue, 0, 1023, 0, 255);
  213.     // Use FastLED automatic HSV->RGB conversion
  214.     showAnalogRGB( CHSV( hue, 255, high_intensity) );
  215.  
  216.     // set the cursor to column 0, line 1
  217.     // (note: line 1 is the second row, since counting begins with 0):
  218.     lcd.setCursor(0, 1);
  219.     // print the number of seconds since reset:
  220.     //lcd.print("Active: ");
  221.     lcd.print(main_menu[menu_active]);
  222.     //    menu_previous = menu_current;
  223.     if ((millis()-last_button) > 10000 && menu_active <9){
  224.         if (idle == false){
  225.             lcd.setCursor(0,0);
  226.             lcd.print("                ");
  227.             idle = true;
  228.         }
  229.         lcd.setCursor(0,0);
  230.         lcd.print("Berkana");
  231.     }
  232.     uint8_t buttons = lcd.readButtons();
  233.     if ((millis()-last_button) > 333) {
  234.         if (buttons) {
  235.             lcd.clear();
  236.             lcd.setCursor(0,0);
  237.             if (buttons & BUTTON_UP) {
  238.                 if (menu_current == 0){
  239.                     menu_current = menu_count-1;
  240.                 }
  241.                 else {
  242.                     menu_current = menu_current--;
  243.                 }
  244.                 last_button=millis();
  245.                 idle = false;
  246.                 //lcd.print("Menu: ");
  247.                 lcd.print(main_menu[menu_current]);
  248.                 //          lcd.setBacklight(GREEN);
  249.                 //lcd.print("up");
  250.             }
  251.             if (buttons & BUTTON_DOWN) {
  252.                 if (menu_current == menu_count-1) {
  253.                     menu_current = 0;
  254.                 }
  255.                 else {
  256.                     menu_current=menu_current++;
  257.                 }
  258.                 last_button=millis();
  259.                 idle = false;
  260.                 //lcd.print("Menu: ");
  261.                 lcd.print(main_menu[menu_current]);
  262.             }
  263.             if (menu_active==9){
  264.                 //lcd.clear();
  265.                 lcd.setCursor(0,0);
  266.                 //lcd.print(frame_delay);
  267.                 if (buttons & BUTTON_LEFT) {
  268.                     //lcd.setCursor(0,1);
  269.                     if (frame_delay > 50) {
  270.                         frame_delay=(frame_delay - 50);
  271.                         lcd.print(frame_delay);
  272.                     }
  273.                 }
  274.                 if (buttons & BUTTON_RIGHT) {
  275.                     //lcd.clear();
  276.                     //lcd.setCursor(0,0);
  277.                     //lcd.print(main_menu[menu_current]);
  278.                     //lcd.setCursor(0,1);
  279.                     if (frame_delay < 5000) {
  280.                         frame_delay= (frame_delay + 50);
  281.                         lcd.print(frame_delay);
  282.                     }
  283.                 }
  284.                 if (buttons & BUTTON_SELECT) {
  285.                     menu_active=menu_previous;
  286.                     lcd.clear();
  287.                     lcd.setCursor(0,0);
  288.                     lcd.print("Berkana");
  289.                 }
  290.             }
  291.             if (menu_active==10){
  292.                 lcd.setCursor(0,0);
  293.                 if (buttons & BUTTON_LEFT) {
  294.                     if (high_intensity > 72) {
  295.                         high_intensity=(high_intensity - 4);
  296.                         lcd.print(high_intensity);
  297.                     }
  298.                 }
  299.                 if (buttons & BUTTON_RIGHT) {
  300.                     if (high_intensity < 252) {
  301.                         high_intensity= (high_intensity + 4);
  302.                         lcd.print(high_intensity);
  303.                     }
  304.                 }
  305.                 if (buttons & BUTTON_SELECT) {
  306.                     menu_active=menu_previous;
  307.                     lcd.clear();
  308.                     lcd.setCursor(0,0);
  309.                     lcd.print("Berkana");
  310.                 }
  311.             }
  312.             if (buttons & BUTTON_SELECT) {
  313.                 menu_previous=menu_active;
  314.                 menu_active=menu_current;
  315.                 lcd.clear();
  316.                 lcd.setCursor(0,0);
  317.                 lcd.print("Berkana");
  318.                 //lcd.setCursor(0,0);
  319.                 //lcd.print("Menu: ");
  320.                 //lcd.print(main_menu[menu_current]);
  321.                
  322.             }
  323.         }
  324.     }
  325.    
  326.     choice_update();
  327.  
  328.     current_millis=millis();
  329.     if (kpattern_selected)
  330.     { kelley_pattern();
  331.     };
  332.     if (chase_selected)
  333.     {
  334.         chase_sub();
  335.     };
  336.     if (cycle_selected)
  337.     {
  338.         cycle_sub();
  339.     };
  340.  
  341.  
  342. }
  343.  
  344.  
  345. // ***********************************************************************************************************
  346. // *
  347. // *                            Subroutines
  348. // *
  349. // *
  350. // ***********************************************************************************************************
  351.  
  352. void showAnalogRGB( const CRGB& rgb)
  353. {
  354.     // showAnalogRGB: this is like FastLED.show(), but outputs on
  355.     // analog PWM output pins instead of sending data to an intelligent,
  356.     // pixel-addressable LED strip.
  357.     //
  358.     // This function takes the incoming RGB values and outputs the values
  359.     // on three analog PWM output pins to the r, g, and b values respectively.
  360.  
  361.     analogWrite(REDPIN,   rgb.r );
  362.     analogWrite(GREENPIN, rgb.g );
  363.     analogWrite(BLUEPIN,  rgb.b );
  364. }
  365. void kelley_pattern() {
  366.     // subroutine to display kelley pattern in selected color
  367.     if (kelley_menu_selection < 6) {
  368.         led_color[0] = pgm_read_dword_near(&colors[kelley_menu_selection][0]);
  369.         led_color[1] = pgm_read_dword_near(&colors[kelley_menu_selection][1]);
  370.     };
  371.  
  372.     if (kelley_menu_selection == 6){
  373.         // set color to analog picker color
  374.         led_color[0]= hue;
  375.         led_color[1]= 255;
  376.     };
  377.     if (current_millis-last_millis > frame_delay) {
  378.         delay(0);
  379.         last_millis=current_millis;
  380.  
  381.         if (frame_count == 0 ) {
  382.             x=xstart;
  383.             y=ystart;
  384.             frame_count++;
  385.             return;
  386.         }
  387.         if (frame_count == 1 ) {
  388.             kelley_frame();
  389.             return;
  390.  
  391.         }
  392.  
  393.         if (frame_count == 2){
  394.             kelley_frame();
  395.             return;
  396.         }
  397.  
  398.         if (frame_count == 3) {
  399.             kelley_frame();
  400.             return;
  401.         }
  402.  
  403.         if (frame_count == 4) {
  404.             kelley_frame();
  405.             return;
  406.         }
  407.  
  408.         if (frame_count == 5) {
  409.             kelley_frame();
  410.             return;
  411.         }
  412.  
  413.         if (frame_count == 6) {
  414.             kelley_frame();
  415.             return;
  416.         }
  417.  
  418.         if (frame_count == 7) {
  419.             kelley_frame();
  420.             return;
  421.         }
  422.  
  423.         if (frame_count == 8) {
  424.             kelley_frame();
  425.             return;
  426.         }
  427.  
  428.         if (frame_count == 9) {
  429.             x=xstart;
  430.             y=ystart;
  431.             kelley_blank();
  432.             return;
  433.         }
  434.  
  435.         if (frame_count == 10){
  436.             kelley_blank();
  437.             return;
  438.         }
  439.         if (frame_count == 11){
  440.             kelley_blank();
  441.             return;
  442.         }
  443.         if (frame_count == 12){
  444.             kelley_blank();
  445.             return;
  446.         }
  447.         if (frame_count == 13){
  448.             kelley_blank();
  449.             return;
  450.         }
  451.         if (frame_count == 14){
  452.             kelley_blank();
  453.             frame_count = 0;
  454.             return;
  455.         }
  456.  
  457.  
  458.     }
  459. }
  460. void kelley_frame() {
  461.     // generates frames for kelley_pattern
  462.     if (frame_count <= (NUM_LEDS/2)){
  463.         leds[(x+NUM_LEDS) % NUM_LEDS]=CHSV(led_color[0],led_color[1],low_intensity);
  464.         leds[y] = leds[(x+NUM_LEDS) % NUM_LEDS];
  465.     }
  466.     if (frame_count >1 && frame_count <= (NUM_LEDS/2)+1) {
  467.         leds[(1+x+NUM_LEDS) % NUM_LEDS]=CHSV(led_color[0],led_color[1],med_intensity);
  468.         leds[y-1] = leds[(1+x+NUM_LEDS) % NUM_LEDS];
  469.     }
  470.     if (frame_count >2 && frame_count <= (NUM_LEDS/2)+2) {
  471.         leds[(2+x+NUM_LEDS) % NUM_LEDS]=CHSV(led_color[0],led_color[1],high_intensity);
  472.         leds[y-2] = leds[(2+x+NUM_LEDS) % NUM_LEDS];
  473.     }
  474.     FastLED.show();
  475.     x--;
  476.     y++;
  477.     frame_count++;
  478. }
  479. void kelley_blank () {
  480.     // blanking subroutine for kelley_pattern
  481.     leds[(x+NUM_LEDS) % NUM_LEDS]=CHSV(led_color[0],led_color[1],0);
  482.     leds[y] = leds[(x+NUM_LEDS) % NUM_LEDS];
  483.     FastLED.show();
  484.     x--;
  485.     y++;
  486.     frame_count++;
  487. }
  488. void colorBars()
  489. {
  490.     // colorBars: flashes Red, then Green, then Blue, then Black.
  491.     // Helpful for diagnosing if you've mis-wired which is which.
  492.  
  493.     showAnalogRGB( CRGB::Red );
  494.     delay(500);
  495.     showAnalogRGB( CRGB::Green );
  496.     delay(500);
  497.     showAnalogRGB( CRGB::Blue );
  498.     delay(500);
  499.     showAnalogRGB( CRGB::Black );
  500.     delay(500);
  501. }
  502. void chase_sub() {
  503.     if (current_millis-last_millis > frame_delay * .15) {
  504.         delay(0);
  505.         last_millis=current_millis;
  506.         static uint8_t hue = 64;
  507.         leds[x % NUM_LEDS]=CHSV(hue--, 255, high_intensity);
  508.         FastLED.show();
  509.         x++;
  510.     }
  511. }
  512. void cycle_sub() {
  513.     if (current_millis-last_millis > (frame_delay * .5)) {
  514.         delay(0);
  515.         last_millis=current_millis;
  516.  
  517.         static uint8_t hue = 64;
  518.         FastLED.showColor(CHSV(hue--, 255, high_intensity));
  519.         // delay (frame_delay);
  520.     }
  521. }
  522. void choice_update()
  523. {
  524.     if (menu_active < 7) {
  525.         kpattern_selected = true;
  526.         chase_selected = false;
  527.         cycle_selected = false;
  528.         kelley_menu_selection = menu_active;
  529.         // Serial.println(kelley_menu_selection);
  530.        
  531.     }
  532.     if (menu_active == 7) {
  533.         kpattern_selected = false;
  534.         chase_selected = true;
  535.         cycle_selected = false;
  536.     }
  537.     if (menu_active == 8) {
  538.         kpattern_selected = false;
  539.         chase_selected = false;
  540.         cycle_selected = true;
  541.     }
  542. }
Advertisement
Add Comment
Please, Sign In to add comment