2

My target is to make an Arduino system that is able to change modes with different delays by pushing a button. For example, if I pressed the button, it will go into mode 1 with loop 1 that has a 30s delay. If I pressed it one more time, it will go to mode 2 with with loop 2 that has a 1 min delay, etc. The important thing is that mode 1 should be breaked when the push button pressed.

The code below solved part of the problem. However, LEDs are only constant ON, they are not blinking for a certain time then it turned either on-off within the mode when the push button pressed.

int b =3;int rl= 5;int gl=6;
int yl=7; int s=0; int o=0;
 int bp =0;

void setup() {
  // put your setup code here, to run once:
pinMode(b,INPUT);
pinMode(rl,OUTPUT);
pinMode(gl,OUTPUT);
pinMode(yl,OUTPUT);

 digitalWrite(rl,LOW);
digitalWrite(gl,LOW);
digitalWrite(yl,LOW);
}

void loop() {
  // put your main code here, to run repeatedly:

bp=digitalRead(b);
if (bp==1){
  delay(50);
  bp=digitalRead(b);
  if (bp==0){
    s=o+1;}}
    else{
      delay(100);}
      switch(s){
        case 1:
        digitalWrite(rl,HIGH);
digitalWrite(gl,LOW);
digitalWrite(yl,LOW);
o=s;
break;

case 2 :
digitalWrite(rl,LOW);
digitalWrite(gl,HIGH);
digitalWrite(yl,LOW);
o=s;
break;

case 3:

digitalWrite(rl,LOW);
digitalWrite(gl,LOW);
digitalWrite(yl,HIGH);
o=s;
break;
default:

digitalWrite(rl,LOW);
digitalWrite(gl,LOW);
digitalWrite(yl,LOW);
o=0;
break;}}

Connection diagram

S1 is responsible to activate D12 to be constant ON (when it’s pressed once) which lead UNO2 to be powered then blink the right LED ON (1min) OFF(4Hr), (pressing it twice should turn D12 OFF (optional)). The same thing with S2, when it’s pressed once it should first disable D12 and activate D11 instead, powering UNO3, blinking the left LED ON(30S), OFF (4Hr).

In addition, blinking on() off() repeatedly is needed (unless action break/occur, ex: pressing S1 or S2).

About S1 and S2. The LED on D12 will flash ON for 1 minute then turn off for 4 hours. After the 4 hours, the LED on D12 will flash ON again for 1 min then turn off for 4 hours again & again...as an infinite loop. With S2 The LED on D11 will flash ON for 30 seconds then turn off for 4 hours. After the 4 hours, the LED On D11 will flash ON again for 30 s then turn off for 4 hours again and again as an infinite loop.

  • 1
    I got tired with no result>< what does this even mean? What have you tried so far? Have you written ANY code at all? – Jaromanda X Jan 29 at 9:54
  • state machine triggered by interrputs – MichaelT Jan 29 at 14:07
0

In response to your comment on Matej's answer @Ibrahim.M: "I wish I can abbreviate it with only one UNO that able to do the same task by using programming.". You can do this with just one Uno.

I would start by detecting the button presses and debouncing them. This is easy to do using the Bounce2 library. You can use the button presses to start timers which will turn the LEDs On and Off.

EDIT

To make an LED flash on and off, and to keep time, you can use the millis() function. I started with the BlinkWithoutDelay tutorial, and came up with the following sketch. It only has one timer / LED flasher, but there is enough information in the sketch to figure out how to make the second timer / LED flasher.

#include <Bounce2.h>

byte led1State = LOW;
byte timer1Active = 0;
const byte led1Pin = LED_BUILTIN;
const byte buttonPin1 = 6;
const byte buttonPin2 = 7;
unsigned int timer1Counter = 0;
const unsigned long debouncerInterval = 50;
const unsigned long oneSecond = 1000;
unsigned long previousMillis = 0;

Bounce debouncer = Bounce();
Bounce debouncer2 = Bounce();

