Help with blink without delay

I'm trying to write a program that compares an analog input value and if true starts a timer and when the timer is done turns on a led. Then the leds stays on as long the comparison is true. Right now what happens is as soon as the comparison is true the led turns on, it doesnt wait for the time delay. Thanks for any help.

enum LedStates{ON, OFF};           //The two possible states for an LED
LedStates ledState = ON;           //Start state is ON
byte ledPin = 13;                  //LED is on pin 13 (onboard LED)
int delayOff = 1000;               //The time in milliseconds that the LED will stay off
int delayOn = 500;                //The time in milliseconds that the LED will stay on
unsigned long chrono = millis();   //Our chronometer
const int analogOutPin = 9;        // Analog output pin that the LED is attached to

const int thresholdlow = 904;   // an arbitrary threshold level that's in the range of the analog input
const int thresholdhigh = 894;      
const int inputPin=A0;
int Sensor = 0;

void blinkMachine() { 
Sensor = analogRead(inputPin) ;


switch (ledState) {                        //Depending of the state
  case OFF: {                                //State is OFF
    if ((thresholdlow >= Sensor) &&(millis() - chrono >= delayOff)) {     
      chrono = millis();                       //Reset the chrono for next phase
      digitalWrite(ledPin, HIGH);              //Bring LED pin HIGH
      ledState = ON;                           //State is now ON
    }
    break;                                   //Get out of switch
  }
  case ON: {                                 //State is OFF
    if ((thresholdlow <= Sensor)&&(millis() - chrono >= delayOn)) {        
     chrono = millis();;                        //Reset the chrono for next phase
    digitalWrite(ledPin, LOW);                 //Bring LED pin LOW
      ledState = OFF;                            //State is now OFF
    }
    
    break;  
//Get out of switch
  }
}
}

void setup() { 
Serial.begin(9600);             
pinMode(ledPin, OUTPUT);     //LED pin mode is OUTPUT
digitalWrite(ledPin, HIGH);  //Bring it HIGH 
}
void loop() {
Serial.print("sensor = ");
Serial.println(Sensor);

blinkMachine();  //Run the machine
 
}

Welcome to the Forum. Please read these two posts:

General Guidance and How to use the Forum
and
Read this before posting a programming question ...
You have posted code without using code tags. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons. The "Code: [Select]" feature allows someone to select the entire sketch so it can be easily copied and pasted into the IDE for testing.

If you have already posted without using code tags, open your message and select "modify" from the pull down menu labelled, "More", at the lower right corner of the message. Highlight your code by selecting it (it turns blue), and then click on the "</>" icon at the upper left hand corner. Click on the "Save" button. Code tags can also be inserted manually in the forum text using the code and /code metatags.

Thanks for the reply, I went back and used code tags.

There's too much "blink without delay" left, you really have to start with the states that apply more directly to what you are trying to do.

Also combining the test for time and the test for analog value can be a source of error. Play computer and step through your cases by hand, don't assume they are doing what you think, they are doing what you wrote (as always!).

At the very least, you also have to decide what to do if the condition (analog compare to a fixed value) goes false during the delay period before you would have turnt on the light.

Also you don't seem to use thresholdhigh anywhere which makes me wonder if you have clearly and completely figured out (in any language) how you want the analog input, delay and thresholds to control whether the lamp is on or off.

I'm gonna guess you might have meant to have turning off after the other value is crossed after a delay, but I'm no mind reader, so.

a7

Your state machine does not have enough states.

You didn't specify during the timer state if the compare needs to remain true or not

BTW, you state machine seems overly complicated for such a simple task unless it may be part of a bigger project.

enum LedStates {OFF, ON_TIMING, ON, OFF_TIMING};
LedStates ledState = ON;           //Start state is ON
const byte ledPin = 13;                  //LED is on pin 13 (onboard LED)
const unsigned long delayOff = 1000;               //The time in milliseconds that the LED will stay off
const unsigned long delayOn = 500;                //The time in milliseconds that the LED will stay on
unsigned long chrono = millis();   //Our chronometer
const int analogOutPin = 9;        // Analog output pin that the LED is attached to

const int thresholdlow = 904;   // an arbitrary threshold level that's in the range of the analog input
const int thresholdhigh = 894;
const int inputPin = A0;
int Sensor = 0;

void blinkMachine() {
  Sensor = analogRead(inputPin);

  switch (ledState) {                        //Depending of the state
    case OFF:
      // check to see if sensor is good and if so, start timer
      if (thresholdlow <= Sensor) {
        chrono = millis();
        ledState = ON_TIMING;
      }
      break;

    case ON_TIMING:
      // must remain off for at least 'delayOff' msec before turning on
      if (millis() - chrono >= delayOff) {
        // timout, so proceed to next state
        chrono = millis();                       //Reset the chrono for next phase
        digitalWrite(ledPin, HIGH);
        ledState = ON;
      }
      break;

    case ON:
      // check to see if sensor is bad and if so, start timer
      if (thresholdlow > Sensor) {
        chrono = millis();
        ledState = OFF_TIMING;
      }
      break;

    case OFF_TIMING:
      // must remain on for at least 'delayOn' msec before turning off
      if (millis() - chrono >= delayOn) {
        // timout, so proceed to next state
        chrono = millis();                       //Reset the chrono for next phase
        digitalWrite(ledPin, LOW);
        ledState = OFF;
      }
      break;
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);     //LED pin mode is OUTPUT
  digitalWrite(ledPin, HIGH);  //Bring it HIGH
}
void loop() {
  Serial.print("sensor = ");
  Serial.println(Sensor);

  blinkMachine();  //Run the machine

}

It would be a big help (to us and also, I suspect for you) if you were to write a description of what the function blinkMachine() is intended to do. I can't figure it out but it seems to me you have stuff unnecessarily mixed up within it.

Also, it will make your code much easier to read and debug if you use the AutoFormat tool to indent the code consistently.

...R

I’m building a circuit for a tank, I have an analog sensor(variable float) to measure level and when the level goes low for 10 seconds I want it to turn on a warning light. I want to wait so that I don’t get a false indication of the actual level. I’ve looked at variations of blink without delay but i want the light to stay on as long as the level is low. The way the program works right now is that as soon as the level goes low it turns on the light, it does not wait for the time delay and the light stays on as long as the level is low.

I thought this piece of code would mean the the timer wouldn’t start unless
the threshold was less than or equal to Sensor but that’s not what happens.

if (thresholdlow <= Sensor) {
chrono = millis();
ledState = ON_TIMING;
}
break

cb

cbuckner6:
and when the level goes low for 10 seconds I want it to turn on a warning light. I want to wait so that I don’t get a false indication of the actual level.

A simple way to do that is with code like this pseudo code. Note that it is updating the clock every time it finds plenty of water in the tank - which may seem counter-intuitive at first.

tankState =  read depth sensor;
if (tankState == HIGH) { // i.e. plenty of water
   lastTimeTankHigh = millis();
}

if (millis() - lastTimeTankHigh >= interval) {
   // water level has been low throughout the interval
   doSomething();
}

...R

Thanks, I’m going to try this.