Mills code being ignored, by if statement... trouble shooting

Hi:

I have tried every permutation of code I can find to get this to work, the meat of the code works but for some reason when I replace my delay with mills the code ignores that portion. What your looking at is code for a lighting display that fades on based on approach and then holds on for a set amount of time or as long as your standing close then fades off as you leave. I can get it working perfectly with one using delay but due I needing to run multiples from one arduino can some one direct me if I am way off or I simply have something wrong with the code?

I have also tried moving the fade functions out into a self contained function… no luck.

int sensorPin = 0; //analog pin 0
int ledPin = 9;   // Red LED,   connected to digital pin 9
int ledVal = 0;   // Variables to store the values to send to the pins
int sensorValue, fadeValue, sensorValuePush;

long previousMillis1 = 0;
long currentMillis1 = 0; 
long previousMillis2 = 0;
long currentMillis2 = 0;
long interval1 = 600;
long interval2 = 10000;

void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  

 //pinMode(s3Pin, INPUT);
 
  
    Serial.begin(9600);  // ...set up the serial ouput in 0004 format
  }




// Main program
void loop()



{
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  
  
  sensorValue = analogRead(sensorPin);
  
   if(currentMillis1 - previousMillis1 > interval1) {
    previousMillis1 = currentMillis1;   
  
  sensorValuePush = sensorValue;

}
  
  
   
  if (sensorValuePush >= 70 && ledVal <= 254) 
  { ledVal++;
    analogWrite(ledPin, ledVal);
  }         
              
  if (sensorValuePush <= 70 && ledVal >= 1) 
  { ledVal--;
    analogWrite(ledPin, ledVal); 
  }           
      
  if (sensorValuePush <= 70 && ledVal <= 1) 
  { ledVal = 0;
    analogWrite(ledPin, ledVal); 
  }                            
     
  if (sensorValuePush <= 70 && ledVal >= 250 )
  {       
        
     unsigned long currentMillis2 = millis();
   if(currentMillis2 - previousMillis2 > interval2) {
    previousMillis2 = currentMillis2; 

  ledVal = 25;
    analogWrite(ledPin, ledVal); 
  
      
 }
    
    
  }
 



 
  delay(5);
Serial.println(ledVal);
//Serial.println(sensorValue);
  
  
}

Thanks
J

There is a 0.6 second interval and a 10 second interval. It’s not clear when you intended the intervals to start and what you intended to de when the interval expired. What did the code with delays do?

This sketch will do the basic fading:

const int sensorPin = A0; //analog pin 0
const int ledPin = 9;   // Red LED,   connected to digital pin 9

int ledVal = 0;   // Variables to store the values to send to the pins
int sensorValuePush;

unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long interval1 = 600;
unsigned long interval2 = 10000;

void setup() {
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  // pinMode(s3Pin, INPUT);
  Serial.begin(9600);  // ...set up the serial ouput in 0004 format
}

// Main program
void loop() {
  unsigned long currentMillis = millis();

  // Every 0.6 seconds read the input sensor (Why?)
  if(currentMillis - previousMillis1 > interval1) {
    previousMillis1 = currentMillis;   
    sensorValuePush = analogRead(sensorPin);
    ;
  }

  // Every 1/100th of a second, ramp the brightness up or down.  
  // This should take about 2.55 seconds to do a full ramp
  if(currentMillis - previousMillis2 > 10) {
    previousMillis2 = currentMillis;   

    if (sensorValuePush >= 70 && ledVal < 255) { 
      ledVal++;
      analogWrite(ledPin, ledVal);
    }         

    if (sensorValuePush <= 70 && ledVal > 0) { 
      ledVal--;
      analogWrite(ledPin, ledVal); 
    }           
  }
}

I’m sorry, I failed to mention the .6 second interval works, it smooths out the sensor read.

The delay held the light on for a set amount of time, so that even if you walk away from the exhibit the light is on for a few seconds, then fades out. Below is the code with the delay.

int sensorPin = 0; //analog pin 0
int ledPin = 9;   // Red LED,   connected to digital pin 9
int ledVal = 0;   // Variables to store the values to send to the pins
int sensorValue, fadeValue, sensorValuePush;

long previousMillis1 = 0;
long currentMillis1 = 0; 
long previousMillis2 = 0;
long currentMillis2 = 0;
long interval1 = 600;
long interval2 = 10000;

void setup()
{
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  

 //pinMode(s3Pin, INPUT);
 
  
    Serial.begin(9600);  // ...set up the serial ouput in 0004 format
  }