void setup(){
  Serial.begin(9600);
  debouncer.attach(buttonPin1, INPUT_PULLUP);
  debouncer.interval(debouncerInterval);
  debouncer2.attach(buttonPin2, INPUT_PULLUP);
  debouncer2.interval(debouncerInterval);
  pinMode(led1Pin, OUTPUT);
}

void loop(){

  unsigned long currentMillis = millis();

  // 4 hour, 30 second timer.
  if((currentMillis - previousMillis >= oneSecond) && (timer1Active == 1)){
    previousMillis = currentMillis;
    timer1Counter++;
    if(timer1Counter < 31){
      //if(led1State == LOW){
        led1State = HIGH;
      //}
      //else{
        //led1State = LOW;
      //}
      digitalWrite(led1Pin, led1State);
    }
    else if(timer1Counter == 31){
      digitalWrite(led1Pin, LOW);
    }

    // 60 sec X 60 min X 4 hours + 30 seconds.
    if(timer1Counter > 14430){
      timer1Counter = 0;
    }
  }

  // Button 1
  if(debouncer.update()){
    if(debouncer.read() == 0){
      Serial.println("Start 30 second ON, 4 hour OFF timer.");
      timer1Active = 1;
      timer1Counter = 0;
    }
  }

  // Button 2
  if(debouncer2.update()){
    if(debouncer2.read() == 0){
      Serial.println("Start 1 minute ON, 4 hour OFF timer.");
      timer1Active = 0;
      digitalWrite(led1Pin, LOW);
    }
  }

}

Based on this part of your last comment "I’ve a trick! ‘const unsigned long oneSecond = 1000;’ should be edited to ‘const unsigned long oneSecond = 10;’ this make the led be as a constant ON.", it sounds like you want the LED to remain ON constantly for the 30 or 60 seconds. I have "commented out" 5 lines of the above sketch that will make this happen.

  • 1
    Matej and VE7JRO you are a great persons, thank you so much. – Ibrahim.M Feb 12 at 9:53
0

Do not use delay but millis(). Example:

#define BTN 2
#define MAX_MODE 1   //2 modes

const unsigned int times[] = {1000, 2000};

unsigned int time = times[0];

unsigned long btn_tm = 0;
unsigned long l_time = 0;

byte mode = 0;



void setup(){
  Serial.begin(9600);
  pinMode(BTN, INPUT);
}

void loop(){
  if(digitalRead(BTN) == 1 && millis() - btn_tm > 200){
    btn_tm = millis();
    mode ++
    if(mode > MAX_MODE) mode = 0;
    time = times[mode];
 } 
  if(millis() - l_time >= time){
    l_time = millis();
    if(mode == 0) Serial.println("mode 0");
    if(mode == 1) Serial.println("mode 1");
 } 
}

Read it and try it.

  • Thank you Matej. The code has an error related to this part: ' if(mode > MAX_MODES) mode = 0; ' , kindly, how can I add LEDs as an output for each mode pls? – Ibrahim.M Jan 30 at 7:40
  • Is it possible to make the code inside the link take place each case mentioned in my topic code? where then each case will has its own time [arduino.cc/en/tutorial/BlinkWithoutDelay] – Ibrahim.M Jan 30 at 8:30
  • @Ibrahim.M I fixed this error, it was wrong name of variable. If you want to use code from the link, remove this part from code if(millis() - l_time >= time){ l_time = millis(); if(mode == 0) Serial.println("mode 0"); if(mode == 1) Serial.println("mode 1"); } and instead of it, put inside if(mode == 0){ } code which is in the loop() from your link. – Matej Jan 30 at 8:38
  • @Ibrahim.M And for your first comment, simply put pinMode() to the setup() above setup put bool state = 0; and into a if(mode == 0){ } put digitalWrite(LED, state); state = !state; – Matej Jan 30 at 8:53
  • Thank you Matej, I appreciate it. Unfortunately, my problem is still not solved. I assume that uno’s IC cannot do what I want ( ex; yellow button activates pin9 1min each 6 hr wherase blue button activate pin10 30 sec each 6hr ). – Ibrahim.M Feb 10 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.