Trying to learn as fast as I can. Thank you for being patient. I will share the completed code once it’s all working and done for the benefit of others like me.
I am using TIMEALARMS to trigger off these activities
void waterLevelIsSet()
{
int hour = setHour;
int minute = setMinute;
Alarm.alarmRepeat(hour, minute, 0, waterLevel1Now);
Alarm.alarmRepeat(hour, minute, 0, waterLevel2Now);
}
Although the setTime is the same for both the alarms. They are called out sequentially and not together. I read the issue is related to multi threading. Any ways around this?
If they’re supposed to act at the same time, couldn’t you just put the actions into a single function and trigger that?
there is a delay for start and stop
void waterLevel1Now()
{
Serial.println("Watering Level 1 Now");
digitalWrite(pumpLevel1,HIGH);
delay(waterTime1);
digitalWrite(pumpLevel1,LOW);
Serial.println("Watering Level 1 Ended");
}
void waterLevel2Now()
{
Serial.println("Watering Level 2 Now");
digitalWrite(pumpLevel2,HIGH);
delay(waterTime2);
digitalWrite(pumpLevel2,LOW);
Serial.println("Watering Level 2 Ended");
}
It would be helpful to know a little more about what you’re trying to accomplish. I assume you want pumpLevel1 and pumpLevel2 to go HIGH at the same time, and at some later time(s) for them to go LOW. What kind of times are we talking about for the delays? Microseconds, milliseconds, seconds? Is one of the delays (waterTime1 or waterTime2) always longer than the other?
The times are set in minutes and they are variable. It’s for a hydroponics system so depending on the type of plant the watering time has to be variable. Although typically would be under 10 minutes.
Unless your code is doing nothing else, then you don’t want to use delay() for such long delays (since none of your other code will run during the delay). You might want to think about having one alarm that turns on the pumps (both at the same time), and two other alarms, one to turn off each pump at some future time, instead of using delay().
Yea ill do that. Although i do have a C question related to the project you could help me with. You helped me parse a string earlier by breaking it into tokens. So 11:54 became 11 and 54 and both could get individual values. What if I want to add a string like A:11:34
where A
would be an identifier and 11:34
would be time or another int value I could assign to variables. That way I can build a method which assigns particular string values to respective variables.
Or you could point me in the right direction towards what I should be searching for on Google
Sorry, I don't understand what you're asking here. What do you mean by "add a string"? Add a string to what?
How would I break ABCD:11:34 such that
var1 = ABCD
var2 = 11
var3 = 34
I could then assign
If var1 == "some const"
Var2 = sethour
Var3 = setTime
You would use strtok(), like I showed before, near the top of this thread.
As @Ric already suggested earlier Google can be your friend (especially when you already got the search terms given strtok
, sprintf
)
http://www.cplusplus.com/reference/cstring/strtok/
http://www.cplusplus.com/reference/cstdio/sprintf/
i have the following static constants in my program right now.
int static varM_t = 0;
int static varM = 0;
int static varH = 0;
int const P1ON = 11;
int static P1ON_t_h = 0;
int static P1ON_t_m = 0;
int static P1OFF_t_m = 0;
int const P1OFF = 10;
int static CODE = 0;
at the end of it i am assigning these to time alarm
Alarm.alarmRepeat(hour, minute, 0, waterOn);
I may need to set about 10 different alarms. And i want to store the alarms into EEPROM so the program keeps running as per set state in case there is a power cycle.
Can you please point me in the right direction.
https://docs.particle.io/reference/firmware/photon/#eeprom
https://docs.particle.io/reference/firmware/photon/#put-
https://docs.particle.io/reference/firmware/photon/#get-
This should be clear enough
Seems like the EEPROM to L1OFF is over written when i call function l1s. Any ideas to what im doing wrong?
// This #include statement was automatically added by the Particle IDE.
#include "TimeAlarms.h"
int led = D7;
struct startTime
{
bool active = false;
int hour = 0;
int minute = 0;
}
l1On,l2On;
struct runTime
{
bool active = false;
int runT = 0;
}
l1Off;
AlarmID_t lightsL1On = 255;
int TimeZoneAddr = 0;
int L1ON = 1;
int L1OFF = 2;
int P1ON = 3;
int P1OFF = 4;
void setup()
{
Serial.begin(9600);
setInitialValue();
Particle.function("setAnything",setAnything);
pinMode(led,OUTPUT);
}
void loop()
{
Alarm.delay(1000);
}
int setAnything(String cmd)
{
String action = cmd.substring(0, 3);
String arg = cmd.substring(3);
Serial.println(action);
Serial.println(arg);
if (action == "t")
{
Serial.println(Time.format());
}
else if (action == "tzs")
{
int8_t num = atoi(arg);
Serial.println(num);
EEPROM.write(TimeZoneAddr,num);
Time.zone(num);
return 1;
}
else if (action == "s")
{
Serial.println();
}
else if (action == "l1s")
{
int act = atoi(arg.substring(0,1));
int hour = atoi(arg.substring(1,3));
int min = atoi(arg.substring(3,5));
l1On.active = act;
l1On.hour = hour;
l1On.minute = min;
Serial.println(act);
Serial.println(hour);
Serial.println(min);
if (act)
{
lightsL1On = Alarm.alarmRepeat(hour, min, 0, runTime1);
}
else
{
Alarm.disable(lightsL1On);
shutOff();
}
EEPROM.put(L1ON,l1On);
}
else if (action == "l1t")
{
int act = atoi(arg.substring(0,1));
int runT = atoi(arg.substring(1,5));
Serial.println(act);
Serial.println(runT);
l1Off.active = act;
l1Off.runT = runT;
EEPROM.put(L1OFF,l1Off);
}
else if (action =="rep")
{
//readStorage();
readEEp();
}
}
void setInitialValue()
{
int8_t zone = (int8_t)EEPROM.read(TimeZoneAddr);
Serial.println(zone);
Time.zone(zone);
EEPROM.get(L1ON,l1On);
if (l1On.active)
{
lightsL1On = Alarm.alarmRepeat(l1On.hour, l1On.minute, 0, runTime1);
}
}
void runTime1()
{
digitalWrite(led,HIGH);
Alarm.timerOnce(l1Off.runT,shutOff);
}
void shutOff()
{
digitalWrite(led,LOW);
}
void readEEp()
{
EEPROM.get(L1OFF,l1Off);
int t = l1Off.active;
int p = l1Off.runT;
Serial.println(t);
Serial.println(p);
}
You can’t have your EEPROM addresses just one byte apart when you intend to have multiple bytes in the struct to store at that location.
int L1ON = 1;
int L1OFF = 2;
int P1ON = 3;
int P1OFF = 4;
i see!! so to be on the safe size since im saving 5 ints i should initialize values in multipes of 5
An int
on a 32bit µC like the Particles use is four bytes long.
But even if you only use uint8_t
in your structs they will still be alligned to four byte boundaries unless you use a different packing pragma.
But you could always use sizeof()
to get the actual sizes.
And for EEPROM data you should also make sure that the data you read from EEPROM is actually in tact (e.g. magic numbers and/or CRC)
so in my case stored data will be 11113 or 1300. I would need to validate that by using L1On.sizeof() == 20?
I’d start with this
struct startTime
{
bool active = false; // four byte
int hour = 0; // four byte
int minute = 0; // four byte
}
l1On,l2On;
struct runTime
{
bool active = false; // four byte
int runT = 0; // four byte
}
l1Off;
...
int TimeZoneAddr = 0; // stores an int8_t
int L1ON = TimeZoneAddr + sizeof(int8_t); // stores a startTime
int L1OFF = L1ON + sizeof(l1On); // stores a runTime
And on top of that would add some sanity check/validation.