1

I have a sketch that contains code for an analog input (FSR sensor), a pushbutton, and 6 blinking LEDs.

Currently, the sketch is written to allow the LEDs to blink only when the button is pressed and there is sensor input.

Can someone help me write code to make the LEDs blink for a certain period of time once there is input from the analog sensor and while the button is pressed? I am trying to make the LED blink for 15 seconds and then turnoff.

thank you!

/*
 6 Flashing LED Lights With A Pushbutton and FSR Sensor
*/

const int buttonPin = 8;
const int LedPin1 = 7;
const int LedPin2 = 6;
const int LedPin3 = 5;
const int LedPin4 = 4;
const int LedPin5 = 3;
const int LedPin6 = 2;


int buttonState = 0;
int SensorPin = A0;
int SensorPinReading;


void setup() {
  Serial.begin(9600);
  pinMode(LedPin1, OUTPUT);
  pinMode(LedPin2, OUTPUT);
  pinMode(LedPin3, OUTPUT);
  pinMode(LedPin4, OUTPUT);
  pinMode(LedPin5, OUTPUT);
  pinMode(LedPin6, OUTPUT);
  pinMode(buttonPin,INPUT);
  pinMode(SensorPin, INPUT);
}


void loop() {
  SensorPinReading = analogRead(SensorPin);
  Serial.print("Analog reading = ");
  Serial.print(SensorPinReading);

if (SensorPinReading < 10) {
  Serial.println(" - No Pressure");
} else if (SensorPinReading < 200) {
  Serial.println(" - Light Touch");
} else if (SensorPinReading < 500) {
  Serial.println(" - Light Squeeze");
} else if (SensorPinReading < 800) {
  Serial.println(" - Medium Squeeze");
} else {
  Serial.println(" - Big Squeeze");
}


  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH && SensorPinReading > 10)  {
  digitalWrite(LedPin1, HIGH);
  digitalWrite(LedPin2, HIGH);
  digitalWrite(LedPin3, HIGH);
  digitalWrite(LedPin4, HIGH);
  digitalWrite(LedPin5, HIGH);
  digitalWrite(LedPin6, HIGH);     
  delay(600);                      
  digitalWrite(LedPin1, LOW);
  digitalWrite(LedPin2, LOW);
  digitalWrite(LedPin3, LOW);
  digitalWrite(LedPin4, LOW);
  digitalWrite(LedPin5, LOW);
  digitalWrite(LedPin6, LOW);       
  delay(200);                       
  }
  else {
    digitalWrite(LedPin1, LOW);
    digitalWrite(LedPin2, LOW);
    digitalWrite(LedPin3, LOW);
    digitalWrite(LedPin4, LOW);
    digitalWrite(LedPin5, LOW);
    digitalWrite(LedPin6, LOW);
  }

}
  • Please edit your question (click "edit") and mark the code as code. In the editing box, highlight the code and press ctrl-k. Or highlight the code and click the {} icon in the toolbar at the top of the editing box. To highlight text click-drag across it or use the arrow keys while holding the shift key. – James Waldby - jwpat7 Apr 20 '17 at 0:11
0

The code shown below is to “make the LEDs blink like the previous sketch during the 15 seconds”. The previous sketch (that is, the code in the question) turns the LEDs on for 600 ms and off for 200. The code below reverses the order – that is, does off for 200 and on for 600 – and repeats that pattern during the first 15 seconds after conditions being met. The annoyingly complicated if statements in the code are to prevent retriggering; that is, to prevent another 15-second blink session immediately starting up if the trigger conditions are still present. Your problem statement is not perfectly clear on how that should be handled.

// 6 Flashing LED Lights With A Pushbutton and FSR Sensor

enum { LedPin6=2, LedPin5, LedPin4, LedPin3, LedPin2, LedPin1 };
enum { buttonPin=8, SensorPin = A0};
enum { quantum=200, sessionLength=15000/quantum};

byte buttonState = 0;
byte SensorPinReading;
byte blinkLEDs=false, sessionDone=false;
unsigned long baseMilli;

