RGB Lightshow using a Neopixel (WS2812) LED strip and the LIS3SH accelerometer. Used for my scooter at 35C3.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Neopixel_LIS3DH.ino 5.2KB

  1. /*
  2. * Blinky, Colorful Neopixel (WS2812) LED Stip Controlled by Motion Sensor (LIS3DH)
  3. *
  4. * copyright: Jannik Beyerstedt | https://jannikbeyerstedt.de | code@jannikbeyerstedt.de
  5. * license: http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 License
  6. */
  7. #include <Wire.h>
  8. #include <Adafruit_LIS3DH.h>
  9. #include <Adafruit_Sensor.h>
  10. const uint32_t accel_interval = 50;
  11. #include <Adafruit_NeoPixel.h>
  12. #define PIXEL_PIN 6 // Digital IO pin connected to the NeoPixels.
  13. #define PIXEL_COUNT 16
  14. const uint32_t neopx_defaultInt = 100;
  15. // I2C: SCL A4, SDA A5, SDO float or GND: 0x18
  16. Adafruit_LIS3DH lis = Adafruit_LIS3DH();
  17. const int accel_thldNoiseX = 500; // below this is no movement
  18. const int accel_thldNoiseY = 500;
  19. const int accel_thldNoiseZ = 9000;
  20. const int accel_thldMaxX = 5000; // light effects should scale until this point
  21. const int accel_thldMaxY = 5000;
  22. const int accel_thldMaxZ = 15000;
  23. // Neopixel ring: NEO_RGB or NEO_GRB + NEO_KHZ400 or NEO_KHZ800
  24. Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ400);
  25. uint32_t neopx_loopCnt = 0;
  26. // some global variables
  27. uint32_t accel_lastWake = 0;
  28. uint32_t neopx_lastWake = 0;
  29. uint32_t neopx_interval = 50;
  30. uint32_t debug_lastWake = 0;
  31. const uint32_t debug_interval = 200;
  32. const int accel_rangeX = accel_thldMaxX - accel_thldNoiseX;
  33. const int accel_rangeY = accel_thldMaxY - accel_thldNoiseY;
  34. const int accel_rangeZ = accel_thldMaxZ - accel_thldNoiseZ;
  35. void setup() {
  36. Serial.begin(115200);
  37. Serial.println("Neopixel Animation with LIS3DH Motion Sensor\n");
  38. if (!lis.begin(0x18)) { // change this to 0x19 for alternative i2c address
  39. Serial.println("Couldnt start");
  40. while (1)
  41. ;
  42. }
  43. lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
  44. strip.begin();
  45. strip.show(); // Initialize all pixels to 'off'
  46. pinMode(LED_BUILTIN, OUTPUT);
  47. }
  48. void loop() {
  49. uint32_t currentTime_millis = millis();
  50. // READ SENSOR
  51. if (currentTime_millis - accel_lastWake >= accel_interval) {
  52. accel_lastWake = currentTime_millis;
  53. lis.read();
  54. int32_t diffX = abs(lis.x) - accel_thldNoiseX;
  55. if (diffX > accel_rangeX) {
  56. diffX = accel_rangeX;
  57. }
  58. int32_t diffY = abs(lis.y) - accel_thldNoiseY;
  59. if (diffY > accel_rangeY) {
  60. diffY = accel_rangeY;
  61. }
  62. int32_t diffZ = abs(lis.z) - accel_thldNoiseZ;
  63. if (diffZ > accel_rangeZ) {
  64. diffZ = accel_rangeZ;
  65. }
  66. neopx_interval = neopx_defaultInt;
  67. if (diffX > 0) {
  68. int32_t fasterInt = neopx_defaultInt - (diffX * (neopx_defaultInt - 5) / accel_rangeX);
  69. if (neopx_interval > fasterInt) {
  70. neopx_interval = fasterInt;
  71. }
  72. } else if (diffY > 0) {
  73. uint32_t fasterInt = neopx_defaultInt - (diffY * (neopx_defaultInt - 5) / accel_rangeY);
  74. if (neopx_interval > fasterInt) {
  75. neopx_interval = fasterInt;
  76. }
  77. } else if (diffZ > 0) {
  78. uint32_t fasterInt = neopx_defaultInt - (diffZ * (neopx_defaultInt - 5) / accel_rangeZ);
  79. if (neopx_interval > fasterInt) {
  80. neopx_interval = fasterInt;
  81. }
  82. }
  83. }
  84. // DO LIGHTSHOW
  85. if (currentTime_millis - neopx_lastWake >= neopx_interval) {
  86. neopx_lastWake = currentTime_millis;
  87. neopx_loopCnt++;
  88. // rainbow
  89. for (uint16_t i = 0; i < strip.numPixels(); i++) {
  90. strip.setPixelColor(i, Wheel((i + neopx_loopCnt) & 255));
  91. }
  92. strip.show();
  93. }
  94. // DEBUG OUTPUT
  95. if (currentTime_millis - debug_lastWake >= debug_interval) {
  96. debug_lastWake = currentTime_millis;
  97. Serial.print("X: ");
  98. Serial.print(lis.x);
  99. Serial.print(" \tY: ");
  100. Serial.print(lis.y);
  101. Serial.print(" \tZ: ");
  102. Serial.print(lis.z);
  103. Serial.println();
  104. }
  105. }
  106. void rainbow(uint8_t wait) {
  107. uint16_t i, j;
  108. for (j = 0; j < 256; j++) {
  109. for (i = 0; i < strip.numPixels(); i++) {
  110. strip.setPixelColor(i, Wheel((i + j) & 255));
  111. }
  112. strip.show();
  113. delay(wait);
  114. }
  115. }
  116. // Slightly different, this makes the rainbow equally distributed throughout
  117. void rainbowCycle(uint8_t wait) {
  118. uint16_t i, j;
  119. for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
  120. for (i = 0; i < strip.numPixels(); i++) {
  121. strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
  122. }
  123. strip.show();
  124. delay(wait);
  125. }
  126. }
  127. //Theatre-style crawling lights with rainbow effect
  128. void theaterChaseRainbow(uint8_t wait) {
  129. for (int j = 0; j < 256; j++) { // cycle all 256 colors in the wheel
  130. for (int q = 0; q < 3; q++) {
  131. for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
  132. strip.setPixelColor(i + q, Wheel((i + j) % 255)); //turn every third pixel on
  133. }
  134. strip.show();
  135. delay(wait);
  136. for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
  137. strip.setPixelColor(i + q, 0); //turn every third pixel off
  138. }
  139. }
  140. }
  141. }
  142. // Input a value 0 to 255 to get a color value.
  143. // The colours are a transition r - g - b - back to r.
  144. uint32_t Wheel(byte WheelPos) {
  145. WheelPos = 255 - WheelPos;
  146. if (WheelPos < 85) {
  147. return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  148. }
  149. if (WheelPos < 170) {
  150. WheelPos -= 85;
  151. return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  152. }
  153. WheelPos -= 170;
  154. return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  155. }