Jonathan León, FabAcademy 2021.
About me Assignments Final project

How to make (almost) anything.

Embedded programming

The code includes three cases: fade, steady light, and off. It performs its function for 20 minutes and then goes into sleep mode to save energy (assuming that the user is already asleep by that time).

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