void setLEDlevels(byte level) {
  digitalWrite(LedPin1, level);
  digitalWrite(LedPin2, level);
  digitalWrite(LedPin3, level);
  digitalWrite(LedPin4, level);
  digitalWrite(LedPin5, level);
  digitalWrite(LedPin6, level);     
}

void setup() {
  Serial.begin(115200);
  pinMode(LedPin1, OUTPUT);
  pinMode(LedPin2, OUTPUT);
  pinMode(LedPin3, OUTPUT);
  pinMode(LedPin4, OUTPUT);
  pinMode(LedPin5, OUTPUT);
  pinMode(LedPin6, OUTPUT);
  pinMode(buttonPin,INPUT);
  pinMode(SensorPin, INPUT);
}

void loop() {
  SensorPinReading = analogRead(SensorPin);
  Serial.print("Analog reading = ");
  Serial.print(SensorPinReading);

  if (SensorPinReading < 10) {
    Serial.println(" - No Pressure");
  } else if (SensorPinReading < 200) {
    Serial.println(" - Light Touch");
  } else if (SensorPinReading < 500) {
    Serial.println(" - Light Squeeze");
  } else if (SensorPinReading < 800) {
    Serial.println(" - Medium Squeeze");
  } else {
    Serial.println(" - Big Squeeze");
  }

  buttonState = digitalRead(buttonPin);
  // Turn on 15-second blink session if conditions met
  if (buttonState == HIGH && SensorPinReading > 10)  {
    if (!blinkLEDs && !sessionDone) { // Is session eligible?
      blinkLEDs = true;
      sessionDone = false;
      baseMilli = millis();
    }
  } else {               // A condition failed.
    if (sessionDone)             // Has session finished?
      blinkLEDs = sessionDone = false; // Enable next session
  }

  if (blinkLEDs) {
    int age = (millis()-baseMilli)/quantum;
    setLEDlevels((age&3)>0);    // Off for 1 quantum, on for 3 quanta
    // See if blink session has run long enough
    if (age > sessionLength) {
      blinkLEDs = false;        // Stop blinking
      sessionDone = true;   // Prevent retrigger until conditions reset
      setLEDlevels(LOW);    // Turn off lights
    }
  }
}

The statement setLEDlevels((age&3)>0) calls setLEDlevels() with a parameter value of 0 or 1. It will be 0 if age is a multiple of 4. In binary, multiples of 4 have their lowest two bits clear. It will be 1 if age is not a multiple of 4. This will alternately turn the LEDs off for one quantum (200 ms) and then on for 3 quanta (600 ms).


Edit 1: To “make the sensor read input while the button is not pressed, and then relay that input once the button is pressed so the LEDs immediately light up when it is pressed”, add a state variable (eg sensorPressed) to use in place of SensorPinReading > 10. Whenever SensorPinReading is large enough (and any other necessary conditions are met), set sensorPressed. When you start a blink session, reset sensorPressed (make it false).

Note, from your comment, you've added the following code near the end of loop():

if (buttonState == LOW && blinkLEDs == true) {
  blinkLEDs = false; 
  sessionDone = true; 
  setLEDlevels(LOW); 
}

A minor issue with that code is it leaves sessionDone = true. It is minor because the next pass through loop() usually will execute the else branch (of the if (buttonState == HIGH && SensorPinReading > 10) if-statement) which will go ahead and set sessionDone = false to enable the next blink session. Assuming you want to shut down blinking whenever the button is low, what I would do instead of that little code block is this:

if (!buttonState) {
  blinkLEDs = sessionDone = false; 
  setLEDlevels(LOW); 
}

(The expression !buttonState has the same value as buttonState == LOW and is four syllables shorter.)

