Help with timer code

Hey all

I am doing a project that uses a touch screen controller and I am trying to set up dosing pumps.

I am having difficulty using the RTC time to start the motors at a set time.

I have the following code

if ( myTFT.LatchCircle_Draw(88,85,11,8) &&  now.hour() == 15 && now.minute() == 30 ) 
 Dosing1On();

in my loop function and the following function setup

void Dosing1On(){
  DateTime now = RTC.now();   
 
  // Display the current time
  Serial.print("Current time: ");
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  Serial.print(" TRUE");
Serial.println(" ");
Serial.println(" MP1");
analogWrite(motorPin1, 255);
delay(Pump1dose/2*EEPROM.read(Pump1duration)); // set how long you want the motor to run... 1000 = aprox 1ml
analogWrite(motorPin1, 0);
return;
}

however the timer never seems to actually come on.

Does it look more or less correctly setup?

The problem may be with the TFT extension library I am using to create the LatchCircle

now.hour and now.minute only exist inside of the curly-brackets of the Dosing1On function. The rest of the code/sketch is not aware of it. If you need to use the “now” instance of the DateTime class then you need to declare it globally earlier in your sketch. Get it out of Dosing1On. It is improper anyway to declare variables inside of the loop code.

[EDIT] Didn’t this give compiler errors? It seems this should have generated them, I think.

No it compiles fine. It does however give me compiler errors if I don’t have it declared there as it does not recognize now.hour etc.

I will declare it globally and see what happens and remove it.

you are correct. to test I removed everything except the call to the dosing function and took out my equation for the delay and still got nothing so I have to debug my timer code a bit.

I am not using the RTC time correctly.

I have this in the void loop

DateTime now = RTC.now();
  Hours = now.hour();
  Minutes = now.minute();
  Seconds = now.second();
  Day = now.day();
  Month = now.month();
  Year = now.year();
  Weekday = now.dayOfWeek();

Is the correct usage to go

 if (Hours == 14 && Minutes == 34 ) 
 Dosing1On();

So at 14:34 it calls the Dosing1On function?

Is the correct usage to go

 if (Hours == 14 && Minutes == 34 ) 

Dosing1On();



So at 14:34 it calls the Dosing1On function?
You seem to have forgotten the braces{} to tell what happens when the if() is true.
if (Hours == 14 && Minutes == 34 ) {
  Dosing1On();
}

http://arduino.cc/en/Reference/If

No1Daemon:
I have this in the void loop

DateTime now = RTC.now();

Hours = now.hour();
Minutes = now.minute();
Seconds = now.second();
Day = now.day();
Month = now.month();
Year = now.year();
Weekday = now.dayOfWeek();



Is the correct usage to go


if (Hours == 14 && Minutes == 34 )
Dosing1On();



So at 14:34 it calls the Dosing1On function?

Impossible to tell. Your selection of the code shown does not show how or where Hours,Minutes,Seconds,Day,Month,Year and Weekday is declared. If Hours and Minutes are declared globally then it should work. If the instance now is declared outside of, and before, loop then it should be adressable by all functions in the sketch.

Also, I would force the logic operator priority by bounding-in the the logic statements with round brackets. ( (Hours == 14) && (Minutes == 34) ) This statement is reasonable simple so should work. But more complex ones might might execute differently than intended.

Since it is usually not very productive to guess after the rest of your unknown code I suggest you show the entire code. So we can make more directed suggestions on how to solve this problem.

Hi

@Mee_n_Mac - You are correct. Thanks

@Valen - I know what you are saying but the original code is huge and difficult to post.

I did have the code running but using a different Ds1307 piece of code. I am still trying to get my head around this method of declaring Hours, Minutes etc.

Prior to this I was using

#define DS1307_I2C_ADDRESS 0x68
 
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
 
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
 

 
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-28/29/30/31
byte month,         // 1-12
byte year)          // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second));    // 0 to bit 7 starts the clock
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));      // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.endTransmission();
}
 
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
 
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
 
// A few of these need masks because certain bits are control bits
*second     = bcdToDec(Wire.read() & 0x7f);
*minute     = bcdToDec(Wire.read());
*hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
*dayOfWeek  = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month      = bcdToDec(Wire.read());
*year       = bcdToDec(Wire.read());
void setup()  // run once, when the sketch starts
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;}
void loop() // run over and over again
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
 