// Main program
void loop()



{
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  
  
  sensorValue = analogRead(sensorPin);
  
   if(currentMillis1 - previousMillis1 > interval1) {
    previousMillis1 = currentMillis1;   
  
  sensorValuePush = sensorValue;

}
  
  
   
  if (sensorValuePush >= 70 && ledVal <= 254) 
  { ledVal++;
    analogWrite(ledPin, ledVal);
  }         
              
  if (sensorValuePush <= 70 && ledVal >= 1) 
  { ledVal--;
    analogWrite(ledPin, ledVal); 
  }           
      
  if (sensorValuePush <= 70 && ledVal <= 1) 
  { ledVal = 0;
    analogWrite(ledPin, ledVal); 
  }                            
     
  if (sensorValuePush <= 70 && ledVal >= 250 )
  {       
     
  ledVal = 255;
   analogWrite(ledPin, ledVal); 
  delay(5000);
      
 }
    
    
  }
 



 
  delay(5);
Serial.println(ledVal);
//Serial.println(sensorValue);
  
  
}

A couple of videos of the test pieces. Maybe this will help make it more clear... this is the code with delay.

https://vine.co/v/bH6nmBpiQ2Y

https://vine.co/v/bD6MdvIgIpp

How long do you want the fade up and fade down to take?

jahue: holds on for a set amount of time or as long as your standing close then fades off as you leave.

Do you mean (1) it will start fading off after a set time even if you stay there, or (2) if you move away before the set time has expired it will stay on until the set time has expired?

long previousMillis1 = 0;
long currentMillis1 = 0; 
long previousMillis2 = 0;
long currentMillis2 = 0;
long interval1 = 600;
long interval2 = 10000;

These variables presumably refer to when some event happened in the past and how long until the next event of the same kind is to happen again.

I find it incredibly hard to believe that those events are 1 and 2.

Using meaningful names will make you life so much easier that I'm not even inclined to read code that has such poor names.

This should do what you want:

const int sensorPin = A0; //analog pin 0
const int ledPin = 9;   // Red LED,   connected to digital pin 9

int ledVal = 0;
unsigned long lastFullBrightnessTime = 0;
const unsigned long fullBrightnessInterval = 10000;
unsigned long lastFadeTime = 0;
const unsigned long fadeInterval = 10;

void setup() {
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  // pinMode(s3Pin, INPUT);
  Serial.begin(9600);  // ...set up the serial ouput in 0004 format
}

// Main program
void loop() {
  unsigned long currentMillis = millis();

  // Limit the fade rate
  if (currentMillis - lastFadeTime > fadeInterval) {
    lastFadeTime = currentMillis;
    
    if (analogRead(sensorPin) >= 70) {  // Person in range
      if (ledVal < 255)
        ledVal++;
      else
        lastFullBrightnessTime = currentMillis;
    } 
    else { // Person has moved away    
      if (ledVal > 0 && currentMillis - lastFullBrightnessTime > fullBrightnessInterval)
        ledVal--;
    }       
    analogWrite(ledPin, ledVal); 
  }  
}

Do you mean (1) it will start fading off after a set time even if you stay there, or (2) if you move away before the set time has expired it will stay on until the set time has expired?

The idea is as you approach the light fades up from 0 to full, if you get close enough the light will hold in the on position it will do so as long as your standing in that location (close enough to keep the sensor triggered) when you walk away the sensor value drops and the light is help on for lets say 10s then it fades back down to off. If you approach but don't meet the sensor value it will fade up but never lock on. All of this works with delay, just not with millis

These variables presumably refer to when some event happened in the past and how long until the next event of the same kind is to happen again.

I find it incredibly hard to believe that those events are 1 and 2.

Using meaningful names will make you life so much easier that I'm not even inclined to read code that has such poor names.

Yeah this was my attempt at isolating the timers.The names work for me... and as always I would love to have anyones help but my names work for me, I am not writing code for you. And the names used are very similar to the examples from Arduino... that I was using to test, if I change all the names to something goofy and "readable" then troubleshooting becomes harder for others. All should understand this code... if you have ever used the examples. This way I can get feed back on why things are not exactly working properly and can correct the mistake in the future, I generally change the names as I get a handle on whats is happening and not happening.

const int sensorPin = A0; //analog pin 0
const int ledPin = 9;   // Red LED,   connected to digital pin 9

int ledVal = 0;
unsigned long lastFullBrightnessTime = 0;
const unsigned long fullBrightnessInterval = 10000;
unsigned long lastFadeTime = 0;
const unsigned long fadeInterval = 10;