Note, the code perhaps can be made more clear by using a state machine to control what happens. To do so, draw a diagram with nodes representing possible states – such as “idle” or “waiting for inputs”, “enabled”, “blinking”, “after blinking”. Draw lines between states, each labeled with the condition that triggers the particular state transition. State machines can be implemented using switch and case statements, or via an if–else sequence.

  • thank you so much! That is basically what I need, although I made one modification to your code... – msquirrel Apr 20 '17 at 16:00
  • if (buttonState == LOW && blinkLEDs == true) { blinkLEDs = false; sessionDone = true; setLEDlevels(LOW); Thank you so much @jwpat7 ! Sorry about the unclear problem statement. I added the above code at the end. Now to complicate it a bit more. I will explain best I can. Is there any way to make the sensor read input while the button is not pressed, and then relay that input once the button is pressed so the LEDs immediately light up when it is pressed? Either way thank you again! – msquirrel Apr 20 '17 at 16:09
  • @msquirrel, see edit 1 – James Waldby - jwpat7 Apr 20 '17 at 16:40
  • To “make the sensor read input while the button is not pressed, and then relay that input once the button is pressed so the LEDs immediately light up when it is pressed”... I changed the SensorPinReading to sensorPressed, but what type of statement would I use in the loop to meet the condition? I tried similar if statements that did not work, and I'm unsure of how to set it up. – msquirrel Apr 20 '17 at 17:30
  • You still need to set SensorPinReading = analogRead(SensorPin) each pass thru loop. Turn on sensorPressed whenever SensorPinReading is high enough; turn sensorPressed off once you have used it to trigger a blink session. – James Waldby - jwpat7 Apr 20 '17 at 17:34
1

Here below is modified code based on your requirement. There are some changes in your code and I also comment it out. I hope it will help you.

/*
 6 Flashing LED Lights With A Pushbutton and FSR Sensor
*/

const int buttonPin = 8;

const int LedPin1 = 7;
const int LedPin2 = 6;
const int LedPin3 = 5;
const int LedPin4 = 4;
const int LedPin5 = 3;
const int LedPin6 = 2;

const int kDelay = 1000; // Take one varible "kDelay" and value = 1000

int buttonState = 0;
int SensorPin = A0;
int SensorPinReading;


void setup()
{
  Serial.begin(9600);
  pinMode(LedPin1, OUTPUT);
  pinMode(LedPin2, OUTPUT);
  pinMode(LedPin3, OUTPUT);
  pinMode(LedPin4, OUTPUT);
  pinMode(LedPin5, OUTPUT);
  pinMode(LedPin6, OUTPUT);

  pinMode(buttonPin,INPUT_PULLUP); // Provide PULLUP
  pinMode(SensorPin, INPUT);
}


void loop()
{
  SensorPinReading = analogRead(SensorPin);
  Serial.print("Analog reading = ");
  Serial.print(SensorPinReading);

  if(SensorPinReading < 10)
  {
    Serial.println(" - No Pressure");
  }
  else if (SensorPinReading < 200)
  {
    Serial.println(" - Light Touch");
  }
  else if (SensorPinReading < 500)
  {
    Serial.println(" - Light Squeeze");
  }
  else if (SensorPinReading < 800)
  {
    Serial.println(" - Medium Squeeze");
  }
  else
  {
    Serial.println(" - Big Squeeze");
  }


  buttonState = digitalRead(buttonPin);

  if(buttonState == HIGH && SensorPinReading > 10)
  {
    digitalWrite(LedPin1, HIGH);
    digitalWrite(LedPin2, HIGH);
    digitalWrite(LedPin3, HIGH);
    digitalWrite(LedPin4, HIGH);
    digitalWrite(LedPin5, HIGH);
    digitalWrite(LedPin6, HIGH);     
    delay(15 * kDelay);            // You need 15 Sec, multiply kDelay with 15                      
    digitalWrite(LedPin1, LOW);
    digitalWrite(LedPin2, LOW);
    digitalWrite(LedPin3, LOW);
    digitalWrite(LedPin4, LOW);
    digitalWrite(LedPin5, LOW);
    digitalWrite(LedPin6, LOW);                              
  }
  else
  {
    digitalWrite(LedPin1, LOW);
    digitalWrite(LedPin2, LOW);
    digitalWrite(LedPin3, LOW);
    digitalWrite(LedPin4, LOW);
    digitalWrite(LedPin5, LOW);
    digitalWrite(LedPin6, LOW);
  }
}
  • is there any way to make the LEDs blink like the previous sketch during the 15 seconds? @Hasan – msquirrel Apr 20 '17 at 14:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.