Using seconds with rtc for less than a minute timer

Hello all

uno
ds3231
relay
fork out of jeelib rtc library

I have a bit of code I need some help with, I have searched the forum but cant seem to find what I need. I need to set a time interval that includes seconds for a pump to run. For instance I need the pump to run for 15 seconds only at 10:05:00 and turn off again at 10:05:15

currently I have this

relayFlag = (now.hour()*60) + now.minute() + now.second();

if (relayFlag >= 605 && relayFlag < 620){
digitalWrite (pumpPin, LOW);
Serial.println(“Water Pump ON”);
}
else {
digitalWrite (pumpPin, HIGH);
Serial.println(“Water Pump OFF”);
}

the pump relay will come on at the start time for 15 then off. Then about a minute later back on again, continuously after every minute. I know im missing some thingcant figure out what.

Any help would be greatly received :slight_smile: :slight_smile: :slight_smile: :slight_smile:

relayFlag = (now.hour()*60) + now.minute() + now.second();

You do note minutes and second have the same impact? ;) For the value of relayFlag (which isn't a flag...) there is no difference for: 05:03:10 05:10:03

Instead of messing wih a "flag", just check hours, minutes and seconds :)

This is a problem:

relayFlag = (now.hour()*60) + now.minute() + now.second();

You are converting hours to minutes and adding minutes and seconds. You need to convert hours and minutes to seconds and then add seconds :)

Or, calculate seconds since midnight properly: hours * 3600 + minutes * 60 + seconds

The result is NOT a flag, so don't use flag in the name.

Agreed. Although I think doing all that multiplication to get a single variable to compare is just a it mehh.

I would consider:

unsigned long relayTimeFootprint = (hours << 12) || (minutes << 6) || seconds;

But I think I would just give in and use three comparisons… Just because it’s so damn clear what’s going on if you do.

septillion:
Agreed. Although I think doing all that multiplication to get a single variable to compare is just a it mehh.

I would consider:

unsigned long relayTimeFootprint = (hours << 12) || (minutes << 6) || seconds;

But I think I would just give in and use three comparisons… Just because it’s so damn clear what’s going on if you do.

I don’t know which Arduino the OP is using, but from what I understand, the Arduino UNO, at least, is more comfortable with multiplication than with bit shifts.

I am using an Uno as stated above

So this is what I have so far but I am unsure for how to layout the sum as currently this does not work

15:01 on
15:01:45 off

pumpState = (now.hour()*3600 + now.minute()*60) + now.second();

if (pumpState >= 54060 && pumpState < 54105){
digitalWrite (pumpPin, LOW);
Serial.println(“Water Pump ON”);
}
else {
digitalWrite (pumpPin, HIGH);
Serial.println(“Water Pump OFF”);
}

I don't know which Arduino the OP is using, but from what I understand, the Arduino UNO, at least, is more comfortable with multiplication than with bit shifts.

Your understanding is flawed.

So this is what I have so far but I am unsure for how to layout the sum as currently this does not work

What type does now.hour() return? If it returns an int, then 15 * 3600 will overflow an int register.

You need to cast now.hour() to unsigned long, and pumpState must also be unsigned long.

so far I keep getting errors

#include <RTClib.h>               // Real time clock
#include <DHT.h>                  // Air Temp Humid Sensor
#include <OneWire.h>              // Sensors (water temp) connected to one wire
#include <DallasTemperature.h>    // Water Temp Sensor
#include <LiquidCrystal_I2C.h>    // Lcd display 
const int lightingPin = 4;
const int bulblightingPin = 9;
const int pumpPin = 6;
RTC_DS3231 rtc;                    // Init the DS3231 using the hardware interface (Nano A4=SDA A5=SCL)
unsigned long currentTime;
unsigned long previousTime = 0;
int marker = 0;
int lampState =0;
unsigned long pumpState =0;
unsigned long hour = 0;
int pumpHour =0;
char dateBuffer [12];
                        


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Lcd Display ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
                                                                // set the LCD address to 0x3F or 0x27 depending what display using for a 16 chars 2 line display
                                                                // Set the pins on the I2C chip used for LCD connections:
                                                                // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol           

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Air Temperature & Humidity sensor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 #define DHTPIN 2             // what pin we're connected to
 #define DHTTYPE DHT22        // DHT 22  (AM2302)
 DHT dht(DHTPIN, DHTTYPE);    // Initialize DHT sensor
 int chk;
 float hum;                   //Stores humidity value
 float temp;                  //Stores temperature value

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Water Temperature sensor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 #define ONE_WIRE_BUS 7
 OneWire oneWire(ONE_WIRE_BUS);          // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
 DallasTemperature sensors(&oneWire);    // Pass our oneWire reference to Dallas Temperature.


 //########################################################################## SETUP ################################################################################################### 
