Millis (); won't work properly

Hello everyone,

I'm trying to program Arduino uno to Blink 1 led at 20Hz or 40Hz for 5 secs after pressing a pushbutton to select between two modes (20Hz or 40Hz), and then after 5 secs it stops blinking and stay idle awaiting for another button push.
The issue is that the 5 sec timer won't work, it does not starts blinking when i press the button.
Could someone help me please.

Thanks in advance,

// Pin assignement
const int ledPin = 7;
const int btnPin = 8;
#include <Wire.h>   
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
enum fcnMode {
OFF,
BLINK1,
BLINK2,
NBSTATE
};  // OFF = 0 and NBSTATE=7
int ledState = LOW;  // ledState used to set the led
unsigned long buttonState = 0;
int funcState = 0;
unsigned long currentTime1, currentTime2, currentTimebtn, currentTimeact1, currentTimeact2;  // will store current time
unsigned long previousTime1, previousTime2, previousTimebtn, previousTimeact1, previousTimeact2;  // will store last time led was updated
const long PERIOD1 = 25000;  // interval at which to blink (microseconds) = 20 Hz
const long PERIOD2 = 12500;  // interval at which to blink (microseconds) = 40 Hz
const long PERIODact = 5000;  // amount of time to keep blinking (milliseconds)
const long PERIODbtn = 150000;  // (microseconds)
/******************************************************************\
SETUP
\******************************************************************/
void setup() {
lcd.begin(16, 2); // LCD 
pinMode(btnPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
}
/******************************************************************\
Main Function of the code
\******************************************************************/
void loop() {
buttonPressed();
setMode();
}
/******************************************************************
SUBFUNCTIONS
\******************************************************************/
void buttonPressed(){
currentTimebtn = micros();
if (currentTimebtn - previousTimebtn >= PERIODbtn) { // push button delay to prevent fast toggling between funcstates when pressed
previousTimebtn = currentTimebtn;
{
if (digitalRead(btnPin) == HIGH){
funcState += 1;
if (funcState >= 4) {
funcState = 0;
lcd.clear();
}
}
}
}
}
void setMode() {
// All Off
switch (funcState) {
case OFF:
digitalWrite(ledPin, LOW);
lcd.setCursor(4,0);
lcd.print("*Idle*"); // LCD main idle screen
break;
case BLINK1:
blinkled1();
break;
case BLINK2:
blinkled2();
break;
}
}
void blinkled1() {
currentTime1 = micros();
lcd.setCursor(2,0);
lcd.print("Mode: 20 Hz"); // LCD shows selected mode
if (currentTime1 - previousTime1 >= PERIOD1) { // defines the blinking frequency
// save the last time you blinked the led
previousTime1 = currentTime1;
// if the led is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
}
else {
ledState = LOW;
}
// set the led with the ledState of the variable: 
digitalWrite(ledPin, ledState);
}
currentTimeact1 = millis();
if (currentTimeact1 - previousTimeact1 >= PERIODact) { // checks if time after the start is equal or longer than 5 seconds to stop blinking
previousTimeact1 = currentTimeact1;
lcd.clear();
funcState = 0; //go back to iddle screen
}
}
void blinkled2() {
currentTime2 = micros();
lcd.setCursor(2,0);
lcd.print("Mode: 40 Hz"); // LCD shows selected mode
if (currentTime2 - previousTime2 >= PERIOD2) { // defines the blinking frequency
// save the last time you blinked the led
previousTime2 = currentTime2;
// if the led is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} 
else {
ledState = LOW;
}
// set the led with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
currentTimeact2 = millis();
if (currentTimeact2 - previousTimeact2 >= PERIODact) { // checks if time after the start is equal or longer than 5 seconds to stop blinking
previousTimeact2 = currentTimeact2;
lcd.clear();
funcState = 0; //go back to iddle screen
}
}

if you want to use millis() , you should use millis().
Paul

currentTimebtn = millis();

You forgot to set previousTimeact1 to millis() to start the five second timer. Do that when the button changes funcState.

Most people cannot see an LED blink faster than 25Hz.

i use micros for the fast blinking frequency and millis for the other timer

Why? Millis() can be used for any time greater than a few milliseconds.
Paul

i set currentTimeact1 = millis(); isn't that right?

Ok.
I changed all the micros (); for millis ();
The same issue persists.

Post the revised code in your next post, using code tags.

You don't set currentTimeact1 and currentTimeact2 to millis() when the state changes to BLINK1 or BLINK2.

Is it what you mean?

// Pin assignement
const int ledPin = 7;
const int btnPin = 8;
#include <Wire.h>   
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
enum fcnMode {
OFF,
BLINK1,
BLINK2,
NBSTATE
};  // OFF = 0 and NBSTATE=7
int ledState = LOW;  // ledState used to set the led
unsigned long buttonState = 0;
int funcState = 0;
unsigned long currentTime1, currentTime2, currentTimebtn, currentTimeact1, currentTimeact2;  // will store current time
unsigned long previousTime1, previousTime2, previousTimebtn, previousTimeact1, previousTimeact2;  // will store last time led was updated
const long PERIOD1 = 25;  // interval at which to blink (microseconds) = 20 Hz
const long PERIOD2 = 12.5;  // interval at which to blink (microseconds) = 40 Hz
const long PERIODact = 5000;  // amount of time to keep blinking (milliseconds)
const long PERIODbtn = 150;  // (microseconds)
/******************************************************************\
SETUP
\******************************************************************/
void setup() {
lcd.begin(16, 2); // LCD 
pinMode(btnPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
}
/******************************************************************\
Main Function of the code
\******************************************************************/
void loop() {
buttonPressed();
setMode();
}
/******************************************************************
SUBFUNCTIONS
\******************************************************************/
void buttonPressed(){
currentTimebtn = millis();
if (currentTimebtn - previousTimebtn >= PERIODbtn) { // push button delay to prevent fast toggling between funcstates when pressed
previousTimebtn = currentTimebtn;
{
if (digitalRead(btnPin) == HIGH){
funcState += 1;
if (funcState >= 4) {
funcState = 0;
lcd.clear();
}
}
}
}
}
void setMode() {
// All Off
switch (funcState) {
case OFF:
digitalWrite(ledPin, LOW);
lcd.setCursor(4,0);
lcd.print("*Idle*"); // LCD main idle screen
break;
case BLINK1:
blinkled1();
break;
case BLINK2:
blinkled2();
break;
}
}
void blinkled1() {
currentTime1 = millis();
currentTimeact1 = millis();
lcd.setCursor(2,0);
lcd.print("Mode: 20 Hz"); // LCD shows selected mode
if (currentTime1 - previousTime1 >= PERIOD1) { // defines the blinking frequency
// save the last time you blinked the led
previousTime1 = currentTime1;
// if the led is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
}
else {
ledState = LOW;
}
// set the led with the ledState of the variable: 
digitalWrite(ledPin, ledState);
}
if (currentTimeact1 - previousTimeact1 >= PERIODact) { // checks if time after the start is equal or longer than 5 seconds to stop blinking
previousTimeact1 = currentTimeact1;
lcd.clear();
funcState = 0; //go back to iddle screen
}
}
void blinkled2() {
currentTime2 = millis();
currentTimeact2 = millis();
lcd.setCursor(2,0);
lcd.print("Mode: 40 Hz"); // LCD shows selected mode
if (currentTime2 - previousTime2 >= PERIOD2) { // defines the blinking frequency
// save the last time you blinked the led
previousTime2 = currentTime2;
// if the led is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} 
else {
ledState = LOW;
}
// set the led with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
if (currentTimeact2 - previousTimeact2 >= PERIODact) { // checks if time after the start is equal or longer than 5 seconds to stop blinking
previousTimeact2 = currentTimeact2;
lcd.clear();
funcState = 0; //go back to iddle screen
}
}

When I see this, I just walk away.

If i take one out of these } the IDE reports error: expected '}' at end of input

If you auto-formatted your code (or previously formatted it properly but manually), you would see why. Code that is written this way, makes it difficult to identify the code blocks.

I'm just a beginner, so i cant notice anything wrong with the }
The part of the program that is not working the way i need, i guess it has nothing with the }.

