Operation between functions call.

Hello everyone

I am doing a test with a simple code to make a menu with functions separated from the loop function to configure the times that the LEDS will be lit
In the main function when I press the set button I want to go to the function menus I make the settings I want, to exit the function menu presses again set and goes to the main function.
The problem is that by pressing set for some time the program goes back and forth from the main function to the function menus alternately, I would like that by pressing set, whatever the time you press, to enter or exit the function only when I press a turn.

Here is the code I made as an example

Thank you in advance for your help

int set=12;
bool menut = 0;
int oldstat=0;
int pinbut;
int newstat;
void menus();

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
 pinMode(set,INPUT_PULLUP);
 
}

void loop() {
  
     
      pinbut = digitalRead(set);
   
      if ((pinbut== LOW) && (oldstat == HIGH)) 
      {
          menut = 1; 
          menus();
      }
      
       oldstat = pinbut;
   
Serial.println("main menu");

delay(100);
}

void menus()
{

     delay(800);
     
     while(menut> 0)
     {
      Serial.println(" function menus");
      
       pinbut= digitalRead(set);
 
      if ((pinbut== LOW) && (oldstat== HIGH)) 
      {
        menut =  0;
      }
      
      oldstat = pinbut;
     }
     
 }

You should probably read stuff about state machines

J-M-L:
You should probably read stuff about state machines

Hi, thanks for replying!

I have already done a lot of research I've read about state machines, but the understanding was not clear, so come here for a possible better clarification!
I hope everyone understands
thanks

Have you compiled what you've posted?

Hi
Thanks for answering !
Yes I compiled the code and compiled it without any problems after correcting for a missing (}) in setup, the problem is what I said in the first topic, if you can help me to solve this problem thank you

delay(100);

Why on earth do you have this? Do you get billed for the number of times loop() iterates?

