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 |