Hi All, new to the forum having got my arduino a few days ago....
So my project is a timed relay controller.
So far, I have got a DS1307, working, got the LCD, working, got the relays hitched up and able to control.
Ive done a little sketch that is just sequentially switching relays on/off on a millisecond count, and showing the day, hh:mm on an LCD.
I've tried my best to "figure it out" as I have done so far, and cobble bits together, but now I stuck..
Here is my code:
(code tags fixed by moderator)
// include the library code for DS1307
// include the library code for LCD
// Define the DS1307
#include <LiquidCrystal.h>
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
// initialize the library with the numbers of the interface pins for LCD
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
const int relay0pin = 8; // Set the pin for relay0
const int relay1pin = 9; // set the pin for relay1
// Variables will change:
int relay0state = LOW;
int relay1state = LOW;
// ledState used to set the relays
long previousMillis0 = 1; // will store last time relay0 was updated
long previousMillis1 = 1; // will store last time relay1 was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval0 = 5000; // interval at which to switch (milliseconds)
long interval1 = 10000; // interval at which to switch (milliseconds)
// 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));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.write(0x10); // writes 0x10 (hex) 00010000 (binary) to control register - turns on square wave
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() {
// set the digital pin as output:
pinMode(relay0pin, OUTPUT);
pinMode(relay1pin, OUTPUT);
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 45;
minute = 31;
hour = 20;
dayOfWeek = 6;
dayOfMonth = 19;
month = 4;
year = 13;
//setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
lcd.begin(16, 2); // tells Arduino the LCD dimensions
}
void loop()
{
// here is the code that needs to be running all the time.
lcd.begin(16, 2);
lcd.setCursor(6, 0);
lcd.print("L1");
lcd.setCursor(10, 0);
lcd.print("L2");
lcd.setCursor(14, 0);
lcd.print("L3");
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
//lcd.clear(); // clear LCD screen
lcd.setCursor(0,0);
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10)
{
lcd.print("0");
}
lcd.print(minute, DEC);
if (second<10)
{
lcd.print("");
}
lcd.setCursor(0,1);
switch(dayOfWeek){
case 1:
lcd.print("Sun");
break;
case 2:
lcd.print("Mon");
break;
case 3:
lcd.print("Tue");
break;
case 4:
lcd.print("Wed");
break;
case 5:
lcd.print("Thu");
break;
case 6:
lcd.print("Fri");
break;
case 7:
lcd.print("Sat");
break;
}
delay(1000);
// check to see if it's time to switch the realy; that is, if the
// difference between the current time and last time you switched
// the relay is bigger than the interval at which you want to
// switch the relay.
unsigned long currentMillis0 = millis();
unsigned long currentMillis1 = millis();
if(currentMillis0 - previousMillis0 > interval0) {
// save the last time relay0 switched
previousMillis0 = currentMillis0;
lcd.setCursor(6, 1);
// if the relay0 is off turn it on and vice-versa:
if (relay0state == LOW)
relay0state = HIGH;
else
relay0state = LOW;
digitalWrite(relay0pin, relay0state);
}
if(currentMillis1 - previousMillis1 > interval1) {
// save the last time relay1 switched
previousMillis1 = currentMillis1;
// if the relay1 is off turn it on and vice-versa:
if (relay1state == LOW)
relay1state = HIGH;
else
relay1state = LOW;
digitalWrite(relay1pin, relay1state);
}
}
I have two questions, at the bottom of the code you will see there are two relays switching on and off at set timings, not usefull at the moment, but more of a test while I get the hang of it.
I have an LCD set to show L1, L2, L3 on line one, ignore L3 - no hooked this relay up yet), but I am trying to get it to display "on" on line 2 at the set positions corresponding with the L1, L2 when each relay is on its "high" cycle, I cant work it out though.... can anyone help point me?
Essentially I am trying to get along the lines of (example when relay0 is low and relay 1 is high)
00:00 L1 L2 L3
Fri ON
(example when relay0 is HIGH and relay 1 is HIGH)
00:00 L1 L2 L3
Fri ON ON
As said, once I have that I can figure out to add additional ones once I hook up....