Relay doesn't start

I'm building an automatic plant watering system, but it'll be timed. If the user selects timer-based, it will then input the time when the relay will open. For example, if the user sets it to 2 hours, it will open the relay for 5 seconds every 2 hours and then restart. But I'm not sure why it's not starting. I'm hoping you can assist me. Thank you very much!

This is the code.

#include <millisDelay.h>
// millisDelay is in the SafeString library, install from the Arduino Library manager
// see millisDelay tutorial  https://www.forward.com.au/pfod/ArduinoProgramming/TimingDelaysInArduino.html
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h> 

LiquidCrystal_I2C lcd(0x27, 20, 4);

//keypad
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

int setupHours = 0;     // How many hours will count down when started
int setupMinutes = 0;   // How many minutes will count down when started
int setupSeconds = 0;   // How many seconds will count down when started

int counter = 7;

String hrs; 
String mins;
String secs;


int sett = 0; 
int switchh = 0; // for opening relay

char keys[ROWS][COLS]=
{
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad

millisDelay outHighDelay;
const unsigned long relay = 4000;

millisDelay outLowDelay;

const unsigned long All_InSeconds = setupHours * 3600ul + setupMinutes * 60ul + setupSeconds;
const unsigned long All_InMilliSeconds = All_InSeconds * 1000ul;

const int outPin = 12;

// for border
byte verticalLine[8] = {B00100,B00100,B00100,B00100,
                        B00100,B00100,B00100,B00100};  

byte char2[8] = {B00000,B00000,B00000,B11100,
                 B00100,B00100,B00100,B00100};

byte char1[8] = {0b00000,0b00000,0b00000,0b00111,
                0b00100,0b00100,0b00100,0b00100};

byte char3[8] = {0b00100,0b00100,0b00100,0b00111,
                0b00000,0b00000,0b00000,0b00000};

byte char4[8] = {0b00100,0b00100,0b00100,0b11100,
                 0b00000,0b00000,0b00000,0b00000};
                 
void setup() {
  Serial.begin(9600);
  
  pinMode(12, OUTPUT);
  digitalWrite(outPin, LOW);

  //LCD BACKLIGHT
  lcd.init();
  lcd.backlight();

  //START
  lcd.clear();


}

void loop() {

  mainMenu();

 if(switchh == 1){
     if (outHighDelay.justFinished()) {
    digitalWrite(outPin, LOW);
    outLowDelay.start(All_InMilliSeconds);
    }
    if (outLowDelay.justFinished()) {
      digitalWrite(outPin, HIGH);
      outHighDelay.start(relay);
    }
  }

}

void mainMenu(){
  

  printMenu( F("----MAIN MENU-----"), F(" 1 Sensor Based"), F(" 2 Timer Based"), F("- 3 Back         -"));
  
  boolean ch = true;
  while(ch){
    char key = customKeypad.getKey();
    
    if(key){
      switch(key){
        case '1': 
          ch = false;
         
        break;
 
        case '2': 
          ch = false;
          hours();
        break;
        
        case '3': //back
          ch = false;
          
        break;     
      }
    }
  }
}

void hours(){

  boolean ch = true;
  
  printTime(F("Set Timer HH:"));

  while(ch){ 
    char key = customKeypad.getKey();
    
    if(key){
      Serial.println(key);
      counter = counter + 1; 
      lcd.setCursor(counter, 2);
      lcd.print(key);
    }

    if (key == '1'){ hrs = hrs + 1;}
  
    if (key == '2'){ hrs = hrs + 2;}
    
    if (key == '3'){ hrs = hrs + 3;}
  
    if (key == '4'){ hrs = hrs + 4;}
  
    if (key == '5'){ hrs = hrs + 5;}
  
    if (key == '6'){ hrs = hrs + 6;}
  
    if (key == '7'){ hrs = hrs + 7;}

    if (key == '8'){ hrs = hrs + 8;}
  
    if (key == '9'){ hrs = hrs + 9;}
               
    if (key == '0'){ hrs = hrs + 0;}

    if (key == '#'){ clearTimer();}

    if (key == '*'){

      setupHours = hrs.toInt(); // convert from string to int
      Serial.print(setupHours);
      printTime(F("   HOURS:"));
      lcd.setCursor(8, 2);
      lcd.print(setupHours);
      hrs = "";
      delay(2000);
      counter = 7; 
      sett = 1; // to mins
      while(sett = 1){ForMins();}
      }

    if (key == 'B'){
      mainMenu();
    }
  }
}

void ForMins(){

  boolean ch = true;
  
  printTime(F("Set Timer MM:"));

  while(ch){ 
    char key = customKeypad.getKey();
    
    if(key){
      Serial.println(key);
      counter = counter + 1; 
      lcd.setCursor(counter, 2);
      lcd.print(key);
    }

    if (key == '1'){ mins = mins + 1;}
  
    if (key == '2'){ mins = mins + 2;}
    
    if (key == '3'){ mins = mins + 3;}
  
    if (key == '4'){ mins = mins + 4;}
  
    if (key == '5'){ mins = mins + 5;}
  
    if (key == '6'){ mins = mins + 6;}
  
    if (key == '7'){ mins = mins + 7;}

    if (key == '8'){ mins = mins + 8;}
  
    if (key == '9'){ mins = mins + 9;}
               
    if (key == '0'){ mins = mins + 0;}

    if (key == '#'){ clearTimer();}

    if (key == '*'){

      setupMinutes = mins.toInt();
      Serial.print(setupMinutes);
      printTime(F("  MINUTES:"));
      lcd.setCursor(8, 2);
      lcd.print(setupMinutes);
      mins = "";
      delay(2000);
      counter = 7;
      sett = 2;
      while(sett = 2){ForSecs();}
      }

    if (key == 'B'){
      mainMenu();
    }
  }
}

void ForSecs(){

  boolean ch = true;
  
  printTime(F("Set Timer SS:"));

  while(ch){ 
    char key = customKeypad.getKey();
    
    if(key){
      Serial.println(key);
      counter = counter + 1; 
      lcd.setCursor(counter, 2);
      lcd.print(key);
    }

    if (key == '1'){ secs = secs + 1;}
  
    if (key == '2'){ secs = secs + 2;}
    
    if (key == '3'){ secs = secs + 3;}
  
    if (key == '4'){ secs = secs + 4;}
  
    if (key == '5'){ secs = secs + 5;}
  
    if (key == '6'){ secs = secs + 6;}
  
    if (key == '7'){ secs = secs + 7;}

    if (key == '8'){ secs = secs + 8;}
  
    if (key == '9'){ secs = secs + 9;}
               
    if (key == '0'){ secs = secs + 0;}

    if (key == '#'){ clearTimer();}

    if (key == '*'){

      setupSeconds = secs.toInt();
      Serial.print(setupSeconds);
      printTime(F("  SECONDS:"));
      lcd.setCursor(8, 2);
      lcd.print(setupSeconds);
      secs = "";
      delay(2000);
      counter = 7;
      sett = 0;
      printTime(F("  TIME SET:"));
      lcd.setCursor(5, 2);
      
      String overall;
      overall = String(setupHours) + ":" + String(setupMinutes) + ":" + String(setupSeconds);
     const unsigned long All_InSeconds = setupHours * 3600ul + setupMinutes * 60ul + setupSeconds;
     const unsigned long All_InMilliSeconds = All_InSeconds * 1000ul;

      lcd.setCursor(5, 2);
      lcd.print(overall);
      delay(200);
      outHighDelay.start(relay); 
      switchh = 1; 
      }

    if (key == 'B'){
      mainMenu();
    }
  }
}

You will have to rephrase your discussion. A relay does not usually "open" to make short term electrical contacts. If doing that, the relay would have to waste power for a long time being pulled in and closing the contacts. Perhaps that is the reason your project is not working as you want.

The most important advice is:

narrowing down the problem through reducing the number of things that could cause the not-functioning.

I have never used the millisDelay-library.
I coded all my timings based on a short function.

So as a general advise: I guess the library has some examples in an examples subfolder
I guess there well be some kind of on/off-"blinking"-sketch

Take this example code adjust only the IO-pin to your hardware and test your hardware with this example code.

or use the most simplest code you can think of that does nothing more than switching the IO-pin on/off once every two seconds. I mean the IO-pin that is connected to your relay

If this works you know: hardware is OK.

For checking if your timer-logic works as expected add serial debug-output to your code that makes visible which lines of code get executed.

Your code includes inputting the timing with a keypad.
I don't have such a keypad laying around wired to an arduino

Another thing in developping code is to add one thing at a time then test.

Did you test if the number that is stored into your variable "All_InMilliSeconds" is correct?
Did you print the value of All_InMilliSeconds to the serial monitor and check it?

Code for testing your relay on io-pin 12

// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long

const int outPin = 12;


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  pinMode(outPin,OUTPUT);
}


void loop() {

  if ( TimePeriodIsOver(MyTestTimer,2000) ) {
    digitalWrite(outPin, !digitalRead(outPin) );
    Serial.print("IO-pin No ");
    Serial.print(outPin);
    Serial.print(" set to to state ");
    Serial.println( digitalRead(outPin) );    
  }  

}

best regards Stefan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.