Adding 2 buttons for increase or decrease value in for loop

Hi. I have a big problem and I need help. i'm using relay with 100 time minimum on and off. now i want to use and add 2 buttons for increase or decrease value in for loop

my code

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#define RELAY1  10    
//----------------------------------------------------------

void setup()
           {
 lcd.init();                      // initialize the lcd 
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0,0);

//-------------------------------------


delay(900);
           Serial.begin(19200);

         
            for (int count = 0; count < 100; count++)  // cycle count 100
            
           {
            
            Serial.println(count);
            lcd.clear();
            lcd.print(count);
            pinMode(RELAY1, OUTPUT);         
       

            
           digitalWrite(RELAY1,HIGH);          // Turns OFF Relay 1
      
           delay(1000);                        // Pause 1 seconds
        
           digitalWrite(RELAY1,LOW);           // Turns ON Relay 1
        
           delay(1000);                       // Pause 1 seconds 
          }    
          }

 void loop()
                    
          {
             
  
           }


Have you wanted to mean that you will have two buttons -- one to increase the value of the count variable of the for() loop and the other button will decrease the value of the count variable?

Solution Hints: You may adjust the value of count in the background through interrupt process.

Do you want to increase/decrease the DELAY or the COUNT?

Hello deppen_s

I only have one small question for my understanding:
What is this programme used for in the real world?

You need to make your code non blocking (see examples of non blocking code or blink without delay).
You need to replace delay with timers. Once you have done that you can simply add a button to a digital input and monitor that.
Forget about the interrupts suggested above. That will solve your current problem, but not the next...
Interrupts are for things that cannot wait (tachometers in motors).

https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/8

I think you could enter the count using serial monitor. So that you could enter a value each time

i want to use this for testing magnetic coils. and "count" must start from 100. 2 buttons for increase or decrease value of "count" loop

for serial input, i need computer and that i dont want to use

How about a potentiometer, could you use that.

There are many ways to solve a problem with relative merits and demerits. It is no good that you reject others' proposals destroying the potential desire of the OP to test them. Let there be all possible solutions and make the Forum/thread more resourceful.

1 Like

i'm new to this . i dont know how to do this
i got this code from chatgpt but not working as loop. in this code when count hit 100 , it trigger relay . there are no "for" loop in this code

#include <Wire.h>  // Include the Wire library for I2C communication
#include <LiquidCrystal_I2C.h>  // Include the LiquidCrystal_I2C library for I2C display

const int relayPin = 8;  // Pin connected to the relay module
const int buttonIncPin = 2;  // Pin connected to the button for increasing the value
const int buttonDecPin = 3;  // Pin connected to the button for decreasing the value

int value = 0;  // Initial value

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Initialize the I2C display with the appropriate address and dimensions

void setup() {
  pinMode(relayPin, OUTPUT);  // Set the relay pin as output
  pinMode(buttonIncPin, INPUT_PULLUP);  // Set the button pins as input with internal pull-up resistors
  pinMode(buttonDecPin, INPUT_PULLUP);
  
  lcd.begin(16, 2);  // Initialize the I2C display
  lcd.backlight();  // Turn on the backlight
  
  lcd.print("Value:");  // Display initial text on the first line of the display
  updateDisplay();  // Update the display with the current value
}

void loop() {
  if (digitalRead(buttonIncPin) == LOW) {  // Check if the increase button is pressed
    value++;  // Increment the value
    updateDisplay();  // Update the display with the new value
    delay(200);  // Debounce delay
  }
  
  if (digitalRead(buttonDecPin) == LOW) {  // Check if the decrease button is pressed
    value--;  // Decrement the value
    updateDisplay();  // Update the display with the new value
    delay(200);  // Debounce delay
  }
  
  // Check if the value reaches 100
  if (value >= 100) {
    value = 100;  // Limit the value to 100
    digitalWrite(relayPin, HIGH);  // Turn on the relay
  } else {
    digitalWrite(relayPin, LOW);  // Turn off the relay
  }
}

void updateDisplay() {
  lcd.setCursor(7, 0);  // Set the cursor position to the second character of the first line
  lcd.print("   ");  // Clear the previous value
  lcd.setCursor(7, 0);  // Set the cursor position again
  lcd.print(value);  // Print the new value
}