void setup() {
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  // pinMode(s3Pin, INPUT);
  Serial.begin(9600);  // ...set up the serial ouput in 0004 format
}

// Main program
void loop() {
  unsigned long currentMillis = millis();

  // Limit the fade rate
  if (currentMillis - lastFadeTime > fadeInterval) {
    lastFadeTime = currentMillis;
    
    if (analogRead(sensorPin) >= 70) {  // Person in range
      if (ledVal < 255)
        ledVal++;
      else
        lastFullBrightnessTime = currentMillis;
    } 
    else { // Person has moved away    
      if (ledVal > 0 && currentMillis - lastFullBrightnessTime > fullBrightnessInterval)
        ledVal--;
    }       
    analogWrite(ledPin, ledVal); 
  }  
}

This works!!! Can you walk me through the loop a little more? I think I understand exactly whats going on but I want to make sure…

is the fadeInterval setting steps/smoothness as the led fades up and down ?

This piece is tripping me up, If i am reading this right… if the led is on and the time limit has past fade down?

else { // Person has moved away    
      if (ledVal > 0 && currentMillis - lastFullBrightnessTime > fullBrightnessInterval)
        ledVal--;

So as you approach the light fades up, but lets say you don’t get close enough it fades down properly but when does it know to stick and hang on for the interval? It’s working
as intended but that seems to be the one part that has me scratching my head.

Again thanks for the help, I am still wrapping my head around the logic.

is the fadeInterval setting steps/smoothness as the led fades up and down ?

fadeInterval is the time between changes to the brightness level.

This piece is tripping me up, If i am reading this right... if the led is on and the time limit has past fade down?

If the LED ramped up to full brightness and then the person moved away, the LED needs to fade down, right? This is the code that makes that happen.

So as you approach the light fades up, but lets say you don't get close enough it fades down properly but when does it know to stick and hang on for the interval?

When the LED gets to full brightness, the time that that happens is recorded. It is that time that is used to hold the LED at full brightness for the required time. If the LED hasn't reached full brightness, then the time is 0. Compare the effects of the if test using 0 and 12000 as the value for last full brightness time, when now is 18000.

jahue: else { // Person has moved away          if (ledVal > 0 && currentMillis - lastFullBrightnessTime > fullBrightnessInterval)         ledVal--;

That part means:

The person has moved away, so... If (the brightness isn't already 0) and (it has been at least ten seconds since the last time the LED was at full brightness): Reduce the brightness one step.

To me this feels like a problem that is calling out to be implemented as a finite state machine, with states for IDLE, APPROACHING, PRESENT, WAITING, FADING.

The logic to calculate the appropriate brightness in each state and when to transition to the next state then becomes very simple. IMO this would be a lot cleaner and simpler than using a complex set of discrete checks for different combinations of timers and distances.

To me this feels like a problem that is calling out to be implemented as a finite state machine, with states for IDLE, APPROACHING, PRESENT, WAITING, FADING.

This is super intriguing can you point me to some resource where I can read about this? I have seen finite state machines mentioned but never really seen them implemented.

Thanks for all the help guys, I am curious as to why the final “full on hold” portion of my original sketch was ignored?

if (sensorValuePush <= 70 && ledVal >= 250 )
  {       
        
     unsigned long currentMillis2 = millis();
   if(currentMillis2 - previousMillis2 > interval2) {
    previousMillis2 = currentMillis2; 

    ledVal = 255;
    analogWrite(ledPin, ledVal); 
 
 }

I am assuming that this is completely wrong, however I was curious as to why the statement was being ignored?

Am I reading this correctly… if current time - previous time is greater than the set interval set the previous time to equal current time

I guess I am wonder about syntax and ordering, are there any good resource to walk me through this in a more comprehensive way? Or is this like the missing comma problem, where it’s a stupid simple bug or order flaw?

Again thanks for all the help, I hope that this can help others in similar situations!

jahue: I am curious as to why the final "full on hold" portion of my original sketch was ignored?

It wasn't ignored. It just didn't do what you wanted it to do, only what you told it to do;

if (nobody is present && the LED is near full brightness) {       
   if(it has been more than 10 seconds since the timer was started) {
     re-start the timer and set the LED to full brightness
  }
}

Since you re-start the 10-second timer this code will set the LED to full brightness and then do nothing for 10 seconds. In that time the LED will dim below 250 and the "near full brightness" will no longer apply.

You want the timer to start when the LED is at full brightness so you can prevent the dimming until it has been at full brightness for 10 seconds.