Quick help with millis()

Hi, Im trying to make sort some of protection for my touch buttons so when i dont need to use them they become inactive. I`ve made simple statement in void loop(), that when i press button for more than 3 seconds void activeTouch should loop it self for 10 second and quit if NO input is detected or if input IS detected the 10 second countdown should go back to 0 every time the touch pad is active.

So

const byte button1 = 30;
const byte button2 = 32;

const byte led1 = 22;
const byte led2 = 23;

const byte redPin = 12;
const byte greenPin = 11;
const byte bluePin = 10;

byte ButtonState;
byte lastState = LOW;
byte count = 0;

int lastReading = HIGH;
byte  hold = false;
unsigned long switchOn = 0;
const unsigned int holdTime = 3000;
const unsigned int deactivateTime = 10000;



void setup()
{
  Serial.begin(9600);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(redPin, HIGH);
  pinMode(greenPin, HIGH);
  pinMode(bluePin, HIGH);
}

void loop()
{
  if(digitalRead(button1) == LOW)
  {
    switchOn = millis();
    Serial.println(switchOn);
  }
    
  if((millis() - switchOn) > holdTime)
    {
      activeTouch();
    }
     
  }


void activeTouch()
{
  bool deactivated = false;
  unsigned long activeTime = 0;

  while(!deactivated)
  {
    digitalWrite(led1, !digitalRead(button1));
    digitalWrite(led2, !digitalRead(button2));
    activeTime = millis();
    Serial.println("active");
  }
  if ((millis() - activeTime) > deactivateTime)
  {
    deactivated = true;
  }
}

Symptons at the moment are - the code goes straight to activeTouch, not even waiting for user input.

Any suggestions?? Thanks

You want unsigned longs not ints for your times.

the code goes straight to activeTouch,

Are you sure? Doesn't it wait three seconds after reset?

Well AWOL i think this is what he is actually doing :)

To expand on AWOL’s comment

focus your attention on this line

if((millis() - switchOn) > holdTime)

Better yet, lets run some simple debugging and I will let you see what happens

const byte button1 = 30;
const byte button2 = 32;

const byte led1 = 22;
const byte led2 = 23;

const byte redPin = 12;
const byte greenPin = 11;
const byte bluePin = 10;

byte ButtonState;
byte lastState = LOW;
byte count = 0;

int lastReading = HIGH;
byte  hold = false;
unsigned long switchOn = 0;
const unsigned int holdTime = 3000;
const unsigned int deactivateTime = 10000;



void setup()
{
  Serial.begin(9600);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(redPin, HIGH);
  pinMode(greenPin, HIGH);
  pinMode(bluePin, HIGH);
}

void loop()
{
  if(digitalRead(button1) == LOW)
  {
    switchOn = millis();
    Serial.println(switchOn);
  }
  Serial.print("millis: ");
  Serial.print(millis());
  Serial.print(", switchOn: ");
  Serial.println(switchOn);  
  if((millis() - switchOn) > holdTime)
    {
      Serial.println("millis() - switchOn is now > holdTime, executing activeTouch() function!");
      activeTouch();
    }
     
  }


void activeTouch()
{
  bool deactivated = false;
  unsigned long activeTime = 0;

  while(!deactivated)
  {
    digitalWrite(led1, !digitalRead(button1));
    digitalWrite(led2, !digitalRead(button2));
    activeTime = millis();
    Serial.println("active");
  }
  if ((millis() - activeTime) > deactivateTime)
  {
    deactivated = true;
  }
}

Can you please give some clue??

What is the initial value of switchOn?

it`s 0 and millis start after button is pressed

Run my sample code I gave you, why are you continuing to ask?!

No, millis starts as soon as the processor is reset

AWOL: No, millis starts as soon as the processor is reset

I believe he meant the value of switchOn is millis() after he presses the button

Ps991, sorry last time i checked it was only "focus your attention on this line" did not know you updated it.

Any way, i run your code, and there is no difference to what i had, does exactly the same way it count automaticly from reset and goes to activeTouch(); where i need him to go to that function after i press and hold the button for 3 second.

Did you open the serial monitor and examine the numbers being displayed? Does the number displayed mean anything to you, if not, try changing holdTime to 10000 and try again

ok, i see your point.

Tells me that the code goes to activeTouch after 3sec unless is interupted by switchOn and his counter starts again.

Am i right?

Yes you are! Which variable is 3 seconds?

so at this stage millis() triggering event instead of a button, but this function will be handy to quit while loop in activeTouch

Ok well I got to go to work, here is your solution. PLEASE try to understand why this works!

const byte button1 = 30;
const byte button2 = 32;

const byte led1 = 22;
const byte led2 = 23;

const byte redPin = 12;
const byte greenPin = 11;
const byte bluePin = 10;

byte ButtonState;
byte lastState = LOW;
byte count = 0;

int lastReading = HIGH;
byte  hold = false;
unsigned long switchOn = 0;
boolean isButtonHeld = false;
const unsigned int holdTime = 3000;
const unsigned int deactivateTime = 10000;



void setup()
{
  Serial.begin(9600);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(redPin, HIGH);
  pinMode(greenPin, HIGH);
  pinMode(bluePin, HIGH);
}

void loop()
{
  if(digitalRead(button1) == LOW)
  {
    if(!isButtonHeld) //only activate once!
      switchOn = millis();
    isButtonHeld = true;
    Serial.println(switchOn);
  }
  else
    isButtonHeld = false;
    
  if(isButtonHeld && millis() - switchOn > holdTime) //button has to be held AND for at least "holdTime" milliseconds
    {
      activeTouch();
    }
     
  }


void activeTouch()
{
  bool deactivated = false;
  unsigned long activeTime = 0;

  while(!deactivated)
  {
    digitalWrite(led1, !digitalRead(button1));
    digitalWrite(led2, !digitalRead(button2));
    activeTime = millis();
    Serial.println("active");
  }
  if ((millis() - activeTime) > deactivateTime)
  {
    deactivated = true;
  }
}

ok i sit down and study that, all the time i was trying to modify debounce example. Thanks a lot

Also, this has a problem in it, it will never exit I think

  bool deactivated = false;
  unsigned long activeTime = 0;

  while(!deactivated)
  {
    digitalWrite(led1, !digitalRead(button1));
    digitalWrite(led2, !digitalRead(button2));
    activeTime = millis(); //always updating!!!!!!!!!!
    Serial.println("active");
  }
  if ((millis() - activeTime) > deactivateTime) //this will always be essentially millis() - millis() !!!!!!!!!!! WILL NOT WORK
  {
    deactivated = true;
  }

Ps991:
Also, this has a problem in it, it will never exit I think

Dead right.

The while condition is checking a value which is not modified inside the loop. While (a thing which never changes) can’t be right.

Also. The if condition and inverted boolean flag, is just a long way to say is, ( (now - start) < period) So you might as well write that. Add an = if you 1ms difference to your original, is important.

Finally. Best to avoid functions depending on globals, so pass the global as a parameter and the code is easier to read and to debug.

const unsigned long deactivateTime = 10000;

void loop(void {

//...

  activeTime(millis(), deactivateTime );

//...
}

void activeTouch(unsigned long start, unsigned long period) {

  while( (millis() - start) < period ) {
    digitalWrite(led1, !digitalRead(button1));
    digitalWrite(led2, !digitalRead(button2));
    Serial.println("active");                           //this will get called an awful lot.
  }

HTH