// this prints the output to the serial window (tools > serial monitor in arduino) and is great for testing
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);


 
// Set the time you want the motors to kick in
if((hour == 19)&&(minute == 27)&&(second==00)){
Serial.print(" TRUE");
Serial.println(" ");
Serial.println(" MP1");
analogWrite(motorPin1, 255);
delay(0000); // set how long you want the motor to run... 1000 = aprox 1ml
 
analogWrite(motorPin1, 0);
Serial.println(" MP2");
analogWrite(motorPin2, 255);
delay(0000); // set how long you want the motor to run... 1000 = aprox 1ml
 
analogWrite(motorPin2, 0);
Serial.println(" MP3");
analogWrite(motorPin3, 255);
delay(9500); // set how long you want the motor to run... 1000 = aprox 1ml
analogWrite(motorPin3, 0);
 
}

so all I am trying to do is work out how to achieve the same thing using this other method of using the RTC

I don’t want to use the original way it was coded as it is inefficient. I have used a snippet of code containing the RTC code I posted and it works for the function it is used for however I cannot seem to work out how to define the variables etc and use them to trigger my own timer function.

Does that make sense?

@No1Daemon:

Tip: There is a curly bracket missing right before void Setup.

[EDIT]Why declare

byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

…twice in Setup and Loop? Once should suffice, and Setup would be the place to define initial values to them. Defining a variable with the same name in a different function makes it override any values the other has in that particular function. So now you have 2 hours, 2minutes, 2 seconds and so on, until the function is left. The other variables are left untouched and will not be affected by the last function. Keyword: Scope

http://arduino.cc/en/Tutorial/Variables

http://arduino.cc/en/Reference/scope

Okay so having a closer look at the code with the understanding you have given me.

Hours, Minutes, Second etc have been declared right at the start in global variables

like so

//###   Clock Variables ################################

int Hours, Minutes, Seconds;
int Day;
int Month;
int Year;
int Weekday;
String Current_time;
boolean Daytime = true;
boolean Was_day;

Then the RTC is initiated in setup

void setup(){
  
  myGLCD.InitLCD(PORTRAIT);                           //Initiate LCD Screen
  myGLCD.clrScr();
  file.initFAT(SPISPEED_VERYHIGH);                    //Initiate SD Card for FAT16 Lib
  Wire.begin();
  RTC.begin();

and then the current time is called from the RTC in the loop and the hours, minutes, seconds etc passed to the global variables earlier already setup like so

void loop(){
    
  DateTime now = RTC.now();
  Hours = now.hour();
  Minutes = now.minute();
  Seconds = now.second();
  Day = now.day();
  Month = now.month();
  Year = now.year();
  Weekday = now.dayOfWeek();
}

Can ignore any syntax errors with the curly braces as it is only due to cutting and pasting relevant code.

So with those globally declared and the loop runs continuously and keeps updating those int values

Then in theory I should be able to simply use a time trigger like I have been trying to by using

if ( myTFT.LatchCircle_Draw(213,85,11,10) && (( Hours == 14) && ( Minutes == 30) && Seconds <10)){ 
 Dosing2On();}

Is that all that is needed?

Obviously I also have the RTC library loaded etc also.

EDIT. I forgot to add that the above line has also been placed in the loop and the first part is dependant on a touch screen button being turned on.

Yes that does seem sufficient. But the ultimate test is in compiling the program, and seeing if it generates errors. If it does compile correctly, then run the program and see if it works as required.

It compiles without errors. However does not work as expected.

I included some serial print commands in the Dosing command but it never seems to run at the time set.

I removed the tft command and just used the timer code itself to test that on its own and it still doesn’t seem to run.

How would you write the if statement? Could you please show me an example?

Your last if statement seems almost the way i would make it, except the seconds part isn’t encased between round brackets. But I think it would evaluate correctly anyway.

To debug this problem I would send the values of the variables that are important at each step of processing, to the serial port. And also the results of each calculation or function use so you can compare by yourself.

What goes on inside an Arduino (or any microcontroller for that matter) stays invisible until you bring it out into the open. Your lcd could also be used for this I presume. But might also make the code more complex.

Okay. That makes sense. I will debug it that way and see if I can see what is happening.

Thankyou