void setup()
{
  Serial.begin(9600);
  rtc.begin();             // Initialize the rtc object
  lcd.begin(16,2);         // initialize the lcd for 16 chars 2 lines
  lcd.backlight();         // Turns backlight LCD on
  sensors.begin();         // water temp sensor
  dht.begin();             // temp humid sensor 
  
  pinMode (lightingPin, OUTPUT);
  digitalWrite (lightingPin, HIGH);
  pinMode (bulblightingPin, OUTPUT);
  digitalWrite (bulblightingPin, HIGH); 
  pinMode (pumpPin, OUTPUT);
  digitalWrite (pumpPin, HIGH);
   
  
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Uncomment to set the date and time ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));      // Automatic RTC DS3231 time update from computer clock while compiling
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));       // This line sets the RTC with an explicit date & time for example to set January 21, 2014 at 3am 
    
    
}

 //########################################################################## LOOP ################################################################################################### 

void loop()
{
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OUTPUT REAL TIME CLOCK ON SERIAL ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
   DateTime now = rtc.now();

   sprintf(dateBuffer,"%02u-%02u-%04u ",now.day(),now.month(),now.year());
   Serial.print(dateBuffer);
   sprintf(dateBuffer,"%02u:%02u:%02u ",now.hour(),now.minute(),now.second());
   Serial.println(dateBuffer);
 
  

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lighting RELAY ACTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 
  lampState = (now.hour()*60) + now.minute();         // Hour times it by 60 add the minutes, 18 hour cycle 5am = 300 11pm = 1380
                                                      // 12 hour cycle 6am = 360 12am = 00
                                                      // 14 hour cycle 6am = 360 2am = 1200
                                                    
 if (lampState >= 360 && lampState < 1200){
    digitalWrite (lightingPin, HIGH);
    digitalWrite (bulblightingPin, LOW);
    Serial.println("Lights ON");
 }
  else {
    digitalWrite (lightingPin, LOW);
    digitalWrite (bulblightingPin, HIGH);
    Serial.println("Lights OFF");
 }  

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Water Pump Relay Times ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  now.hour() = pumpHour;
  pumpState = (pumpHour*3600) + (now.minute()*60) + now.second();            
                                                                        
 
   if (pumpState >= 55440 && pumpState < 55485){
      digitalWrite (pumpPin, LOW);
      Serial.println("Water Pump ON");                                 
   }
   else { 
    digitalWrite (pumpPin, HIGH);
    Serial.println("Water Pump OFF");
  }

lvalue required as left operand of asignment

Wrong way around:

  now.hour() = pumpHour;

Got it thank you everyone for your input :slight_smile: :slight_smile: :slight_smile:

#include <RTClib.h>               // Real time clock
#include <DHT.h>                  // Air Temp Humid Sensor
#include <OneWire.h>              // Sensors (water temp) connected to one wire
#include <DallasTemperature.h>    // Water Temp Sensor
#include <LiquidCrystal_I2C.h>    // Lcd display 
const int lightingPin = 4;
const int bulblightingPin = 9;
const int pumpPin = 6;
RTC_DS3231 rtc;                    // Init the DS3231 using the hardware interface (Nano A4=SDA A5=SCL)
unsigned long currentTime;
unsigned long previousTime = 0;
int marker = 0;
int lampState =0;
unsigned long pumpState =0;
unsigned long pumpHour = 0;
char dateBuffer [12];
                        


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Lcd Display ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
                                                                // set the LCD address to 0x3F or 0x27 depending what display using for a 16 chars 2 line display
                                                                // Set the pins on the I2C chip used for LCD connections:
                                                                // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol           

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Air Temperature & Humidity sensor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 #define DHTPIN 2             // what pin we're connected to
 #define DHTTYPE DHT22        // DHT 22  (AM2302)
 DHT dht(DHTPIN, DHTTYPE);    // Initialize DHT sensor
 int chk;
 float hum;                   //Stores humidity value
 float temp;                  //Stores temperature value

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Water Temperature sensor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 #define ONE_WIRE_BUS 7
 OneWire oneWire(ONE_WIRE_BUS);          // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
 DallasTemperature sensors(&oneWire);    // Pass our oneWire reference to Dallas Temperature.


 //########################################################################## SETUP ################################################################################################### 
void setup()
{
  Serial.begin(9600);
  rtc.begin();             // Initialize the rtc object
  lcd.begin(16,2);         // initialize the lcd for 16 chars 2 lines
  lcd.backlight();         // Turns backlight LCD on
  sensors.begin();         // water temp sensor
  dht.begin();             // temp humid sensor 
  
  pinMode (lightingPin, OUTPUT);
  digitalWrite (lightingPin, HIGH);
  pinMode (bulblightingPin, OUTPUT);
  digitalWrite (bulblightingPin, HIGH); 
  pinMode (pumpPin, OUTPUT);
  digitalWrite (pumpPin, HIGH);
   
  
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Uncomment to set the date and time ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));      // Automatic RTC DS3231 time update from computer clock while compiling
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));       // This line sets the RTC with an explicit date & time for example to set January 21, 2014 at 3am 
    
    
}

 //########################################################################## LOOP ################################################################################################### 

