Advertisement
GyroGearloose

FastLED and I2C Accel

Aug 17th, 2015
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.67 KB | None | 0 0
  1. /* ==================================================================================================================================================
  2.  
  3. replaced analog accel sensor with BMA020 Bosch Sensortec (I2C)
  4.  
  5. y-accel works; use Y1 and Y2 (Y1 only does not work)
  6. Arduino 1.6.4.
  7. **Gyro Gearloose**
  8.  
  9. Original sketch from:
  10. http://arduinobasics.blogspot.com.au/2015/07/neopixel-playground.html
  11.          Project: NeoPixel Playground
  12. Neopixel chipset: ws2812B  (144 LED/m strip)
  13.           Author: Scott C
  14.          Created: 12th June 2015
  15.      Arduino IDE: 1.6.4
  16.          Website: http://arduinobasics.blogspot.com/p/arduino-basics-projects-page.html
  17.      Description: This project will allow you to cycle through and control five LED
  18.                   animation sequences using a potentiometer and an accelerometer
  19.                      Sequence 1:   Cylon with Hue Control                                       Control: Potentiometer only
  20.                      Sequence 2:   Cylon with Brightness Control                                Control: Potentiometer only
  21.                      Sequence 3:   Comet effect with Hue and direction control                  Control: Potentiometer and Accelerometer (Y axis only)
  22.                      Sequence 4:   FireStarter / Rainbow effect with Hue and Direction control  Control: Potentiometer and Accelerometer (Y axis only)
  23.                      Sequence 5:   Digital Spirit Level                                         Control: Accelerometer only (Y axis)
  24.            
  25.                   This project makes use of the FastLED library. Some of the code below was adapted from the FastLED library examples (eg. Cylon routine).
  26.                   The Comet, FireStarter and Digital Spirit Level sequence was designed by ScottC.
  27.                   The FastLED library can be found here: http://fastled.io/
  28.                   You may need to modify the code below to accomodate your specific LED strip. See the FastLED library site for more details.
  29. ===================================================================================================================================================== */
  30.  
  31. #include <Wire.h>
  32. #define AccelerometerAddress 0x38
  33. #define Axis_Y_Out1 0x04
  34. #define Axis_Y_Out2 0x05
  35.  
  36.  
  37.  
  38. //This project needs the FastLED library - link in the description.
  39. #include "FastLED.h"
  40.  
  41. //The total number of LEDs being used is 144
  42. #define NUM_LEDS 144
  43.  
  44. // The data pin for the NeoPixel strip is connected to digital Pin 6 on the Arduino
  45. #define DATA_PIN 6
  46. #define CLOCK_PIN 8
  47.  
  48. //Initialise the LED array, the LED Hue (ledh) array, and the LED Brightness (ledb) array.
  49. CRGB leds[NUM_LEDS];
  50. byte ledh[NUM_LEDS];
  51. byte ledb[NUM_LEDS];
  52.  
  53. //Pin connections
  54. const int potPin = A0;      // The potentiometer signal pin is connected to Arduino's Analog Pin 0
  55. const int yPin = A4;        // Y pin on accelerometer is connected to Arduino's Analog Pin 4
  56.                             // The accelerometer's X Pin and the Z Pin were not used in this sketch
  57.  
  58. //Global Variables ---------------------------------------------------------------------------------
  59. byte potVal;                // potVal:      stores the potentiometer signal value
  60. byte prevPotVal=0;          // prevPotVal:  stores the previous potentiometer value
  61. int LEDSpeed=1;             // LEDSpeed:    stores the "speed" of the LED animation sequence
  62. int maxLEDSpeed = 80;       // maxLEDSpeed: identifies the maximum speed of the LED animation sequence
  63. int LEDAccel=0;             // LEDAccel:    stores the acceleration value of the LED animation sequence (to speed it up or slow it down)
  64. int LEDPosition=72;         // LEDPosition: identifies the LED within the strip to modify (leading LED). The number will be between 0-143.  (Zero to NUM_LEDS-1)
  65. int oldPos=0;               // oldPos:      holds the previous position of the leading LED
  66. byte hue = 0;               // hue:         stores the leading LED's hue value
  67. byte intensity = 150;       // intensity:   the default brightness of the leading LED
  68. byte bright = 80;           // bright:      this variable is used to modify the brightness of the trailing LEDs
  69. int animationDelay = 0;     // animationDelay: is used in the animation Speed calculation. The greater the animationDelay, the slower the LED sequence.
  70. int effect = 0;             // effect:      is used to differentiate and select one out of the four effects
  71. int sparkTest = 0;          // sparkTest:   variable used in the "sparkle" LED animation sequence
  72. boolean constSpeed = false; // constSpeed:  toggle between constant and variable speed.
  73.  
  74.  
  75. //===================================================================================================================================================
  76. // setup() : Is used to initialise the LED strip
  77. //===================================================================================================================================================
  78. void setup() {
  79.     delay(2000);          //Delay for two seconds to power the LEDS before starting the data signal on the Arduino
  80.     FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN /*, GBR*/ >(leds, NUM_LEDS);                            //initialise the LED strip      
  81.   FastLED.setCorrection(TypicalPixelString);
  82.   Wire.begin();
  83.   Serial.begin(9600);
  84.  
  85. }
  86.  
  87.  
  88. //===================================================================================================================================================
  89. // loop() : The Arduino will take readings from the potentiometer and accelerometer to control the LED strip
  90. //===================================================================================================================================================
  91. void loop(){
  92.   readPotentiometer();          
  93. //Serial.println(potVal);
  94.   adjustSpeed();
  95.   constrainLEDs();
  96.  
  97.   switch(effect){
  98.     case 0:                                               // 1st effect : Cylon with Hue control - using Potentiometer
  99. //    Serial.println(0);
  100.       cylonWithHueControl();
  101.       break;
  102.      
  103.     case 1:                                               // 2nd effect : Cylon with Brightness control - using Potentiometer
  104. //    Serial.println(1);
  105.       cylonWithBrightnessControl();
  106.       break;
  107.      
  108.     case 2:                                               // 3rd effect : Comet effect. Hue controlled by potentiometer, direction by accelerometer
  109. //     Serial.println(2);
  110.       cometEffect();
  111.       break;
  112.      
  113.     case 3:                                               // 4th effect : FireStarter / Rainbow Sparkle effect. Direction controlled by accelerometer, sparkle by potentiometer.
  114. //     Serial.println(3);
  115.       fireStarter();
  116.       break;
  117.    
  118.     case 4:
  119. //     Serial.println(4);
  120.       levelSense();                                        // 5th effect : LevelSense - uses the accelerometer to create a digital "spirit" level.
  121.       break;
  122.   }
  123. }
  124.  
  125.  
  126. //===================================================================================================================================================
  127. // readPotentiometer() : Take a potentiometer reading. This value will be used to control various LED animations, and to choose the animation sequence to display.
  128. //===================================================================================================================================================
  129. void readPotentiometer(){
  130.   //Take a reading from the potentiometer and convert the value into a number between 0 and 255
  131.   potVal = map(analogRead(potPin), 0, 1023 , 0, 255);
  132.  
  133.   // If the potentiometer reading is equal to zero, then move to the next effect in the list.
  134.   if(potVal==0){
  135.     if(prevPotVal>0){   // This allows us to switch effects only when the potentiometer reading has changed to zero (from a positive number). Multiple zero readings will be ignored.
  136.       prevPotVal = 0;   // Set the prev pot value to zero in order to ignore replicate zero readings.
  137.       effect++;         // Go to the next effect.
  138.       if(effect>4){
  139.         effect=0;       // Go back to the first effect after the fifth effect.
  140.       }
  141.     }
  142.   }
  143.   prevPotVal=potVal;    // Keep track of the previous potentiometer reading
  144. }
  145.  
  146.  
  147. //===================================================================================================================================================
  148. // adjustSpeed() : use the Y axis value of the accelerometer to adjust the speed and the direction of the LED animation sequence
  149. //===================================================================================================================================================
  150. void adjustSpeed(){
  151.   // Take a reading from the Y Pin of the accelerometer and adjust the value so that
  152.   // positive numbers move in one direction, and negative numbers move in the opposite diraction.
  153.   // We use the map function to convert the accelerometer readings, and the constrain function to ensure that it stays within the desired limits
  154.   // The values of 230 and 640 were determined by trial and error and are specific to my accelerometer. You will need to adjust these numbers to suit your module.
  155.  
  156. int Y_1 = readAcceleration(Axis_Y_Out1);  
  157. int Y_2 = readAcceleration(Axis_Y_Out2);
  158. //  LEDAccel = constrain(map(analogRead(yPin), 230, 640 , maxLEDSpeed, -maxLEDSpeed),-maxLEDSpeed, maxLEDSpeed);
  159.   LEDAccel = constrain(map(Y_2, 0, 250 , maxLEDSpeed, -maxLEDSpeed),-maxLEDSpeed, maxLEDSpeed);
  160. //Serial.print(Y_2);
  161. //Serial.print("\t");
  162. //Serial.println(LEDAccel);  
  163.  
  164.   // If the constSpeed variable is "true", then make sure that the speed of the animation is constant by modifying the LEDSpeed and LEDAccel variables.
  165.   if(constSpeed){
  166.     LEDAccel=0;
  167.     if(LEDSpeed>0){
  168.       LEDSpeed = maxLEDSpeed/1.1;     // Adjust the LEDSpeed to half the maximum speed in the positive direction
  169.     }
  170.     if (LEDSpeed<0){
  171.       LEDSpeed = -maxLEDSpeed/1.1;    // Adjust the LEDSpeed to half the maximum speed in the negative direction
  172.     }
  173.   }
  174.  
  175.   // The Speed of the LED animation sequence can increase (accelerate), decrease (decelerate) or stay the same (constant speed)
  176.   LEDSpeed = LEDSpeed + LEDAccel;                        
  177.  
  178.   //The following lines of code are used to control the direction of the LED animation sequence, and limit the speed of that animation.
  179.   if (LEDSpeed>0){
  180.     LEDPosition++;                                       // Illuminate the LED in the Next position
  181.     if (LEDSpeed>maxLEDSpeed){
  182.       LEDSpeed=maxLEDSpeed;                              // Ensure that the speed does not go beyond the maximum speed in the positive direction
  183.     }
  184.   }
  185.  
  186.   if (LEDSpeed<0){
  187.     LEDPosition--;                                       // Illuminate the LED in the Prior position
  188.     if (LEDSpeed<-maxLEDSpeed){
  189.       LEDSpeed = -maxLEDSpeed;                           // Ensure that the speed does not go beyond the maximum speed in the negative direction
  190.     }
  191.   }
  192. }
  193.  
  194.  
  195. //===================================================================================================================================================
  196. // constrainLEDs() : This ensures that the LED animation sequence remains within the boundaries of the various arrays (and the LED strip)
  197. //                   and it also creates a "bouncing" effect at both ends of the LED strip.
  198. //===================================================================================================================================================
  199. void constrainLEDs(){
  200.   LEDPosition = constrain(LEDPosition, 0, NUM_LEDS-1);    // Make sure that the LEDs stay within the boundaries of the LED strip
  201.   if(LEDPosition == 0 || LEDPosition == NUM_LEDS-1) {
  202.     LEDSpeed = (LEDSpeed * -0.9);                         // Reverse the direction of movement when LED gets to end of strip. This creates a bouncing ball effect.
  203.   }
  204. }
  205.  
  206.  
  207.  
  208. //===================================================================================================================================================
  209. // cylonWithHueControl() :  This is the 1st LED effect. The cylon colour is controlled by the potentiometer. The speed is constant.
  210. //===================================================================================================================================================
  211. void cylonWithHueControl(){
  212.       constSpeed = true;                                  // Make the LED animation speed constant
  213.       showLED(LEDPosition, potVal, 255, intensity);       // Illuminate the LED
  214.       fadeLEDs(8);                                        // Fade LEDs by a value of 8. Higher numbers will create a shorter tail.
  215.       setDelay(LEDSpeed);                                 // The LEDSpeed is constant, so the delay is constant
  216. }
  217.  
  218.  
  219. //===================================================================================================================================================
  220. // cylonWithBrightnessControl() : This is the 2nd LED effect. The cylon colour is red (hue=0), and the brightness is controlled by the potentiometer
  221. //===================================================================================================================================================
  222. void cylonWithBrightnessControl(){
  223.       constSpeed = true;                                  // Make speed constant
  224.       showLED(LEDPosition, 0, 255, potVal);               // Brightness is controlled by potentiometer.
  225.       fadeLEDs(16);                                       // Fade LEDs by a value of 16
  226.       setDelay(LEDSpeed);                                 // The LEDSpeed is constant, so the delay is constant
  227. }
  228.  
  229.  
  230. //===================================================================================================================================================
  231. // cometEffect() :  This is the 3rd LED effect. The random brightness of the trailing LEDs produces an interesting comet-like effect.
  232. //===================================================================================================================================================
  233. void cometEffect(){
  234.       constSpeed = false;                                  // The speed will be controlled by the slope of the accelerometer (y-Axis)
  235.       showLED(LEDPosition, potVal, 255, intensity);        // Hue will change with potentiometer.
  236.      
  237.       //The following lines create the comet effect
  238.       bright = random(50, 100);                            // Randomly select a brightness between 50 and 100
  239.       leds[LEDPosition] = CHSV((potVal+40),255, bright);   // The trailing LEDs will have a different hue to the leading LED, and will have a random brightness
  240.       fadeLEDs(8);                                         // This will affect the length of the Trailing LEDs
  241.       setDelay(LEDSpeed);                                  // The LEDSpeed will be affected by the slope of the Accelerometer's y-Axis
  242. }
  243.  
  244.  
  245. //===================================================================================================================================================
  246. // fireStarter() : This is the 4th LED effect. It starts off looking like a ball of fire, leaving a trail of little fires. But as you
  247. //                 turn the potentiometer, it becomes more like a shooting star with a rainbow-sparkle trail.
  248. //===================================================================================================================================================
  249. void fireStarter(){
  250.       constSpeed = false;                                  // The speed will be controlled by the slope of the accelerometer (y-Axis)
  251.       ledh[LEDPosition] = potVal;                          // Hue is controlled by potentiometer
  252.       showLED(LEDPosition, ledh[LEDPosition], 255, intensity);
  253.      
  254.       //The following lines create the fire starter effect
  255.       bright = random(50, 100);                            // Randomly select a brightness between 50 and 100
  256.       ledb[LEDPosition] = bright;                          // Assign this random brightness value to the trailing LEDs
  257.       sparkle(potVal/5);                                   // Call the sparkle routine to create that sparkling effect. The potentiometer controls the difference in hue from LED to LED.
  258.       fadeLEDs(1);                                         // A low number creates a longer tail
  259.       setDelay(LEDSpeed);                                  // The LEDSpeed will be affected by the slope of the Accelerometer's y-Axis
  260. }
  261.  
  262.  
  263. //===================================================================================================================================================
  264. // levelSense() : This is the 5th and final LED effect. The accelerometer is used in conjunction with the LED strip to create a digital "Spirit" Level.
  265. //                You can use the illuminated LEDs to identify the angle of the LED strip
  266. //===================================================================================================================================================
  267. void levelSense(){
  268.       constSpeed = true;
  269. //      LEDPosition = constrain(map(analogRead(yPin), 230, 640, 1, NUM_LEDS-1), 0 , NUM_LEDS-1);
  270.  
  271.  
  272. int Y_1 = readAcceleration(Axis_Y_Out1);  
  273. int Y_2 = readAcceleration(Axis_Y_Out2);
  274.                                  //  0, 255
  275. Serial.println(Y_2);
  276.   LEDPosition = constrain(map(Y_2, 200, 250 , 1, NUM_LEDS-1), 0 , NUM_LEDS-1);    
  277.  
  278.       //Jitter correction: this will reduce the amount of jitter caused by the accelerometer reading variability
  279.       if(abs(LEDPosition-oldPos) < 2){
  280.         LEDPosition = oldPos;
  281.       }
  282.      
  283.       //The following lines of code will ensure the colours remain within the red to green range, with green in the middle and red at the ends.
  284.       hue = map(LEDPosition, 0, NUM_LEDS-1, 0, 200);
  285.       if (hue>100){
  286.          hue = 200 - hue;
  287.       }
  288.      
  289.       //Illuminate 2 LEDs next to each other
  290.       showLED(LEDPosition, hue, 255, intensity);
  291.       showLED(LEDPosition-1, hue, 255, intensity);              
  292.      
  293.       //If the position moves, then fade the old LED positions by a factor of 25 (high numbers mean shorter tail)
  294.       fadeLEDs(25);                              
  295.       oldPos = LEDPosition;
  296. }
  297.  
  298.  
  299. //===================================================================================================================================================
  300. // fadeLEDs(): This function is used to fade the LEDs back to black (OFF)
  301. //===================================================================================================================================================
  302. void fadeLEDs(int fadeVal){
  303.   for (int i = 0; i<NUM_LEDS; i++){
  304.     leds[i].fadeToBlackBy( fadeVal );
  305.   }
  306. }
  307.  
  308.  
  309.  
  310. //===================================================================================================================================================
  311. // showLED() : is used to illuminate the LEDs
  312. //===================================================================================================================================================
  313. void showLED(int pos, byte LEDhue, byte LEDsat, byte LEDbright){
  314.   leds[pos] = CHSV(LEDhue,LEDsat,LEDbright);
  315.   FastLED.show();
  316. }
  317.  
  318.  
  319. //===================================================================================================================================================
  320. // setDelay() : is where the speed of the LED animation sequence is controlled. The speed of the animation is controlled by the LEDSpeed variable.
  321. //              and cannot go faster than the maxLEDSpeed variable.
  322. //===================================================================================================================================================
  323. void setDelay(int LSpeed){
  324.   animationDelay = maxLEDSpeed - abs(LSpeed);
  325.   delay(animationDelay);
  326. }
  327.  
  328.  
  329. //===================================================================================================================================================
  330. // sparkle() : is used by the fireStarter routine to create a sparkling/fire-like effect
  331. //             Each LED hue and brightness is monitored and modified using arrays  (ledh[]  and ledb[])
  332. //===================================================================================================================================================
  333. void sparkle(byte hDiff){
  334.   for(int i = 0; i < NUM_LEDS; i++) {
  335.     ledh[i] = ledh[i] + hDiff;                // hDiff controls the extent to which the hue changes along the trailing LEDs
  336.    
  337.     // This will prevent "negative" brightness.
  338.     if(ledb[i]<3){
  339.       ledb[i]=0;
  340.     }
  341.    
  342.     // The probability of "re-igniting" an LED will decrease as you move along the tail
  343.     // Once the brightness reaches zero, it cannot be re-ignited unless the leading LED passes over it again.
  344.     if(ledb[i]>0){
  345.       ledb[i]=ledb[i]-2;
  346.       sparkTest = random(0,bright);
  347.       if(sparkTest>(bright-(ledb[i]/1.1))){
  348.         ledb[i] = bright;
  349.       } else {
  350.         ledb[i] = ledb[i] / 2;                  
  351.       }
  352.     }
  353.     leds[i] = CHSV(ledh[i],255,ledb[i]);
  354.   }
  355. }
  356. //------------------------------------------------------------------------------------------------------
  357. byte readAcceleration(byte address)
  358. {
  359.   byte val = 0x00;
  360.   Wire.beginTransmission(AccelerometerAddress);
  361.   Wire.write(address);
  362.   Wire.endTransmission();
  363.   Wire.requestFrom(AccelerometerAddress, 1);
  364.   val = Wire.read();
  365.   return val;
  366. }
  367.  
  368. /*
  369. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  370. Accelerometer sketch BMA020
  371. /*
  372. http://meineweltinmeinemkopf.blogspot.de/2012/06/beschleunigungssensor-auslesen-mit_3.html
  373. */
  374.  
  375. /*
  376. #include <Wire.h>
  377. #define AccelerometerAddress 0x38
  378. #define Axis_X_Out1 0x02
  379. #define Axis_X_Out2 0x03
  380. #define Axis_Y_Out1 0x04
  381. #define Axis_Y_Out2 0x05
  382. #define Axis_Z_Out1 0x06
  383. #define Axis_Z_Out2 0x07
  384. void setup()
  385. {
  386.   Wire.begin();
  387.   Serial.begin(9600);
  388. }
  389. void loop()
  390. {
  391.   Serial.println();
  392.  
  393.   Serial.print("X1:");
  394.   Serial.print(readAcceleration(Axis_X_Out1), DEC);
  395.   Serial.print("\t");
  396.   Serial.print("SX2:");
  397.   Serial.print("\t");
  398.   Serial.print(readAcceleration(Axis_X_Out2), DEC);
  399.   Serial.print("\t");
  400.   Serial.print("@Y1:");
  401.   Serial.print("\t");
  402.   Serial.print(readAcceleration(Axis_Y_Out1), DEC);
  403.   Serial.print("\t");
  404.   Serial.print("SY2:");
  405.   Serial.print("\t");
  406.   Serial.print(readAcceleration(Axis_Y_Out2), DEC);
  407.   Serial.print("\t");
  408.   Serial.print("@Z1:");
  409.   Serial.print("\t");
  410.   Serial.print(readAcceleration(Axis_Z_Out1), DEC);
  411.   Serial.print("\t");
  412.   Serial.print("SZ2:");
  413.   Serial.print("\t");
  414.   Serial.println(readAcceleration(Axis_Z_Out2), DEC);
  415.  
  416.   delay(50);
  417. }
  418. byte readAcceleration(byte address)
  419. {
  420.   byte val = 0x00;
  421.   Wire.beginTransmission(AccelerometerAddress);
  422.   Wire.write(address);
  423.   Wire.endTransmission();
  424.   Wire.requestFrom(AccelerometerAddress, 1);
  425.   val = Wire.read();
  426.   return val;
  427. }
  428. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement