-1

I am new to Arduino development. I want to use millis function instead of delay because delay is blocking further execution of program.

Program description: In this code I want to control 2 solenoid valves with DS3231 RTC alarm and also with infrared remote control button pressed. But when I press one button for valve ON program does not turn valve on.

Please check this program and correct my mistake.

#include <DS3231.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include "IRremote.h"
#define LED1 2
int receiver = 6;
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'
#define VALVE1 7
#define VALVE2 12
DS3231  rtc(SDA, SCL);
Time  t;
//-------------millis timer----------------------------------
unsigned long last1 = millis();

void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  rtc.begin();
  Serial.begin(9600);
  pinMode(VALVE1, OUTPUT);
  pinMode(VALVE2, OUTPUT);
}

void loop()
{
  t = rtc.getTime();   // Get data from the DS3231
  delay(200);
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    translateIR();
    irrecv.resume(); // receive the next value
  }

  //------ALARM FOR AUTO WATERING GARDEN----
  //MORNING Routine FOR VALVE========
  if (t.hour == 16 && t.min == 15 && t.sec == 00)  //Open valve1 8AM morning
  {
    void G_valve1On();
  }

  if (t.hour == 16 && t.min == 20 && t.sec == 00)  //close valve1 8:10AM morning
  {
    void G_valve1Off();
  }


  //---------FUNCTIONS-----------------------------
  //IR COMMAND FUNCTIONS
  void translateIR()
  {
    switch (results.value)
    {
      case 0x843509F6:         //valve 1 turn on for 10minute delay
        if (millis() - last1 > 600000) //when remote button pressed valve turn on for 10min
        { G_valve1On();
          Serial.println("valve ON");
        }
        G_valve1Off();
        Serial.println("valve off");
        delay(250);
        break;
      case 0x84350AF5:                 //2nd button for 15 min delay
        G_valve2On();

        //Serial.println("valve on 15minutes...");
        //Help me to use MILLS FUNCTION.

        G_valve2Off();
        //Serial.println("valve off");
        delay(250);
        break;
    }
    delay(300);
  }
}

  //----VALVES- FUNCTION------

  void G_valve1On()
  {
    digitalWrite(VALVE1, HIGH);
    Serial.println("...turning valve1 on...");
  }
  void G_valve1Off()
  {
    digitalWrite(VALVE1, LOW);
    Serial.println("...turningvalve1 off...");
  }
  void G_valve2On()
  {
    digitalWrite(VALVE2, HIGH);
    Serial.println("...turning valve1 on...");
  }
  void G_valve2Off()
  {
    digitalWrite(VALVE2, LOW);
    Serial.println("...turningvalve1 off...");
  }

UPDATE:

Thanks for the replies. I have made some changes in the program that user ratchet freak provided below, but it is giving error.

Program:

#include <DS3231.h>
#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include "IRremote.h"
#define LED1 2
int receiver = 6;
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'
#define valve1 13
#define valve2 12
DS3231  rtc(SDA, SCL);
Time  t;

struct valve_state {
  bool on;
  unsigned long on_timestamp;
  unsigned long on_time;
}
valve_state valve1;
valve_state valve2;
void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  rtc.begin();
  Serial.begin(9600);
  pinMode(valve2, OUTPUT);
  pinMode(valve1, OUTPUT);
}

void loop() {
  t = rtc.getTime();

  //read ir
  //read rtc
  if (irrecv.decode(&results))
  {
    if (ir.value == 0x843509F6 ||                              //VALVE 1ON OFF
        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)) {
      valve1.on = true;
      valve1.on_timestamp = millis();

      valve1.on_time = 10 * 60 * 1000;
    }
    if (valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)) {
      valve1.on = false;
      digitalWrite(valve1, LOW);


      if (ir.value == 0x843509F6 ||                                      //VALVE 2 ON OFF
          (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)) {
        valve2.on = true;
        valve2.on_timestamp = millis();
        digitalWrite(valve2, HIGH);
        valve1.on_time = 10 * 20 * 1000;
      }
      if (valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)) {
        valve1.on = false;
        digitalWrite(valve2, LOW);

      }

But the Arduino IDE gives following errors:

:\Users\ABHI's\AppData\Local\Temp\arduino_2447f9e2b3111c537660c536aa9c2330\sketch_nov11a.ino:23:13: note: in expansion of macro 'valve1'

 valve_state valve1;

             ^

sketch_nov11a:12: error: expected unqualified-id before numeric constant

 #define valve2 12

                ^

C:\Users\ABHI's\AppData\Local\Temp\arduino_2447f9e2b3111c537660c536aa9c2330\sketch_nov11a.ino:24:13: note: in expansion of macro 'valve2'

 valve_state valve2;

             ^

C:\Users\ABHI's\AppData\Local\Temp\arduino_2447f9e2b3111c537660c536aa9c2330\sketch_nov11a.ino: In function 'void loop()':