" The loop() function then checks if the value reaches 100. If it does, the value is limited to 100 and the relay is turned on. Otherwise, the relay is turned off."

My standard advice:

Keep asking the robot until he/she/it gives you the correct result you expect.

One answer could probably be 42.

1 Like

So, what does this code do?
How is that different from what you want?
Did chatGPT include a wiring schematic?

This is a forum to get help. You are supposed to do the work. Or at least show you tried... asking chatGPT for a solution is not sufficient...

Here's something from somebody smarter than a chatbot. I'll explain a little as I go.

First we move all the stuff in the for loop to the loop function. We're going to let that be our loop. We're going to also have to get rid of the delay calls. delay is cool in example code where you're just demonstrating what a function does, but in the real world it causes code to be non-responsive. You can't read buttons while in a delay state.

So at the top we add a few variables to help up track what's going on. I've tried to give them names that explain their function.

byte relayState = LOW;
unsigned long lastSwitchTime = 0;
unsigned long switchingInterval = 1000;
int count = 100;

I also added pins for the up and down buttons. Change these to suit your setup

const int upButton = 2;
const int downButton = 3;

Next we have setup and that's just going to setup our pins and Serial and the lcd.

void setup() {
  lcd.init();  // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);

  //-------------------------------------


  delay(900);
  Serial.begin(19200);
  pinMode(RELAY1, OUTPUT);
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
}

And lastly we have loop and I'll break it down a little.

We start by asking if the count variable is greater than 0. If it is then we have another if statement that asks if it has been longer than 1000ms since the last switching. If it has then we have another if statement that checks to see the current state of the relay, if we are at the start or end of a cycle. At the end of all this we call digitalWrite with the state we determine and set the last switched time so we can check next time. Then after all of those if statements are closed out we have some code to read the buttons.

Notice how much easier it is to read this code with the if statement blocks lines up. You can use the auto-format tool in the IDE and it will do this for you. It makes it so much easier to follow your code.

Here's the whole thing. It's untested as I don't have your hardware but it should be pretty close. I'm hoping you'll take the time to understand it. It's really pretty simple.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#define RELAY1 10
const int upButton = 2;
const int downButton = 3;
//----------------------------------------------------------


byte relayState = LOW;
unsigned long lastSwitchTime = 0;
unsigned long switchingInterval = 1000;
int count = 100;


void setup() {
  lcd.init();  // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);

  //-------------------------------------


  delay(900);
  Serial.begin(19200);
  pinMode(RELAY1, OUTPUT);
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
}

void loop() {
  unsigned long currentTime = millis();
  if (count > 0) {
    if (currentTime - lastSwitchTime >= switchingInterval) {
      if (relayState == LOW) {
        Serial.println(count);
        lcd.clear();
        lcd.print(count);
        relayState = HIGH;
      } else {
        relayState = LOW;
        count--;
      }
      digitalWrite(RELAY1, relayState);
      lastSwitchTime = currentTime;
    }
  }
  if(digitalRead(upButton) == LOW){
    count++;
  }
  if(digitalRead(downButton) == LOW){
    count--;
  }
}

i want to change count value , increase or decrease by buttons. program shout wait for 2-3 sec for input . default value of count is 100 . if i want change count value then i have to press button in 2-3 sec else this program will trigger relay off/on 100 times.

1. Build the following setup of Fig-1.
led2Sw2IncrDcr
Figure-1:

2. Upload the following sketch in Arduino UNO.
The program gives the user an adjustable time slot during which he/she will enter two values of opposite polarities using INCR and DECR buttons. The counts will modulate the value of the variable named defaultCount; as a result, the relay1 of Fig-1 will blink for as many times as the defaultCount is.

#include <Debounce.h>
#define INCR 2
#define DECR 3

Debounce Button1(INCR);
Debounce Button2(DECR);

#define relayL 13
byte defaultCount = 10;
unsigned long prMillis = 0;
byte decrCount = 0;
byte incrCount = 0;
byte i = 0;

byte p, m;

void setup()
{
  Serial.begin(9600);
  pinMode(INCR, INPUT_PULLUP);
  pinMode(DECR, INPUT_PULLUP);
  pinMode(relayL, OUTPUT);
}

