3

I'm having some trouble wrapping my head around timers in Arduino. I've got a FSR Pressure Sensor and I want it to turn on my NeoPixel LED after pressing on it for 5 seconds. Any help is much appreciated!

My goal: FSRReading > 1022 then wait 5 seconds, turn on NeoPixel FSRReading < 1022, then reset timer, turn off NeoPixel

This is what I currently have for my code, I can detect and act on sensor readings, but no timer:

#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NUMPIXELS 16
#include "Timer.h"


Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int fsrPin = 9; // FSR is connected to analog 0
int fsrReading; // the analog reading from the FSR resistor divider int LEDbrightness;
int LEDbrightness;
Timer t;


void setup(void) {
 Serial.begin(9600);
 pixels.begin();
}

void loop(void) {
fsrReading = analogRead(fsrPin); 
Serial.println(fsrReading);
Serial.print("Analog reading = "); 

// we'll need to change the range from the analog reading (0-1023) down to the range // used by analogWrite (0-255) with map!
LEDbrightness = map(fsrReading, 0, 1023, 0, 255);

if (fsrReading < 10) {
Serial.println(" - No pressure"); } else if (fsrReading < 200) {
Serial.println(" - Light touch"); } else if (fsrReading < 500) {
Serial.println(" - Light squeeze"); } else if (fsrReading < 800) {
Serial.println(" - Medium squeeze"); } else {
Serial.println(" - Big squeeze"); }
delay(50);

for(int i=0;i<NUMPIXELS;i++){

  // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
  if (fsrReading>1022){
  pixels.setPixelColor(i, pixels.Color(0,255,0)); 
  } else if (fsrReading<1022) {
  pixels.setPixelColor(i, pixels.Color(0,0,0));
  }

  pixels.show(); // This sends the updated pixel color to the hardware.
 }
 }
jmswng
  • 33
  • 3

2 Answers2

3

The basic concept for tracking timing in the loop() is as follows:

1) when your event occurs, you store the current time in a variable:

unsigned long lastReading = 0;
uint8_t waiting = false;

if ( !waiting && fsrReading > 1022 ) {
  lastReading = millis();
  waiting = true;
}

2) you compare the lastReading variable against the current time and when enough time has passed, you can perform you timed action. ie:

int timeToWait = 5000; // 5 seconds

// are we waiting? and has enough time passed?
if ( waiting && millis() - lastReading > timeToWait ) {
   waiting = false; // reset

   // Light up lights
   ...
}

Note: this specific implementation only requires the sensor to rise above 1022 once, then wait 5 seconds before executing the timed action. If you want the sensor reading to be maintained above 1022 for the entire duration then you would add a check for a release with something like:

if ( fsrReading < 1022 ) {
  waiting = false; // reset because reading fell below 1022
}
Mazaryk
  • 1,149
  • 6
  • 16
1

My goal: FSRReading > 1022 then wait 5 seconds, turn on NeoPixel FSRReading < 1022, then reset timer, turn off NeoPixel

something like this will do.

  static uint32_t pressed_time; //last time the pressure sensor is pressed
  static uint8_t pressed_state=0; //the previous state. '1'->pressed, '0'->not pressed

  if (pressed()) {
    if (!pressed_state)) { //first time the pressure sensor is pressed
      pressed_state = 1;  //pressure sensor has been pressed
      pressed_time = millis(); //take time now
    } 
  } else {                //no longer pressed
    pressed_state = 0;  //reset pressed state
    turnOffled();       //turn the led off
  }

  if ((millis() > pressed_time + LED_DLY) && pressed_state) turnOnled();

untested code, use at your own risk

edit:

the above code in action, with a minor modification to return the desired led state (active high):

    //turn on / off the led pins
    if (led_ctrl()) digitalWrite(LED_PIN, HIGH);    //turn on the led, active high
    else digitalWrite(LED_PIN, LOW);        //turn off the led
}

enter image description here

Note: 1. pressed() is active low; 2. the led is programmed to turn on 100ms after the button goes low.

hope it helps.

dannyf
  • 2,813
  • 11
  • 13