// ************************************************************************************************
//
// Documentation for this, and the rest of the LC libraies that make this up.
// Here's the book : https://github.com/leftCoast/LC_libraryDocs/blob/main/LC_libraries.pdf
// Search for : neoPixel, mapper, autoPOT, timeObj, squareWave
//
// That should keep you busy.
//
// ************************************************************************************************
#include <neoPixel.h>
#include <mapper.h>
#include <autoPOT.h>
#include <timeObj.h>
#include <squareWave.h>
#define GOOD_LIMIT 50 // Up to this, we'll call it good air
#define BAD_LIMIT 80 // At this? your hosed!
neoPixel theRing(12,2); // Your standard neopixle ring.
autoPOT thePOT(A0); // Class that manages the analog input.
mapper POTMapper(0,1023,0,100); // A mapper from analog to percentage.
colorMultiMap theColorMapper; // A mapper from precentage to color.
timeObj blinkTimer(5000,false); // Times how long to blink for.
squareWave blinkWave(500,250); // Times how fast to blink.
float savedPercent; // The last reading we saw.
bool savedState; // The last on/off blink state we set.
void setup() {
float yellowLimit; // We'll calculate the midpoint between good & bad.
float goodBadDelta;
float halfDelta;
theRing.begin(); // Fire up the ring.
theRing.setAll(&black); // Turn off the LEDs.
theRing.show(); // Show the world.
thePOT.setCallback(gotChange); // When the ananlog value changes, call this funtion.
theColorMapper.addColor(0,&green); // Build the percent to color map. Start with green..
theColorMapper.addColor(GOOD_LIMIT,&green); // (X,color) pairs.
goodBadDelta = BAD_LIMIT-GOOD_LIMIT; // Calcualte where we want yellow..
halfDelta = goodBadDelta/2; // ..half way..
yellowLimit = GOOD_LIMIT + halfDelta; // Yellow should go in the middle between good and bad.
theColorMapper.addColor(yellowLimit,&yellow); // Plunk it in there.
theColorMapper.addColor(BAD_LIMIT,&red); // We're all red now.
theColorMapper.addColor(100,&red); // Finish off with red..
savedPercent = 0; // We assume we got good air at the start.
}
// Percentage of bad air has changed! Deal with it.
void gotChange(int newReading) {
float percentBad;
colorObj ringColor;
percentBad = POTMapper.map(newReading); // Read analog, map to percent.
ringColor = theColorMapper.map(percentBad); // Map perecent to a color.
theRing.setAll(&ringColor); // Set the ring to that color.
theRing.show(); // Show the world.
if (percentBad>BAD_LIMIT && savedPercent<BAD_LIMIT) { // If the last percent was ok and this is bad?
savedState = true; // We're showing the color.
blinkTimer.start(); // Start the blink timer.
blinkWave.setOnOff(true); // Fire up our blink square wave.
} else if (savedPercent>BAD_LIMIT && percentBad<BAD_LIMIT) { // Else if we gone from bad to ok?
blinkTimer.reset(); // We shut down the timer.
blinkWave.setOnOff(false); // Shut down the square wave machine.
} //
savedPercent = percentBad; // Not the last value for next time around.
}
// Let's check the blinking status..
void checkBlink(void) {
bool currentState;
if (blinkWave.running()) { // If we are currently blinking..
if (blinkTimer.ding()) { // If we need to stop this blinking..
blinkTimer.reset(); // We shut down the timer.
blinkWave.setOnOff(false); // Shut down the square wave machine.
theRing.setAll(&red); // Set the color to red.
theRing.show(); // Show the change.
} else { // Else, we need to keep blinking..
currentState = blinkWave.pulseHiLow(); // Save current state of the square wave.
if (savedState!=currentState) { // If there's a change of state..
if (currentState) { // If the state is true..
theRing.setAll(&red); // We give them a red.
} else { // Else.. The state is false.
theRing.setAll(&black); // We give them black (All off);
} //
theRing.show(); // Show the change.
savedState = currentState; // Save the state.
} //
} //
} //
}
// And loop..
void loop() {
idle(); // Runs all the magic behind the scenes.
checkBlink(); // See if we need to up update the blinking stuff.
}
CO2 level 0..100