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.