void menus()
{

     delay(800);

More uselessness.

You don't DO anything useful in menus() so i really can't see the point of calling it.

PaulS:

delay(100);

Why on earth do you have this? Do you get billed for the number of times loop() iterates?

void menus()

{

delay(800);



More uselessness.

You don't DO anything useful in menus() so i really can't see the point of calling it.

That and the delay at the end of loop.

I've wired your circuit and run your code and basically the problem is with switch de-bounce (or lack of it). When you detect a button push, you basically goes straight back and read the button again, almost immediately after the last read. I stuck a delay in and everything works fine. Threw a couple of flags in as well to stop the annoying prints. Also changed the identifier assigned to the button pin, you should avoid using reserved words.

int     seti    =  12;
bool    menut   =  false;
int     oldstat =  0;
int     pinbut;
int     newstat;
void    menus();

#define Set(x)      (x = 1)
#define Clear(x)    (x = 0)

typedef struct      // bits
{
    byte    bit_0: 1;
    byte    bit_1: 1;
    byte    bit_2: 1;
    byte    bit_3: 1;
    byte    bit_4: 1;
    byte    bit_5: 1;
    byte    bit_6: 1;
    byte    bit_7: 1;
} bits;

bits    flag1;

#define mm_print            flag1.bit_0
#define fm_print            flag1.bit_1

void setup() 
{
    // put your setup code here, to run once:
    Serial.begin(9600);
    pinMode(seti,INPUT_PULLUP);
    Set(mm_print);
    Set(fm_print);
}

void loop() 
{
    pinbut = digitalRead(seti);

    if ((pinbut == LOW) && (oldstat == HIGH))
    {
        menut = true;
        Set(fm_print);
        delay(300);
        menus();
    }
    
    oldstat = pinbut;

    if(mm_print)
    {
        Serial.println("main menu");
        Clear(mm_print);
    }
}

void menus()
{
    while(menut)
    {
        if(fm_print)
        {
            Serial.println(" function menus");
            Clear(fm_print);
        }
        
        pinbut= digitalRead(seti);

        if ((pinbut== LOW) && (oldstat== HIGH))
        {
            menut =  false;
            Set(mm_print);
            delay(300);
        }
        
        oldstat = pinbut;
    }
}

Hi DKWatson

Thanks for the help, I tested the code that posted and works fine, but if you take a little longer when you press the back button to go to the main function!
What I'm really up to is whenever I press the button for whatever time it is pressed it only acts once each time it is pressed!

Well this is the test I'm doing, then I'm about to make a menu for several functions!

Thanks a lot for the help

The use of delay is not a solution, but a quick fix to identify where the problem is. You will need to establish some timeout before you test again for button push. Without delay, I would suggest the use of some sort of flag that gets set when you detect a button push and remains set while checking millis() to see if the timeout has passed (see the post on using millis() for timing), then clear the flag. Your test for a button push would then be contingent on the flag NOT set.

PaulS:

delay(100);

Why on earth do you have this? Do you get billed for the number of times loop() iterates?

void menus()

{

delay(800);



More uselessness.

You don't DO anything useful in menus() so i really can't see the point of calling it.

Hi PaulS

Actually this code does not do anything is even just so I understand how to make a code with functions separate from the loop function to only be executed when it is necessary for example to set a clock time, to regulate the brightness of LEDs, to light a lamp.
Thanks for the comment

The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

You may also find some ideas in Planning and Implementing a Program

...R

Robin2:
The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

You may also find some ideas in Planning and Implementing a Program

...R

Hi Robin2

I have already studied the operation of the millis, I do not think very complicated, my problem is applied in the logic of programming in this case in the control of the buttons in the functions
I'm studying in a simple way to get to the most advanced, and nothing better with simple examples like I posted.
today I have done dozens of tests to get what I want but without success so far, I hope to achieve.

thanks for helping

Fiasgardone:
today I have done dozens of tests to get what I want but without success so far, I hope to achieve.

Post the recent program that you think is the most promising.

...R

Hi to all

Robin2 as you said you should use millis () I did several small tests with millis in the code but anyway I'm doing wrong logic that does not work with millis. The program compiles well without errors but in practice it does not work as I wish , ie when I press the button the program exits the main function stick to the function menus and back to the main function!

Below is the last code I made, I hope you can help me.

int set=12;
bool menut = 0;
int oldstat=0;
int pinbut;
int newstat;
void menus();

 unsigned long delayBounce;
 
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
 pinMode(set,INPUT_PULLUP);
 
}

void loop() {
  
     
      pinbut = digitalRead(set);
   
     if ((!pinbut && oldstat)&&((millis() - delayBounce) > 50)) 
      {
          menut = 1; 
          menus();
         delayBounce = millis();
      }
      
       oldstat = pinbut;
   
Serial.println("main menu");

delay(100);
}

void menus()
{
    
     while(menut> 0)
     {
      Serial.println(" function menus");
      
       pinbut= digitalRead(set);
 
      if ((!pinbut== LOW  && oldstat== HIGH)&&((millis() - delayBounce) > 50)) 
      {
        menut =  0;
      }
      
      oldstat = pinbut;
     }
     delayBounce = millis();
 }

Fiasgardone:
Below is the last code I made, I hope you can help me.

The code in your menus() function is almost identical to the code in loop() so I suggest you delete ALL of the contents of the menu() function and then put some code in there to display a menu.

I get the feeling that you need to clarify your own thoughts about how the program should work so I suggest you write down an English language description (or your own language, if different) of the step-by-step operation of the program with one step on each line. When you have that clear I reckon it will be straightforward to turn that into a program.

For example (referring to your code in Reply #13) it does not seem to make sense to me to detect a button push in loop() and then always set the variable menut to 1. Surely each button push should change that variable?

Also, if this was my project I would do all my button reading in loop() or in a special function for checking the button-state.

Finally (for now) if you use the Auto Format tool it will make your code much easier to read.

...R

Robin2:
The code in your menus() function is almost identical to the code in loop() so I suggest you delete ALL of the contents of the menu() function and then put some code in there to display a menu.

I get the feeling that you need to clarify your own thoughts about how the program should work so I suggest you write down an English language description (or your own language, if different) of the step-by-step operation of the program with one step on each line. When you have that clear I reckon it will be straightforward to turn that into a program.

For example (referring to your code in Reply #13) it does not seem to make sense to me to detect a button push in loop() and then always set the variable menut to 1. Surely each button push should change that variable?

Also, if this was my project I would do all my button reading in loop() or in a special function for checking the button-state.

Finally (for now) if you use the Auto Format tool it will make your code much easier to read.

...R

Hello.

Robin2
What I really want is to do a program to control a garage, and to do this control it will contain the following

1-A humidity and humidity controller DHT22.
2-a 220V heating resistor.
3-A 220V motor with gearbox to open and close a window every 6 hours.
4-A fan for circulating air.
5-A time counter DS3231.

In the program what is required to do is the following, in the main function (LOOP) I want to show the progress of the program on a 16x4 LCD, but to configure the sensors ex the rest of the peripherals wanted to create a function or more functions outside the main function for configuration of the sensors and the other peripherals, when everything is configured I would press a button to leave the configuration function and return the main function

This little program I posted is just for me to test how I should call a function to do what I want inside it and then press a button and exit the function.

This will serve for my learning for future codes if I can make the complete code

I am not very advanced, so I ask for your understanding, if anyone can help me in this code thank you.

Fiasgardone:
In the program what is required to do is the following, in the main function (LOOP) I want to show the progress of the program on a 16x4 LCD, but to configure the sensors ex the rest of the peripherals wanted to create a function or more functions outside the main function for configuration of the sensors and the other peripherals, when everything is configured I would press a button to leave the configuration function and return the main function

The code to update the LCD should also be in its own function and all the functions can be called from loop(). Have you studied the link to Planning and Implementing a Program that I gave you in Reply #10?

One thing to be careful of - don't update the LCD screen more often than necessary as doing so is slow.

...R