sketch_nov11a:43: error: 'ir' was not declared in this scope

     if(ir.value == 0x843509F6 || 
sketch_nov11a:44: error: 'class DS3231' has no member named 'hour'

    (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){

sketch_nov11a:44: error: 'class DS3231' has no member named 'min'

        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){
                            ^
sketch_nov11a:44: error: 'class DS3231' has no member named 'sec'

        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){                                            

sketch_nov11a:45: error: request for member 'on' in '13', which is of non-class type 'int'

         valve1.on = true;

sketch_nov11a:46: error: request for member 'on_timestamp' in '13', which is of non-class type 'int'

         valve1.on_timestamp = millis();                ^

sketch_nov11a:55: error: request for member 'on_time' in '13', which is of non-class type 'int'

         valve1.on_time = 10*60*1000;

sketch_nov11a:57: error: request for member 'on' in '13', which is of non-class type 'int'

     if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){

sketch_nov11a:57: error: request for member 'on_timestamp' in '13', which is of non-class type 'int'
     if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){

sketch_nov11a:57: error: request for member 'on_time' in '13', which is of non-class type 'int'

     if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){                                                              ^

sketch_nov11a:58: error: request for member 'on' in '13', which is of non-class type 'int'

         valve1.on = false;                ^

sketch_nov11a:69: error: 'ir' was not declared in this scope

      if(ir.value == 0x843509F6 ||          ^

sketch_nov11a:70: error: 'class DS3231' has no member named 'hour'

        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){             ^

sketch_nov11a:70: error: 'class DS3231' has no member named 'min'

        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){                              ^
sketch_nov11a:70: error: 'class DS3231' has no member named 'sec'

        (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){                                                ^

sketch_nov11a:71: error: request for member 'on' in '12', which is of non-class type 'int'
         valve2.on = true;                ^

sketch_nov11a:72: error: request for member 'on_timestamp' in '12', which is of non-class type 'int'

         valve2.on_timestamp = millis();

                ^

sketch_nov11a:81: error: request for member 'on_time' in '13', which is of non-class type 'int'

         valve1.on_time = 10*20*1000;                ^

sketch_nov11a:83: error: request for member 'on' in '12', which is of non-class type 'int'

     if(valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)){
               ^

sketch_nov11a:83: error: request for member 'on_timestamp' in '12', which is of non-class type 'int'

     if(valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)){                                        ^

sketch_nov11a:83: error: request for member 'on_time' in '12', which is of non-class type 'int'

     if(valve2.on && (millis() - valve2.on_timestamp > valve2.on_time)){                                                            ^

sketch_nov11a:84: error: request for member 'on' in '13', which is of non-class type 'int'

         valve1.on = false;                ^

sketch_nov11a:97: error: expected '}' at end of input
 }

exit status 1
expected initializer before numeric constant

Can you please reconstruct complete program for me?

  • loop is not closed with } – Juraj Nov 10 '17 at 10:34
  • 1
    you have a condition which enables turning on the valve after 10 minutes from program start. and the on the next line you turn it off – Juraj Nov 10 '17 at 10:41
  • correct my mistake. which is? – dannyf Nov 10 '17 at 13:19
2

The best way to handle this kind of thing is by state machine. Each valve is its own state machine and is handled one at a time.

The state machine for the valve seems to be trigger valve on based on RTC or remote. Turn off when timeout triggers

So you handle each event based on the current state:

struct valve_state{
    bool on;
    unsigned long on_timestamp;
    unsigned long on_time;
}

valve_state valve1;
valve_state valve2;

void loop(){

    //read ir
    //read rtc

    if(ir.value == 0x843509F6 || 
       (rtc.hour == 16 && rtc.min == 15 && rtc.sec == 00)){
        valve1.on = true;
        valve1.on_timestamp = millis();
        digitalWrite(VALVE1,HIGH);
        valve1.on_time = 10*60*1000;
    }
    if(valve1.on && (millis() - valve1.on_timestamp > valve1.on_time)){
        valve1.on = false;
        digitalWrite(VALVE1,LOW);
    }


    //repeat for valve2
}
1

The code you posted doesn't compile. I fixed the missing brace and used the auto-format command of the IDE to fix the mess in indentation. I then inserted the necessary code for the two buttons.

#include <DS3231.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include "IRremote.h"
#define LED1 2
int receiver = 6;
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'
#define VALVE1 7
#define VALVE2 12
DS3231  rtc(SDA, SCL);
Time  t;
//-------------millis timer----------------------------------
unsigned long last1 = 0;
unsigned long last2 = 0;
void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  rtc.begin();
  Serial.begin(9600);
  pinMode(VALVE1, OUTPUT);
  pinMode(VALVE2, OUTPUT);
}

void loop()
{
  t = rtc.getTime();   // Get data from the DS3231
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    translateIR();
    irrecv.resume(); // receive the next value
  }

  // turn of valves if they are on for enough time
  if (last1 && millis() - last1 > 600000)
  {
    G_valve1Off();
    Serial.println("valve off");
    last1 = 0;
  }
  if (last2 && millis() - last2 > 900000)
  {
    G_valve2Off();
    last2 = 0;
  }

  //------ALARM FOR AUTO WATERING GARDEN----
  //MORNING Routine FOR VALVE========
  if (t.hour == 16 && t.min == 15 && t.sec == 00)  //Open valve1 8AM morning
  {
    void G_valve1On();
  }

  if (t.hour == 16 && t.min == 20 && t.sec == 00)  //close valve1 8:10AM morning
  {
    void G_valve1Off();
  }
}

//---------FUNCTIONS-----------------------------
//IR COMMAND FUNCTIONS
void translateIR()
{
  switch (results.value)
  {
    case 0x843509F6:         //valve 1 turn on for 10minute delay

      G_valve1On();
      Serial.println("valve ON");
      last1 = millis();
      break;


    case 0x84350AF5:                 //2nd button for 15 min delay
      G_valve2On();
      last2 = millis();
      break;
  }
  delay(300);
}



//----VALVES- FUNCTION------

void G_valve1On()
{
  digitalWrite(VALVE1, HIGH);
  Serial.println("...turning valve1 on...");
}
void G_valve1Off()
{
  digitalWrite(VALVE1, LOW);
  Serial.println("...turningvalve1 off...");
}
void G_valve2On()
{
  digitalWrite(VALVE2, HIGH);
  Serial.println("...turning valve1 on...");
}
void G_valve2Off()
{
  digitalWrite(VALVE2, LOW);
  Serial.println("...turningvalve1 off...");
}

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.