This makes use of the CapacitiveSensor.h and Adafruit_NeoPixel.h libraries. The program starts with all the LEDs off, activates the serial monitor to continuously print the values on the capacitive sensor reading: if the value is greater than 1K (a direct touch on the copper) it switches to Stage 1, otherwise it does nothing . When a Stage change is detected, it also changes from Old State to New State, which triggers the following changes: the value of the Show Type is increased (if the value exceeds the number of available shows, it returns to 0 to restart the cycle), and resets the fade and program execution time values. The available shows are specified as cases: the first case assigns values of 0 to the LEDs so they turn off, the second case starts a fade sequence from black to blue and back, the third case assigns all RGB values to 255 so the LEDs glow white at full power. The fade is calculated by subtracting the initial RGB values from the final RGB values and dividing by the assigned number of steps (and the opposite way back). If the execution time reaches 20 minutes, it goes into sleep state (it sets the RGB values of the LEDs to 0,0,0, so it turns them off if they are already on because they were in case 1 or 2) .
/* Breathonome
* Cycle NeoPixels with capacitive sensor, includes sleep function.
* ATmega328P
* Jonathan León
* 2022-13-06
* Thanks to surveyranger, Paul Stoffregen and Konstantin Dimitrov for their sample codes that made this release possible.
*
* A copper plate acting as a capacitive sensor is connected to a 1 megohm resistor between
* pins 7 and 8 cycles through different modes (cases). Mode stops and switches to the
* next mode when the sensor detects a touch. Current mode plays until button is pressed or
* goes into sleep mode after 20 minutes.
* Capacitive sensor is connected to the resistor leg on pin 8.
* NeoPixel data in connected in series with a 330 ohm resistor to pin 14.
*/
#include <CapacitiveSensor.h>
#include <Adafruit_NeoPixel.h>
#define PIXEL_PIN 14 // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 5
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
CapacitiveSensor cs_7_8 = CapacitiveSensor(7,8); // 1M resistor between pins 7 & 8, pin 8 is sensor pin, add a wire and or foil
unsigned long idleMillis; // Measure idle time between button presses
unsigned long patternInterval = 20 ; // time between steps in the pattern
unsigned long lastUpdate = 0; // for millis() when last update occurred
unsigned long showSpeed [] = { 600, 600, 600 } ; // speed for each pattern - add here when adding more cases ****************************
int fadeStep = 0; // state variable for fade function
//const byte BUTTON_PIN = 6; // Pin 6 / PCINT0 / externalInterrupt / Replaced by capacitive sensor
void setup()
{
cs_7_8.set_CS_AutocaL_Millis(0xFFFFFFFF);// Turn off autocalibrate on channel 1
Serial.begin(9600);
//pinMode(13,OUTPUT); // LED debugging, replaced by Neopixels
pinMode(PIXEL_PIN, OUTPUT);
//pinMode(BUTTON_PIN, INPUT); //Button, replaced by sensor
//digitalWrite(BUTTON_PIN, HIGH); // Activate pull-up resistor to set pin HIGH
strip.begin();
strip.show(); // Initialize all pixels to 'off'
wipe(); // Clear buffers on pixels
idleMillis = millis(); // Start idle time
}
void loop()
{
short stage = 0;
long sensor1 = cs_7_8.capacitiveSensor(50);
Serial.println(sensor1); // Print sensor output
if(sensor1 >= 1000)
{
stage = 1;
}
else{
stage = 0;
} //Detects real changes when pressing the sensor
static byte idleTime = 20; // Sets idle time (in minutes) before sleep mode //**SUPER IMPORTANT
if (millis() - idleMillis >= (1000UL*60*idleTime)) // 1000(unsigned long)ms * 60(sec/min) * # minutes
{
strip.clear();
colorWipe(strip.Color( 0, 0, 0), 50);
}
// Start with case 0
static byte showType = 0;
static bool oldState;
// Get current button state
bool newState = stage;
// Check if state changed from high to low (button or sensor press)
if (newState == 1 && oldState == 0)
{
showType++; // Move to next showType
fadeStep = 0; // Reset fade state variable
idleMillis = millis(); // Reset idle timer
if (showType > 2) // If showType exceeds number of shows
{
showType = 0; // Reset showType to case 0
}
patternInterval = showSpeed[showType]; // Set speed for this pattern
//colorWipe(strip.Color( 0, 0, 0), 50); // Clear out pixel buffer
delay(20); // Debounce delay
}
oldState = newState; // Update state
if (millis() - lastUpdate > patternInterval)
{
startShow(showType);
}
}
void startShow(int showPattern)
{
switch(showPattern)
{
case 0: colorWipe(strip.Color( 0, 0, 0), 50); // Black/off
break;
case 1: fade(0, 1, 0, 255, 0, 255, 600); // Fade from black to blue and back
break;
case 2: colorWipe(strip.Color( 255, 255, 255), 50); // White
break;
}
}
// clear all LEDs
void wipe()
{
for(byte i=0;i<strip.numPixels();i++)
{
strip.setPixelColor(i, strip.Color(0,0,0));
strip.show();
}
}
// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
// delay(wait); // Pause for a moment
}
// time for next change to the display
lastUpdate = millis();
}
void fade(byte redStartValue, byte redEndValue, byte greenStartValue, byte greenEndValue, byte blueStartValue, byte blueEndValue, int totalSteps)
{
static float redIncrement, greenIncrement, blueIncrement;
static float red, green, blue;
static bool fadeUp = false;
if (fadeStep == 0) // First step is to initialise the initial colour and increments
{
red = redStartValue;
green = greenStartValue;
blue = blueStartValue;
fadeUp = false;
redIncrement = (float)(redEndValue - redStartValue) / (float)totalSteps;
greenIncrement = (float)(greenEndValue - greenStartValue) / (float)totalSteps;
blueIncrement = (float)(blueEndValue - blueStartValue) / (float)totalSteps;
fadeStep = 1; // next time the function is called start the fade
}
else // All other steps make a new colour and display it
{
// make new colour
red += redIncrement;
green += greenIncrement;
blue += blueIncrement;
// set up the pixel buffer
for (byte i = 0; i > strip.numPixels(); i++)
{
strip.setPixelColor(i, strip.Color((byte)red,(byte)green,(byte)blue));
}
// now display it
// strip.setBrightness(50); // Dim output to reduce consumption
strip.show();
// go on to next step
fadeStep += 1;
// finished fade
if(fadeStep >= totalSteps)
{
if(fadeUp) // Finished fade up and back
{
fadeStep = 0;
return; // So next call recalabrates the increments
}
// now fade back
fadeUp = true;
redIncrement = -redIncrement;
greenIncrement = -greenIncrement;
blueIncrement = -blueIncrement;
fadeStep = 1; // Don't calculate the increments again but start at first change
}
}
}
|
Downloads |