I figured this out..basically any time, less than or equal to now, will immediately fire the relay. Is that correct?
With regards to the retained variables, I'm not sure what changed. It worked at one point, and now it suddenly isn't working at all. I double checked that the photon is still receiving the 3.2v, which it is. It used to work perfectly, now its not working at all. Here is the code.
typedef struct {
int onTime;
int offTime;
float totalDose;
float doseRate; // mL/min
int connectedPin;
int calibrationEnd = 90000; // a vaule greater than "now" can ever be
int numberOfDoses; //number of doses in 24hr period
} Channel;
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
void updateChannel(Channel c);
float now;
char getRelay1[75];
char getRelay2[75];
char getRelay3[75];
char getRelay4[75];
retained Channel channels[4];
void setup() {
channels[1].connectedPin = D3;
channels[2].connectedPin = D4;
channels[3].connectedPin = D5;
channels[4].connectedPin = D6;
pinMode(D3,OUTPUT);
pinMode(D4,OUTPUT);
pinMode(D5,OUTPUT);
pinMode(D6,OUTPUT);
Serial.begin(9600);
Time.zone(-4);
delay(3000);
Particle.function("setupChannel", setupChannel);
Particle.function("calibrate",calibrate);
Particle.function("manual",manual);
Particle.variable("getRelay1", getRelay1);
Particle.variable("getRelay2", getRelay2);
Particle.variable("getRelay3", getRelay3);
Particle.variable("getRelay4", getRelay4);
}
void loop() {
now = Time.hour() * 3600 + Time.minute() * 60 + Time.second();
Serial.println(now);
for (int i=0;i<4;i++) {
updateChannel(i);
}
delay(5000);
}
void updateChannel(int index) {
Channel *c = &channels[index];
if (c->onTime <= now && c->totalDose > 0) {
digitalWrite(c->connectedPin, HIGH);
Serial.printlnf("Fired Relay %d", index);
c->onTime += 7200;
}
if (c->offTime <= now && c->totalDose > 0) {
digitalWrite(c->connectedPin, LOW);
Serial.printlnf("Turned off Relay %d", index);
c->offTime += 7200;
}
if (c->calibrationEnd <= now) {
digitalWrite(c->connectedPin, LOW);
c->calibrationEnd = 90000;
}
}
int setupChannel(String cmd) { // cmd syntax: "channel#,startTime,doseRate, numberOfDoses, totalDose" (startTime is sent as hour*3600 + minute*60 + second)
Serial.println(cmd);
char *rmdr;
char *stringArgs = (char*)cmd.c_str();
int index = atoi(strtok_r(stringArgs, ",", &rmdr));
Channel* c = &channels[index];
c->onTime = atof(strtok_r(NULL, "," ,&rmdr));
c->doseRate = atof(strtok_r(NULL, "," , &rmdr));
c->numberOfDoses = atoi(strtok_r(NULL, ",", &rmdr));
c->totalDose = atof(rmdr);
float dosePerActuation = c->totalDose/c->numberOfDoses;
float durationPerActuation = (dosePerActuation/c->doseRate) * 60; // assuming doseRate is in volume/minute
c->offTime = c->onTime + durationPerActuation;
Serial.printlnf("channel#: %d, onTime: %d, doseRate: %f, totalDose: %f, numberOfDoses: %d", index, c->onTime, c->doseRate, c->totalDose, c->numberOfDoses);
char *str;
switch (index) {
case 1:
str = getRelay1;
break;
case 2:
str = getRelay2;
break;
case 3:
str = getRelay3;
break;
case 4:
str = getRelay4;
break;
}
sprintf(str, "onTime: %d, totalDose: %.1f, numberOfDoses: %.1d", c->onTime, c->totalDose, c->numberOfDoses);
return 1;
}
float doseRate(String cmd) {
char *rmdr;
char *stringArgs = (char*)cmd.c_str();
int index = atoi(strtok_r(stringArgs, ",", &rmdr));
Channel* c = &channels[index];
return 1;
}
int calibrate(String cmd) {
char *rmdr;
char *stringArgs = (char*)cmd.c_str();
int index = atoi(strtok_r(stringArgs, ",", &rmdr));
Channel* c = &channels[index];
if (strcmp(rmdr, "on") == 0) {
digitalWrite(c->connectedPin,HIGH);
c->calibrationEnd = Time.hour() * 3600 + Time.minute() * 60 + Time.second() + 60;
return 1;
}
else if (strcmp(rmdr, "off") == 0) {
digitalWrite(c->connectedPin,LOW);
return 0;
}
else {
return -1;
}
}
int manual(String cmd) {
char *rmdr;
char *stringArgs = (char*)cmd.c_str();
int index = atoi(strtok_r(stringArgs, ",", &rmdr));
Channel* c = &channels[index];
if (strcmp(rmdr, "on") == 0) {
digitalWrite(c->connectedPin,HIGH);
return 1;
}
else if (strcmp(rmdr, "off") == 0) {
digitalWrite(c->connectedPin,LOW);
return 0;
}
else {
return -1;
}
}