I'm hoping what i'm trying to do is possible.
I'm working on a solar powered lighting project for a sculpture. The basic idea is to have lights turn on at a certain time every night and then turn off again. No big deal, however as this is going into an art piece that will be installed permanently I was hoping to add a GPS module that would reset the clock every night so I wouldn't have to climb up the statue every few months to reset the internal timers...
With the TinyGPS library, the Time library, the TimeAlarm library and the TimeZone library, I can get some skeleton code doing the basics of what I want the system to do -turn it on and off according to a schedule and set the clock.
The problem is, as soon as i call a method in the DMXSimple Library, well time goes all to hell... I'm not sure how to work around this so that simpleDMX will play nice with the GPS and clock.... I could just use one arduino as a clock to trigger a relay and start the lighting arduino... Is there a better way... Below is my basic code with the call to DMX that makes it all fall down...
#include <Time.h>
#include <Timezone.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <TimeAlarms.h>
#include <DmxSimple.h> // it includes fine
int sundownHourByMonth[] = {16,17,19,20,20,21,21,20,19,18,16,16}; //based on average sundown time for the 15th of the month.
int sundownMinutesByMonth[] ={42,32,17,20,49,19,31,29,25,22,31,14}; //not integrated yet
SoftwareSerial ss(10, 11); //GPS is on these pins...
TinyGPS gps;
TimeChangeRule myDST = {"PDT", Second, Sun, Mar, 2, -420}; //Daylight time = UTC - 7 hours
TimeChangeRule mySTD = {"PST", First, Sun, Nov, 2, -480}; //Standard time = UTC - 8 hours
Timezone myTZ(myDST, mySTD);
TimeChangeRule *tcr; //pointer to the time change rule, use to get TZ abbrev
time_t utc, local;
void setup(){
Serial.begin(115200); //dumping to screen
//software serial to GPS
///THESE CALLS TO DMX SCREW THE GPS's ability to talk and time stands still
DmxSimple.usePin(4);
DmxSimple.maxChannel(128);
ss.begin(9600); //software serial for GPS
setTime(0,0,0,0,0,0); //initialize clock with bogus time
}
void loop(){
unsigned long age, date, time, chars = 0;
if(year(now()) < 2013){ //time is all crappy like when it's first turned on
setDate(gps);
setAlarms();
}
Serial.println();
//
Alarm.delay(0); // need to do this to pole alarm
printTime(now(), tcr -> abbrev);
smartdelay(1000);
}
void smartdelay(unsigned long ms){
unsigned long start = millis();
do {
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
void setDate(TinyGPS &gps){
int year;
byte month, day, hour, minute, second, hundredths;
unsigned long age;
while(year< 2013){
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age); //where the action is
setTime (hour, minute, second, day, month, year);
smartdelay(0);
utc = now();
local = myTZ.toLocal(utc, &tcr); //change the UTC time to our timezone and daylight savings crap
setTime(local);
}
Serial.println("finished setting time");
}
void printTime(time_t t, char *tz){
sPrintI00(hour(t));
sPrintDigits(minute(t));
sPrintDigits(second(t));
Serial.print(' ');
Serial.print(dayShortStr(weekday(t)));
Serial.print(' ');
sPrintI00(day(t));
Serial.print(' ');
Serial.print(monthShortStr(month(t)));
Serial.print(' ');
Serial.print(year(t));
Serial.print(' ');
Serial.print(tz);
Serial.println();
}
//Print an integer in "00" format (with leading zero).
//Input value assumed to be between 0 and 99.
void sPrintI00(int val){
if (val < 10) Serial.print('0');
Serial.print(val, DEC);
return;
}
//Print an integer in ":00" format (with leading zero).
//Input value assumed to be between 0 and 99.
void sPrintDigits(int val){
Serial.print(':');
if(val < 10) Serial.print('0');
Serial.print(val, DEC);
}
void StartTheShow(){
Serial.println("turn the lights on baby");
}
void EndTheShow(){
Serial.println("turn lights off");
//set the clock again just in case
setDate(gps);
}
void setAlarms(){
Alarm.alarmRepeat(19,50,0, StartTheShow); // 2hours past sundown every evening
Alarm.alarmRepeat(19,51,0, EndTheShow); //01:00am every night shut off
Serial.println("alarms set");
}