void loop()
{
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OUTPUT REAL TIME CLOCK ON SERIAL ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
   DateTime now = rtc.now();

   sprintf(dateBuffer,"%02u-%02u-%04u ",now.day(),now.month(),now.year());
   Serial.print(dateBuffer);
   sprintf(dateBuffer,"%02u:%02u:%02u ",now.hour(),now.minute(),now.second());
   Serial.println(dateBuffer);
 
  

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lighting RELAY ACTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 
  lampState = (now.hour()*60) + now.minute();         // Hour times it by 60 add the minutes, 18 hour cycle 5am = 300 11pm = 1380
                                                      // 12 hour cycle 6am = 360 12am = 00
                                                      // 14 hour cycle 6am = 360 2am = 1200
                                                    
 if (lampState >= 360 && lampState < 1200){
    digitalWrite (lightingPin, HIGH);
    digitalWrite (bulblightingPin, LOW);
    Serial.println("Lights ON");
 }
  else {
    digitalWrite (lightingPin, LOW);
    digitalWrite (bulblightingPin, HIGH);
    Serial.println("Lights OFF");
 }  

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Water Pump Relay Times ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  pumpHour = now.hour();
  pumpState = (pumpHour*3600) + (now.minute()*60) + now.second();            
                                                                        
 
   if (pumpState >= 57120 && pumpState < 57165){
      digitalWrite (pumpPin, LOW);
      Serial.println("Water Pump ON");                                 
   }
   else { 
    digitalWrite (pumpPin, HIGH);
    Serial.println("Water Pump OFF");
  }

Jonathanw82:

   if (pumpState >= 57120 && pumpState < 57165){

digitalWrite (pumpPin, LOW);
      Serial.println(“Water Pump ON”);                               
  }
  else {
    digitalWrite (pumpPin, HIGH);
    Serial.println(“Water Pump OFF”);
  }

57165 minus 57120 gives 45.
So, you want your pump on for forty-five seconds?

Also, it looks like the times you chose to turn it on and off are, respectively, 15:52:00 and 15:52:45.

By the way, if you want to convert hours to seconds in code, I suggest multiplying by 3600L rather than 3600. The L at the end means "treat this number as a long".

yes I only need to pump to run for a short period of time I will keep the L in mind though. it is working now so thank you all for your time and effort :) :)

@septillion

I will have a look at this aswell, i cant seem to get my head around how i can get it to start and stop something? could i have an example im unsure of the structure

Agreed. Although I think doing all that multiplication to get a single variable to compare is just a it mehh.

I would consider:
Code: [Select]
unsigned long relayTimeFootprint = (hours << 12) || (minutes << 6) || seconds;

But I think I would just give in and use three comparisons… Just because it’s so damn clear what’s going on if you do.

if((hours == OnHour) && (minutes == OnMinutes) && (seconds == OnSeconds)){
  digitalWrite(PumpPin, HIGH);
}

if((hours == OffHour) && (minutes == OffMinutes) && (seconds == OffSeconds)){
  digitalWrite(PumpPin, LOW);
}

Or if it’s important that the start / stop command is only excecuted once (because now it’s called for a full second aka thousands of times (does NOT matter for a simple digitalWrite()))

bool motorOn = false;

if((hours == OnHour) && (minutes == OnMinutes) && (seconds == OnSeconds) && !motorOn){
  motorOn = true;
  turnMotorOn(); //whatever that may be
}

if((hours == OffHour) && (minutes == OffMinutes) && (seconds == OffSeconds) && motorOn){
  motorOn = false;
  turnMotorOff(); //whatever that may be
}