It definitely does, in this case, because it impacts the ability of helpers to read your code, and find any problems. Technically, it isn't directly responsible for the problem.

Someone made a suggestion, you replied with a question about what I presume is updated code. In order to consider it, I have to read the code.

Not exactly. You want to mark the time when the blink state is selected. Something along the lines of this (not able to compile as your LCD object declaration doesn't work for me...):

// Pin assignement
const int ledPin = 7;
const int btnPin = 8;
#include <Wire.h>   
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
enum fcnMode 
{
    OFF=0,
    BLINK1,
    BLINK2,
    NBSTATE
};  // OFF = 0 and NBSTATE=7

int ledState = LOW;  // ledState used to set the led
unsigned long buttonState = 0;
int funcState = 0;
unsigned long currentTime1, currentTime2, currentTimebtn, currentTimeact1, currentTimeact2;  // will store current time
unsigned long previousTime1, previousTime2, previousTimebtn, previousTimeact1, previousTimeact2;  // will store last time led was updated
const long PERIOD1 = 25;  // interval at which to blink (microseconds) = 20 Hz
const long PERIOD2 = 12.5;  // interval at which to blink (microseconds) = 40 Hz
const long PERIODact = 5000;  // amount of time to keep blinking (milliseconds)
const long PERIODbtn = 150;  // (microseconds)
/******************************************************************\
SETUP
\******************************************************************/
void setup() 
{
    lcd.begin(16, 2); // LCD 
    pinMode(btnPin, INPUT_PULLUP);
    pinMode(ledPin, OUTPUT);
}
/******************************************************************\
Main Function of the code
\******************************************************************/
void loop() 
{
    buttonPressed();
    setMode();
}
/******************************************************************
SUBFUNCTIONS
\******************************************************************/
void buttonPressed()
{
    currentTimebtn = millis();
    if (currentTimebtn - previousTimebtn >= PERIODbtn) 
    { // push button delay to prevent fast toggling between funcstates when pressed
        previousTimebtn = currentTimebtn;
        if (digitalRead(btnPin) == HIGH)
        {
            funcState += 1;
            if (funcState >= NBSTATE)   //changed from '4' 
                funcState = 0;
            
            lcd.clear();
            switch( funcState )
            {
                case    OFF:
                    digitalWrite(ledPin, LOW);
                    lcd.setCursor(4,0);
                    lcd.print("*Idle*"); // LCD main idle screen
                break;
                
                case    BLINK1:
                    lcd.setCursor(2,0);
                    lcd.print("Mode: 20 Hz"); // LCD shows selected mode
                    currentTimeact1 = millis();
                    previousTime1 = currentTimeact1;
                break;
                
                case    BLINK2:
                    lcd.setCursor(2,0);
                    lcd.print("Mode: 40 Hz"); // LCD shows selected mode
                    currentTimeact2 = millis();
                    previousTime2 = currentTimeact2; 
                break;
                
                default:
                break;
            }
        }
    }
}

void setMode() 
{
    // All Off
    switch (funcState) 
    {
        case OFF:
        break;
        
        case BLINK1:
            blinkled1();
        break;
        case BLINK2:
            blinkled2();
        break;
    }
}

void blinkled1() 
{
    currentTime1 = millis();    
    if (currentTime1 - previousTime1 >= PERIOD1) 
    { 
        // defines the blinking frequency
        // save the last time you blinked the led
        previousTime1 = currentTime1;
        // if the led is off turn it on and vice-versa:
        if (ledState == LOW) 
        {
            ledState = HIGH;
        }
        else 
        {
            ledState = LOW;
        }
        // set the led with the ledState of the variable: 
        digitalWrite(ledPin, ledState);
    }

    if (currentTimeact1 - previousTimeact1 >= PERIODact) 
    { 
        // checks if time after the start is equal or longer than 5 seconds to stop blinking
        previousTimeact1 = currentTimeact1;
        ReturnToIdleState();
    }
}

void blinkled2() 
{
    currentTime2 = millis();
    if (currentTime2 - previousTime2 >= PERIOD2) 
    { 
        // defines the blinking frequency
        // save the last time you blinked the led
        previousTime2 = currentTime2;
        // if the led is off turn it on and vice-versa:
        if (ledState == LOW) 
        {
            ledState = HIGH;
        } 
        else 
        {
            ledState = LOW;
        }
        // set the led with the ledState of the variable:
        digitalWrite(ledPin, ledState);
    }
    if (currentTimeact2 - previousTimeact2 >= PERIODact) 
    { 
        // checks if time after the start is equal or longer than 5 seconds to stop blinking
        previousTimeact2 = currentTimeact2;
        ReturnToIdleState();
    }
}

void ReturnToIdleState( void )
{
    lcd.clear();
    funcState = OFF; //go back to iddle screen
    digitalWrite(ledPin, LOW);
    lcd.setCursor(4,0);
    lcd.print("*Idle*"); // LCD main idle screen
    
}//ReturnToIdleState

Wrong datatype.

Using your modification, nothing happens when pressing push button once, and pressing fast twice, led starts blinks but lasts forever.