I have a project where I am using a steering wheel that triggers a hall effect sensor as it rotates. The idea is that as you rotate the wheel, LEDs will chase up the strand. If you stop rotating, or go to slow, the LEDs will begin to extinguish. It randomly picks a color each time it goes through the cycle to chase up the strip. I would like to incorporate a "show" of sorts like a rainbow effect on the strip if the wheel has not been turned in say 1 minute or so. Then, if the wheel is turned again, the rainbow effect will extinguish, clearing the strip, and the LEDs will again chase up the strip as the wheel is turned. This is where I am stumped. I can't clear the rainbow to begin chasing the LEDS again.
This is my first attempt at using an interrupt and I honestly don't know if I am going about this the right way with what I have done so far. The attached code works as I have described above with the exception of the rainbow "show". I know that it does not work as written. The LEDs chase up and down the strip as they should and the code works fine without the rainbow part added in. I threw in the rainbow function in the loop of the attached code so it's execution can be seen because I feel that this is part of the problem (it seems to be all about the timing). I have tried it many different ways, too many to describe in detail. I would greatly appreciate any guidance I can get in regards to getting this to work.
Do I need to start over and rewrite what the interrupt is doing? Would it be better to poll the sensor and try and get it to work that way?
This is my first attempt at using an interrupt and I honestly don't know if I am going about this the right way with what I have done so far. The attached code works as I have described above with the exception of the rainbow "show". I know that it does not work as written. The LEDs chase up and down the strip as they should and the code works fine without the rainbow part added in. I threw in the rainbow function in the loop of the attached code so it's execution can be seen because I feel that this is part of the problem (it seems to be all about the timing). I have tried it many different ways, too many to describe in detail. I would greatly appreciate any guidance I can get in regards to getting this to work.
Do I need to start over and rewrite what the interrupt is doing? Would it be better to poll the sensor and try and get it to work that way?
Code:
const int hallPin = 8; // the number of the hall effect sensor pin
#include <Adafruit_NeoPixel.h> // Neopixel Library
#define Strip 11 // LED strip on pin 11
Adafruit_NeoPixel strip = Adafruit_NeoPixel(93, Strip, NEO_GRB + NEO_KHZ800);
uint32_t color = strip.Color(0,0,0);
uint32_t Red = strip.Color(0,255, 0);
uint32_t Green = strip.Color(255,0, 0);
uint32_t ColorOff = strip.Color(0, 0, 0);
uint32_t White = strip.Color(255,255,255);
uint32_t Yellow = strip.Color(255,255, 0);
uint32_t Blue = strip.Color(0, 0, 255);
uint32_t Pink = strip.Color(51, 255, 255);
uint32_t LtBlue = strip.Color(76, 0, 153);
int j = 0;
long randomNumber;
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period =170; //time between rotations before LEDs start turning off
void setup() {
randomSeed(analogRead(A1));
startMillis = millis(); //initial start time
strip.begin(); //enable LEDS
strip.show(); //turn all LEDs off
// initialize the hall effect sensor pin as an input:
pinMode(hallPin, INPUT);
attachInterrupt(digitalPinToInterrupt(hallPin), toggle, CHANGE);
}
void loop(){
currentMillis = millis(); //
if (currentMillis - startMillis >= period){ //test whether the period has elapsed {
// turn LED off:
if ((j<93) && (j >-1)) {
strip.setPixelColor(j,ColorOff);
strip.show();// turns LED #j off
j=j-1;
}
startMillis = currentMillis;
}
rainbow(30); //XXX this is where my problem lies XXXX how to incorporate this so that after a period of time if the hall effect is not triggered,
// this rainbow show will display but once the hall effect is triggered again, the LED strip extinguishes and the hall effect controls the LEDS
//chasing up the strip
}
void toggle() {
randomNumber = random(1,8);
if (j <= 0) {
switch (randomNumber) {// picks random color for chasing LEDs
case 1:
color = White;
break;
case 2:
color = Red;
break;
case 3:
color = Green;
break;
case 4:
color = Yellow;
break;
case 5:
color = Blue;
break;
case 6:
color = LtBlue;
break;
case 7:
color = Pink;
break;
}
}
// turn LEDs on one at a time as wheel is turned
if (j < 92) {
strip.setPixelColor(j, color); // Sets the LED #j to color
strip.show(); //lights the LED #j to color
j=j+1; //increments j to the next LED in line
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void colorWipe(uint32_t c) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
}
}