Set up scheduled program cycles #24

Merged
W1CDN merged 41 commits from program-cycle into main 2023-09-15 16:51:45 -05:00
Showing only changes of commit 958e71513c - Show all commits

View File

@ -43,6 +43,9 @@ const char* PARAM_FLOAT = "inputFloat";
const char* PARAM_TIME = "inputTimeUnix"; const char* PARAM_TIME = "inputTimeUnix";
const char* PARAM_START = "inputStartTimeUnix"; const char* PARAM_START = "inputStartTimeUnix";
const char* PARAM_RUNNING = "programRunning"; const char* PARAM_RUNNING = "programRunning";
const char* PARAM_STEPLENGTH = "inputStepLength";
const char* PARAM_CYCLEID = "inputCycleID";
const char* PARAM_NTRANS = "inputNtransmitters";
// Global variables // Global variables
String yourInputString; String yourInputString;
@ -55,7 +58,10 @@ uint32_t yourInputTime; //to keep time
uint32_t yourInputStartTimeUnix; uint32_t yourInputStartTimeUnix;
bool startProgram; bool startProgram;
bool programRunning; bool programRunning;
int step_length = 30000; // 30 secs int yourInputStepLength;
int yourInputCycleID;
int yourInputNtransmitters;
int step_length = 10000; // 10 secs
int cycle_id = 1; // number of this transmitter in cycle int cycle_id = 1; // number of this transmitter in cycle
int n_transmitters = 2; //number of transmitters total int n_transmitters = 2; //number of transmitters total
@ -107,19 +113,19 @@ const char index_html[] PROGMEM = R"rawliteral(
} }
</script></head><body> </script></head><body>
<h1>Vulpes Radio Orienteering Controller</h1>
<p>Local time: <b><span id=local-time-unix></span></b></p> <p>Local time: <b><span id=local-time-unix></span></b></p>
<form action="/get" onsubmit="putDate(this);" accept-charset=utf-8> <form action="/get" onsubmit="putDate(this);" accept-charset=utf-8>
<h2>General Settings</h2>
<p>Sending program (cycle doesn't work yet) (current value: <b>%inputSend%</b>): <p>Sending program:
<select name="inputSend" id="send-program"> <select name="inputSend" id="send-program">
<option value="0" >0 - Off</option> <option value="0" >0 - Off</option>
<option value="1">1 - Continuous</option> <option value="1">1 - Continuous</option>
<option value="2">2 - Cycle</option> <option value="2">2 - Cycle</option>
</select><br> </select><br>
Message (current value <b>%inputMsg%</b>): Message:
<select name="inputMsg" id="message"> <select name="inputMsg" id="message">
<option value="0">0 - TEST TEST TEST DE W1CDN</option> <option value="0">0 - TEST TEST TEST DE W1CDN</option>
<option value="1">1 - MOE</option> <option value="1">1 - MOE</option>
@ -129,6 +135,7 @@ const char index_html[] PROGMEM = R"rawliteral(
<option value="5">5 - MO5</option> <option value="5">5 - MO5</option>
</select></p> </select></p>
<h2>Cycle Settings</h2>
<p>Cycle start time <input type="datetime-local" id="js_start_time_unix_entry" /><br> <p>Cycle start time <input type="datetime-local" id="js_start_time_unix_entry" /><br>
Current value: <b><span id=current-start></span></b>, but only day-of-month HH:MM:SS are used. Current value: <b><span id=current-start></span></b>, but only day-of-month HH:MM:SS are used.
Only applies when <em>Sending Program</em> is set to "2 - Cycle". Only applies when <em>Sending Program</em> is set to "2 - Cycle".
@ -136,6 +143,11 @@ const char index_html[] PROGMEM = R"rawliteral(
<!-- JS converts the entered start time to a unix timestamp, and copies that value <!-- JS converts the entered start time to a unix timestamp, and copies that value
to this hidden field so the user doesn't have to see it. --> to this hidden field so the user doesn't have to see it. -->
<input type="hidden" name="inputStartTimeUnix" id="js_start_time_unix" /></p> <input type="hidden" name="inputStartTimeUnix" id="js_start_time_unix" /></p>
<p>
Step length: <input type="number" name="inputStepLength" value = %inputStepLength%><br>
Cycle ID: <input type="number" name="inputCycleID" value = %inputCycleID%><br>
Number of transmitters: <input type="number" name="inputNtransmitters" value = %inputNtransmitters%><br>
</p>
<!-- This field is hidden so people don't change the submit time (it will be wrong). <!-- This field is hidden so people don't change the submit time (it will be wrong).
The value is automatically filled in with JS. --> The value is automatically filled in with JS. -->
@ -221,6 +233,15 @@ String processor(const String& var){
else if(var == "inputMsg"){ else if(var == "inputMsg"){
return readFile(SPIFFS, "/inputMsg.txt"); return readFile(SPIFFS, "/inputMsg.txt");
} }
else if(var == "inputStepLength"){
return readFile(SPIFFS, "/inputStepLength.txt");
}
else if(var == "inputCycleID"){
return readFile(SPIFFS, "/inputCycleID.txt");
}
else if(var == "inputNtransmitters"){
return readFile(SPIFFS, "/inputNtransmitters.txt");
}
else if(var == "inputFloat"){ else if(var == "inputFloat"){
return readFile(SPIFFS, "/inputFloat.txt"); return readFile(SPIFFS, "/inputFloat.txt");
} else if(var == "inputStartTimeUnix"){ } else if(var == "inputStartTimeUnix"){
@ -304,14 +325,14 @@ int period = morse_cycle.Period();
int repeats = step_length / period; int repeats = step_length / period;
int remainder_wait = step_length - (period * repeats); int remainder_wait = step_length - (period * repeats);
int total_wait = ((step_length * (n_transmitters - 1) + remainder_wait)); int total_wait = ((step_length * (n_transmitters - 1) + remainder_wait));
JLed morses[] = { JLed morses_blink[] = {
// WOW it looks like you can't do Repeat() and DelayAfter() at the same time? // WOW it looks like you can't do Repeat() and DelayAfter() at the same time?
// Opened https://github.com/jandelgado/jled/issues/122 // Opened https://github.com/jandelgado/jled/issues/122
JLed(blinker).UserFunc(&morse_cycle).Repeat(repeats), JLed(blinker).UserFunc(&morse_cycle).Repeat(repeats),
//JLed(blinker).FadeOn(1000).Repeat(3) //JLed(blinker).FadeOn(1000).Repeat(3)
JLed(blinker).Off(total_wait) JLed(blinker).Off(total_wait)
}; };
auto morses_sequence = JLedSequence(JLedSequence::eMode::SEQUENCE, morses); auto morses_sequence_blink = JLedSequence(JLedSequence::eMode::SEQUENCE, morses_blink);
//================================================================================ //================================================================================
// start_program(): a function to start the planned program at the planned time // start_program(): a function to start the planned program at the planned time
@ -328,9 +349,6 @@ bool start_program(){
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
Serial.print("morseEffectTEST.Period(): ");
Serial.println(morseEffectTEST.Period());
pinMode(alarmPin, INPUT_PULLUP); // Set alarm pin as pullup pinMode(alarmPin, INPUT_PULLUP); // Set alarm pin as pullup
if (! rtc.begin()) { if (! rtc.begin()) {
@ -349,6 +367,11 @@ void setup() {
//rtc.adjust(DateTime(2023, 9, 2, 17, 32, 0)); //rtc.adjust(DateTime(2023, 9, 2, 17, 32, 0));
} }
// Report the RTC time
Serial.print("RTC time on startup: ");
Serial.println(rtc.now().unixtime());
Serial.println(rtc.now().timestamp());
// Are there any RTC alarms set? // Are there any RTC alarms set?
DateTime alarm_one = rtc.getAlarm1(); // Get the current time DateTime alarm_one = rtc.getAlarm1(); // Get the current time
char buff[] = "Alarm 1 set for at hh:mm:ss DDD, DD MMM YYYY"; char buff[] = "Alarm 1 set for at hh:mm:ss DDD, DD MMM YYYY";
@ -373,8 +396,6 @@ void setup() {
return; return;
} }
// Read in existing data // Read in existing data
yourInputString = readFile(SPIFFS, "/inputString.txt"); yourInputString = readFile(SPIFFS, "/inputString.txt");
yourInputSend = readFile(SPIFFS, "/inputSend.txt").toInt(); yourInputSend = readFile(SPIFFS, "/inputSend.txt").toInt();
@ -382,6 +403,9 @@ void setup() {
yourInputMsg = readFile(SPIFFS, "/inputMsg.txt").toInt(); yourInputMsg = readFile(SPIFFS, "/inputMsg.txt").toInt();
yourInputFloat = readFile(SPIFFS, "/inputFloat.txt").toFloat(); yourInputFloat = readFile(SPIFFS, "/inputFloat.txt").toFloat();
yourInputStartTimeUnix = readFile(SPIFFS, "/inputStartTimeUnix.txt").toInt(); yourInputStartTimeUnix = readFile(SPIFFS, "/inputStartTimeUnix.txt").toInt();
yourInputStepLength = readFile(SPIFFS, "/inputStepLength.txt").toInt();
yourInputCycleID = readFile(SPIFFS, "/inputCycleID.txt").toInt();
yourInputNtransmitters = readFile(SPIFFS, "/inputNtransmitters.txt").toInt();
// On restart, keep doing what you were doing before // On restart, keep doing what you were doing before
yourInputMsg_old = yourInputMsg; yourInputMsg_old = yourInputMsg;
@ -454,6 +478,24 @@ void setup() {
yourInputMsg_old = yourInputMsg; yourInputMsg_old = yourInputMsg;
yourInputMsg = inputMessage.toInt(); yourInputMsg = inputMessage.toInt();
} }
// GET inputStepLength value on <ESP_IP>/get?inputStepLength=<inputMessage>
if (request->hasParam(PARAM_STEPLENGTH)) {
inputMessage = request->getParam(PARAM_STEPLENGTH)->value();
writeFile(SPIFFS, "/inputStepLength.txt", inputMessage.c_str());
yourInputStepLength = inputMessage.toInt();
}
// GET inputCycleID value on <ESP_IP>/get?inputCycleID=<inputMessage>
if (request->hasParam(PARAM_CYCLEID)) {
inputMessage = request->getParam(PARAM_CYCLEID)->value();
writeFile(SPIFFS, "/inputCycleID.txt", inputMessage.c_str());
yourInputCycleID = inputMessage.toInt();
}
// GET inputNtransmitters value on <ESP_IP>/get?inputNtransmitters=<inputMessage>
if (request->hasParam(PARAM_NTRANS)) {
inputMessage = request->getParam(PARAM_NTRANS)->value();
writeFile(SPIFFS, "/inputNtransmitters.txt", inputMessage.c_str());
yourInputNtransmitters = inputMessage.toInt();
}
// GET inputTimeUnix value on <ESP_IP>/get?inputTimeUnix=<inputMessage> // GET inputTimeUnix value on <ESP_IP>/get?inputTimeUnix=<inputMessage>
if (request->hasParam(PARAM_TIME)) { if (request->hasParam(PARAM_TIME)) {
inputMessage = request->getParam(PARAM_TIME)->value(); inputMessage = request->getParam(PARAM_TIME)->value();
@ -537,26 +579,6 @@ void loop() {
// Timers // Timers
timer.tick(); timer.tick();
// This statement from https://github.com/garrysblog/DS3231-Alarm-With-Adafruit-RTClib-Library/blob/master/DS3231-RTClib-Adafruit-Alarm-Poll-alarmFired/DS3231-RTClib-Adafruit-Alarm-Poll-alarmFired.ino
// Check if alarm by polling SQW alarm pin
if((yourInputSend == 2) & (digitalRead(alarmPin) == LOW)) {
// Print current time and date
DateTime now = rtc.now(); // Get the current time
char buff[] = "Alarm triggered at hh:mm:ss DDD, DD MMM YYYY";
Serial.println(now.toString(buff));
startProgram = true;
// Disable and clear alarm
rtc.clearAlarm(1);
rtc.clearAlarm(2); // clear the other one just in case
}
// Once alarm has started the program, set things up to run
if(startProgram == true){
morses_sequence.Forever().Update();
programRunning = true;
startProgram = false;
} else
// See which message we are sending // See which message we are sending
// Only do this when the message has been updated. // Only do this when the message has been updated.
if(yourInputMsg != yourInputMsg_old){ if(yourInputMsg != yourInputMsg_old){
@ -584,6 +606,40 @@ void loop() {
yourInputMsg_old = yourInputMsg; yourInputMsg_old = yourInputMsg;
} }
// This statement from https://github.com/garrysblog/DS3231-Alarm-With-Adafruit-RTClib-Library/blob/master/DS3231-RTClib-Adafruit-Alarm-Poll-alarmFired/DS3231-RTClib-Adafruit-Alarm-Poll-alarmFired.ino
// Check if alarm by polling SQW alarm pin
if((yourInputSend == 2) & (digitalRead(alarmPin) == LOW)) {
// Print current time and date
DateTime now = rtc.now(); // Get the current time
char buff[] = "Alarm triggered at hh:mm:ss DDD, DD MMM YYYY";
Serial.println(now.toString(buff));
startProgram = true;
// Disable and clear alarm
rtc.clearAlarm(1);
rtc.clearAlarm(2); // clear the other one just in case
}
// Once alarm has started the program, set things up to run
if(startProgram == true){
//auto morse_cycle = morseEffectMOS;
int period = morse_cycle.Period();
int repeats = step_length / period;
int remainder_wait = step_length - (period * repeats);
int total_wait = ((step_length * (n_transmitters - 1) + remainder_wait));
JLed morses_blink[] = {
// WOW it looks like you can't do Repeat() and DelayAfter() at the same time?
// Opened https://github.com/jandelgado/jled/issues/122
JLed(blinker).UserFunc(&morse_cycle).Repeat(repeats),
//JLed(blinker).FadeOn(1000).Repeat(3)
JLed(blinker).Off(total_wait)
};
auto morses_sequence_blink = JLedSequence(JLedSequence::eMode::SEQUENCE, morses_blink);
morses_sequence_blink.Forever().Update();
programRunning = true;
startProgram = false;
}
// if you want to send continuous code, and it's not sending, then start it up // if you want to send continuous code, and it's not sending, then start it up
if((yourInputSend == 1) & (morseToSend.IsRunning() == false)){ if((yourInputSend == 1) & (morseToSend.IsRunning() == false)){
@ -597,25 +653,25 @@ void loop() {
morseToSend_blink.Update(); morseToSend_blink.Update();
// if you want to send cycle code and it is sending, keep sending // if you want to send cycle code and it is sending, keep sending
} else if((yourInputSend == 2) & (programRunning == true) &(morses_sequence.Update() == true)){ } else if((yourInputSend == 2) & (programRunning == true) &(morses_sequence_blink.Update() == true)){
morseToSend.Update(); morseToSend.Update();
//morseToSend_blink.Update(); //morseToSend_blink.Update();
morses_sequence.Update(); morses_sequence_blink.Update();
// if you want to send cycle code and it's not sending, then start it up // if you want to send cycle code and it's not sending, then start it up
} else if((yourInputSend == 2) & (programRunning == true) & (morses_sequence.Update() == false)){ } else if((yourInputSend == 2) & (programRunning == true) & (morses_sequence_blink.Update() == false)){
morseToSend.Reset().Update(); morseToSend.Reset().Update();
//morseToSend_blink.Reset().Update(); //morseToSend_blink.Reset().Update();
morses_sequence.Reset(); morses_sequence_blink.Reset();
// if the cycle program is not running // if the cycle program is not running
} else if((yourInputSend == 2 & (programRunning == false))){ } else if((yourInputSend == 2) & (programRunning == false)){
morses_sequence.Stop(); morses_sequence_blink.Stop();
// if you don't want to send code // if you don't want to send code
} else { } else {
// stop sending and make sure the pin is off // stop sending and make sure the pin is off
morseToSend.Stop(JLed::eStopMode::FULL_OFF).Update(); morseToSend.Stop(JLed::eStopMode::FULL_OFF).Update();
morseToSend_blink.Stop(JLed::eStopMode::FULL_OFF).Update(); morseToSend_blink.Stop(JLed::eStopMode::FULL_OFF).Update();
morses_sequence.Stop(); morses_sequence_blink.Stop();
} }
//morseToSend.Update(); //morseToSend.Update();