Once the Arduino IDE is set up we will want to upload the following code to the board.
Aside from the color LED animation, pulsing the NeoPixels from light to dark and back, the code is looking for a button press and readings from the Accelerometer.
First we look to see if the Right side button is pressed. If so, we add 1 to the ledState variable. This is then passed through a Switch statement that changes the R,G, and B values for the NeoPixel animation and captures the current ColorState. Since there are only 3 colors, when we get to the 4th switch option, ledState is just set to 0 again so that the colors cycle in a loop for button presses.
switch (ledState) {
case 0: // Red Team
R = 255;
G = 0;
B = 0;
ColorState=0;
break;
case 1: // Yellow Team
R = 255;
G = 255;
B = 0;
ColorState=1;
break;
case 2: // Blue Team
R = 0;
G = 0;
B = 255;
ColorState=2;
break;
case 3: // Return to Red Team
ledState = 0;
break;
Next we look for movement using the Accelerometer. There will always be an acceleration reading on the accelerometer because gravity is an acceleration force that will constantly act on the sensor at 9.807 m/s2 in the direction of the ground. So standing still, we should have a net reading from the censor of about 9 to 10. Anything above that would indicate movement and that is what we want to look for. After a bit of testing, we found that a reading of 19 m/s2 was a good indication that someone is walking or running.
The Accelerometer measures acceleration along the X, Y, and Z axis. We need to get a reading on all of the axes at once to look at the net acceleration force exerted on the sensor. We do that by simply adding the X, Y, and Z sensor readings together.
Sensor = abs(CircuitPlayground.motionX())+abs(CircuitPlayground.motionY())+abs(CircuitPlayground.motionZ());
In theory, no matter what orientation we hold the Circuit Playground in, we will get a net value of ~10 m/s2. There is a bit of variation in the actual reading we get, but it is close.
In conclusion, if the net value of the Accelerometer reading is more that 19 m/s2, we assume that the person is walking. Then we set the ledState variable to 4. In the switch statement the number 4 option tells the NeoPixels to alternate blinking bright white and a dimer version of the team color.
case 4: // Walking detected
ColorFill(255, 255, 255);
delay(300);
ColorFill(R/20, G/20, B/20);
delay(300);
ledState=ColorState;
break;
The rest of the code controls the LED animations. Since we want to read the sensors as often as possible, the animations are done a bit more complex than most would be used to. There is a really good article that goes into detail about multitasking NeoPixel animations.
#include <Adafruit_CircuitPlayground.h> // Variables will change: int ledState = 0; // the current state of the output pin int buttonState; // the current reading from the input pin int lastButtonState = LOW; // the previous reading from the input pin int ColorState; // the previous Color set int R = 0; int G = 255; int B = 0; int Roffset; int Goffset; int Boffset; int FadeDir = 1; int FadeTurn =0; int FadeRate = 50; // the following variables are long's because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long lastDebounceTime = 0; // the last time the output pin was toggled long debounceDelay = 50; // the debounce time; increase if the output flickers int Sensor; void setup() { CircuitPlayground.begin(); CircuitPlayground.setBrightness(155); } void loop() { //CircuitPlayground.lightSensor() // read the state of the button into a local variable: int reading = CircuitPlayground.rightButton(); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != lastButtonState) { // reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: // if the button state has changed: if (reading != buttonState) { buttonState = reading; // only toggle the LED if the new button state is HIGH if (buttonState == HIGH) { ++ledState; FadeTurn = 0; } } } Sensor = abs(CircuitPlayground.motionX())+abs(CircuitPlayground.motionY())+abs(CircuitPlayground.motionZ()); if(Sensor>19)ledState=4; // set the LED: // do something different depending on the // range value: switch (ledState) { case 0: // Red Team R = 255; G = 0; B = 0; ColorState=0; break; case 1: // Yellow Team R = 255; G = 255; B = 0; ColorState=1; break; case 2: // Blue Team R = 0; G = 0; B = 255; ColorState=2; break; case 3: // Return to Red Team ledState = 0; break; case 4: // Walking detected ColorFill(255, 255, 255); delay(300); ColorFill(R/20, G/20, B/20); delay(300); ledState=ColorState; break; } delay(1); // delay in between reads for stability Roffset=R/FadeRate; Goffset=G/FadeRate; Boffset=B/FadeRate; if (FadeDir){ FadeTurn++; ColorFill(R-(Roffset*FadeTurn), G-(Goffset*FadeTurn), B-(Boffset*FadeTurn)); if(FadeTurn>FadeRate){ FadeDir = 0; //FadeTurn = 0; } } else{ FadeTurn--; ColorFill(R-(Roffset*FadeTurn), G-(Goffset*FadeTurn), B-(Boffset*FadeTurn)); if(FadeTurn<1){ FadeDir = 1; //FadeTurn = 0; } } // save the reading. Next time through the loop, // it'll be the lastButtonState: lastButtonState = reading; } void ColorFill(uint16_t r,uint16_t g,uint16_t b){ for(uint16_t i=0; i<10; i++) { CircuitPlayground.setPixelColor(i, r, g, b); } }
Page last edited July 17, 2016
Text editor powered by tinymce.