void loop()
{
  Serial.println("3-sec Counting....! Press INCR or DECR Button");
  while (millis() - prMillis < 3000) //3-sec time slot
  {
    incrCount = Button1.count(); //times INCR buton is pressed
    decrCount = Button2.count(); //times DECR button is pressed
  }
  Serial.println("=======================================");
  Serial.println("3-sec is over.");
  Serial.print("IncrCount: "); Serial.println(incrCount);
  Serial.print("DecrCount: "); Serial.println(decrCount);
  //--------------------------------------
  relayOnOff(incrCount, decrCount);
  prMillis = millis();
}

void relayOnOff(byte plus, byte minus )
{
  p = plus;
  m = minus;

  if ((defaultCount + p - m) > 10)
  {
    p = 0;
    m = 0;
    blink();
  }
  else
  {
    blink();
  }
}

void blink()
{
  for (i = 0; i < (defaultCount + p - m) ; i++)
  {
    digitalWrite(relayL, HIGH);
    delay(500);
    digitalWrite(relayL, LOW);
    delay(500);
  }
  Serial.print("RelayL Blinked for: "); Serial.print(i); Serial.println(" times");
  //Button1.resetCount();
  //Button2.resetCount();
}

3. Open the Serial Monitor at Bd = 9600.
4. Follow the message of the Serial Monitor and accordingly operate the buttons. Check that the LED (relayL) blinks correctly depending on how many times INCR or DECR button has been pressed.

Output:

3-sec is over.
IncrCount: 6
DecrCount: 7
RelayL Blinked for: 9 times
3-sec Counting...! Press INCR or DECR Button
=================================================

Can you please explain why you have a function with arguments that sets those values to global variables???

Why the blink with delay?

I always follow simple philosophy -- make it work and then improve it slowly.

I did in my sketch whatever I needed to make it work the way I (the OP) had wanted. Now, I am ready to accept criticism for its improvements.

The values of plus and minus are passed to blink() function via global variables p and m. In addition, those variables might be (if desired) cleared using resetCount() at the end of blink() function.

This is to remain inline with OP's requirements.

#include <Debounce.h>
#define INCR 2
#define DECR 3

Debounce Button1(INCR);
Debounce Button2(DECR);

#define relayL 13
byte defaultCount = 10;
unsigned long prMillis = 0;
byte decrCount = 0;
byte incrCount = 0;
byte i = 0;

byte p, m;

void setup()
{
  Serial.begin(9600);
  pinMode(INCR, INPUT_PULLUP);
  pinMode(DECR, INPUT_PULLUP);
  pinMode(relayL, OUTPUT);
}

void loop()
{
  Serial.println("3-sec Counting....! Press INCR or DECR Button");
  while (millis() - prMillis < 3000) //3-sec time slot
  {
    incrCount = Button1.count(); //times INCR buton is pressed
    decrCount = Button2.count(); //times DECR button is pressed
  }
  Serial.println("=======================================");
  Serial.println("3-sec is over.");
  Serial.print("IncrCount: "); Serial.println(incrCount);
  Serial.print("DecrCount: "); Serial.println(decrCount);
  //--------------------------------------
  relayOnOff(incrCount, decrCount);
  prMillis = millis();
}

void relayOnOff(byte plus, byte minus )
{
  p = plus;
  m = minus;

  if ((defaultCount + p - m) > 10)
  {
    p = 0;
    m = 0;
    blink();
  }
  else
  {
    blink();
  }
}

void blink()
{
  for (i = 0; i < (defaultCount + p - m) ; i++)
  {
    digitalWrite(relayL, HIGH);
    delay(500);
    digitalWrite(relayL, LOW);
    delay(500);
  }
  Serial.print("RelayL Blinked for: "); Serial.print(i); Serial.println(" times");
  //Button1.resetCount();
  //Button2.resetCount();
}

there are some small issue with this program
1- after powering board relay/led blinks 5-6 times .
2. while press button program should wait till then -" 3-sec is over."
3 program is running in loop, it must be stop after finishing loop
4 INCR function is not working
```
10-sec is over.
IncrCount: 12
DecrCount: 0
0123456789RelayL Blinked for: 10 times
3-sec Counting....! Press INCR or DECR Button

10-sec is over.
IncrCount: 4
DecrCount: 0
0123456789RelayL Blinked for: 10 times
3-sec Counting....! Press INCR or DECR Button