vulpes/vulpes/src/main.cpp

755 lines
28 KiB
C++
Raw Normal View History

2023-08-22 12:23:47 -05:00
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-input-data-html-form/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
// include wifi password
#include "config.h"
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <SPIFFS.h>
#include <Preferences.h>
2023-08-26 20:55:28 -05:00
#include <arduino-timer.h>
2023-09-13 20:24:57 -05:00
#include "morse.h"
#include <jled.h> // jled
2023-08-30 22:10:29 -05:00
#include "jled/morse.h" //jled
2023-09-02 18:45:50 -05:00
#include <Adafruit_BusIO_Register.h> // for DS3231
#include <RTClib.h> // for DS3231
2023-09-05 20:41:55 -05:00
#include <string>
2023-08-22 12:23:47 -05:00
// download zip from https://github.com/me-no-dev/ESPAsyncWebServer and install.
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);
2023-09-13 21:06:16 -05:00
// Assign output variables to GPIO pins
const int keyer = 32; //LED_BUILTIN for on-board (dev);//26 for LED; //32 for transmitter keyer
const int blinker = LED_BUILTIN;
RTC_DS3231 rtc; // set up RTC
2023-09-08 10:39:24 -05:00
const int alarmPin = 4; // pin to monitor for RTC alarms
2023-09-02 18:45:50 -05:00
2023-08-22 12:23:47 -05:00
// Read from config.h
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASSWORD;
const char* PARAM_STRING = "inputString";
const char* PARAM_SEND = "inputSend";
2023-08-31 21:35:49 -05:00
const char* PARAM_WPM = "inputWPM";
const char* PARAM_MSG = "inputMsg";
2023-08-22 12:23:47 -05:00
const char* PARAM_FLOAT = "inputFloat";
2023-09-02 18:45:50 -05:00
const char* PARAM_TIME = "inputTimeUnix";
const char* PARAM_START = "inputStartTimeUnix";
2023-09-05 20:41:55 -05:00
const char* PARAM_RUNNING = "programRunning";
2023-09-10 12:35:02 -05:00
const char* PARAM_STEPLENGTH = "inputStepLength";
const char* PARAM_CYCLEID = "inputCycleID";
const char* PARAM_NTRANS = "inputNtransmitters";
2023-08-22 12:23:47 -05:00
// Global variables
String yourInputString;
int yourInputSend;
2023-08-31 21:35:49 -05:00
int yourInputWPM;
2023-09-01 10:01:49 -05:00
int yourInputMsg;
int yourInputMsg_old; // to save previous state and check changes
float yourInputFloat;
uint32_t yourInputTime; //to keep time
uint32_t yourInputStartTimeUnix;
bool startProgram;
bool programRunning;
2023-09-10 12:35:02 -05:00
int yourInputStepLength;
int yourInputCycleID;
int yourInputNtransmitters;
int step_length = 10000; // 10 secs
2023-09-08 22:55:31 -05:00
int cycle_id = 1; // number of this transmitter in cycle
int n_transmitters = 2; //number of transmitters total
2023-09-14 12:44:10 -05:00
long start_millis = 0;
long stop_millis = 0;
long pause_millis = 0;
// HTML web page to handle 3 input fields (inputString, inputSend, inputFloat)
2023-08-22 12:23:47 -05:00
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
2023-09-06 20:14:16 -05:00
<link rel="icon" href="data:,">
2023-08-22 12:23:47 -05:00
<title>ESP Input Form</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
2023-09-06 18:02:07 -05:00
<script type="text/javascript">
// Utility from https://webreflection.medium.com/using-the-input-datetime-local-9503e7efdce
Date.prototype.toDatetimeLocal = function toDatetimeLocal() {
var
date = this,
ten = function (i) {
return (i < 10 ? '0' : '') + i;
},
YYYY = date.getFullYear(),
MM = ten(date.getMonth() + 1),
DD = ten(date.getDate()),
HH = ten(date.getHours()),
II = ten(date.getMinutes()),
SS = ten(date.getSeconds())
;
return YYYY + '-' + MM + '-' + DD + 'T' +
HH + ':' + II + ':' + SS;
}
2023-09-06 21:52:04 -05:00
// Submit timestamps as unix seconds when form is submitted
2023-09-02 20:02:59 -05:00
var putDate = function(form) {
form.inputTimeUnix.value = Math.floor(Date.now() / 1000);// - new Date().getTimezoneOffset()*60;
2023-09-06 20:14:16 -05:00
form.inputStartTimeUnix.value = ((Date.parse(js_start_time_unix_entry.value))/1000);
//document.getElementById("js_start_time_unix").value = ((Date.parse(js_start_time_unix_entry.value))/1000);
2023-09-06 18:02:07 -05:00
}
2023-09-06 21:52:04 -05:00
// Fill in page values
window.onload = function() {
2023-09-06 18:08:36 -05:00
s = %inputStartTimeUnix%;
current_start = new Date(s * 1000);
document.getElementById('current-start').innerHTML = current_start.toLocaleString();
// Show the local time as a string
local_time_unix = new Date().toLocaleString();//toUTCString();
document.getElementById('local-time-unix').innerHTML = local_time_unix.toString();
2023-09-06 21:52:04 -05:00
// Fill in the start time field as local time
document.getElementById('js_start_time_unix_entry').value = current_start.toDatetimeLocal();
2023-09-06 21:52:04 -05:00
// Fill in the other form fields
document.getElementById("send-program").value = %inputSend%;
document.getElementById("message").value = %inputMsg%;
}
2023-08-22 12:23:47 -05:00
</script></head><body>
2023-09-10 12:35:02 -05:00
<h1>Vulpes Radio Orienteering Controller</h1>
<p>Local time: <b><span id=local-time-unix></span></b></p>
2023-09-05 21:11:31 -05:00
2023-09-06 21:36:10 -05:00
<form action="/get" onsubmit="putDate(this);" accept-charset=utf-8>
2023-09-10 12:35:02 -05:00
<h2>General Settings</h2>
<p>Sending program:
<select name="inputSend" id="send-program">
2023-09-06 21:52:04 -05:00
<option value="0" >0 - Off</option>
2023-09-01 14:15:54 -05:00
<option value="1">1 - Continuous</option>
<option value="2">2 - Cycle</option>
2023-08-31 11:52:11 -05:00
</select><br>
2023-08-31 21:35:49 -05:00
2023-09-10 12:35:02 -05:00
Message:
2023-08-31 21:35:49 -05:00
<select name="inputMsg" id="message">
<option value="0">0 - TEST TEST TEST DE W1CDN</option>
2023-09-01 14:15:54 -05:00
<option value="1">1 - MOE</option>
<option value="2">2 - MOI</option>
<option value="3">3 - MOS</option>
<option value="4">4 - MOH</option>
<option value="5">5 - MO5</option>
2023-09-05 20:41:55 -05:00
</select></p>
2023-09-10 12:35:02 -05:00
<h2>Cycle Settings</h2>
2023-09-11 21:09:27 -05:00
<p>Only applies when <em>Sending Program</em> is set to "2 - Cycle". You cannot set a cycle start date more than a month in advance.</p>
<p>Cycle start time <input type="datetime-local" id="js_start_time_unix_entry" /><br>
2023-09-11 21:09:27 -05:00
Current value: <b><span id=current-start></span></b>
2023-09-05 20:41:55 -05:00
<!-- 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. -->
<input type="hidden" name="inputStartTimeUnix" id="js_start_time_unix" /></p>
2023-09-10 12:35:02 -05:00
<p>
2023-09-11 21:09:27 -05:00
Step length: <input type="number" name="inputStepLength" min=1000 step=1000 value = %inputStepLength%> milliseconds <br>
Cycle ID: <input type="number" name="inputCycleID" min=1 value = %inputCycleID%><br>
Number of transmitters: <input type="number" name="inputNtransmitters" min=1 value = %inputNtransmitters%><br>
2023-09-10 12:35:02 -05:00
</p>
2023-09-05 20:41:55 -05:00
<!-- This field is hidden so people don't change the submit time (it will be wrong).
The value is automatically filled in with JS. -->
<input type="hidden" name="inputTimeUnix" id="js_time_unix">
2023-09-02 18:45:50 -05:00
<!-- Extra fields just in case I need them -->
2023-09-05 20:41:55 -05:00
<input type="hidden" name="inputWPM" value = %inputWPM%>
2023-09-06 20:14:16 -05:00
<input type="hidden" name="inputString" value = %inputString%>
2023-09-05 20:41:55 -05:00
<input type="hidden" name="inputFloat" value = %inputFloat%>
2023-09-02 22:13:11 -05:00
<input type="submit" value="Submit"">
2023-08-22 12:23:47 -05:00
</form>
<iframe style="display:none" name="hidden-form" id="hidden-form"></iframe>
2023-09-06 20:14:16 -05:00
<script type="text/javascript">
</script>
2023-08-22 12:23:47 -05:00
</body></html>)rawliteral";
2023-08-26 20:55:28 -05:00
2023-08-22 12:23:47 -05:00
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
String readFile(fs::FS &fs, const char * path){
2023-08-22 14:13:47 -05:00
//Serial.printf("Reading file: %s\r\n", path);
2023-08-22 12:23:47 -05:00
File file = fs.open(path, "r");
if(!file || file.isDirectory()){
Serial.println("- empty file or failed to open file");
return String();
}
2023-08-22 14:13:47 -05:00
//Serial.println("- read from file:");
2023-08-22 12:23:47 -05:00
String fileContent;
while(file.available()){
fileContent+=String((char)file.read());
}
file.close();
2023-08-22 14:13:47 -05:00
//Serial.println(fileContent);
2023-08-22 12:23:47 -05:00
return fileContent;
}
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, "w");
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
file.close();
}
2023-08-31 11:52:11 -05:00
// Replaces placeholder in web UI with stored values
2023-08-22 12:23:47 -05:00
String processor(const String& var){
//Serial.println(var);
if(var == "inputString"){
return readFile(SPIFFS, "/inputString.txt");
}
else if(var == "inputSend"){
return readFile(SPIFFS, "/inputSend.txt");
2023-08-22 12:23:47 -05:00
}
2023-08-31 21:35:49 -05:00
else if(var == "inputWPM"){
return readFile(SPIFFS, "/inputWPM.txt");
}
else if(var == "inputMsg"){
return readFile(SPIFFS, "/inputMsg.txt");
}
2023-09-10 12:35:02 -05:00
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");
}
2023-08-22 12:23:47 -05:00
else if(var == "inputFloat"){
return readFile(SPIFFS, "/inputFloat.txt");
} else if(var == "inputStartTimeUnix"){
2023-09-06 20:14:16 -05:00
// Webform breaks if this value is empty.
2023-09-06 18:08:36 -05:00
String temp = readFile(SPIFFS, "/inputStartTimeUnix.txt");
if(temp == ""){
temp = "0";
}
return temp;
2023-09-05 20:41:55 -05:00
}
2023-08-22 12:23:47 -05:00
return String();
}
2023-09-13 21:06:16 -05:00
// Set up arduinomorse pin and default WPM
LEDMorseSender sender(blinker, 10.0f); // the 'f' makes sure this is a float
// TODO also for keyer once blinker works
// Timers
Timer<1> timer;
//jled from https://github.com/jandelgado/jled/blob/master/examples/morse/morse_effect.h
class MorseEffect : public jled::BrightnessEvaluator {
Morse morse_;
// duration of a single 'dit' in ms
const uint16_t speed_;
public:
explicit MorseEffect(const char* message, uint16_t speed = 200)
: morse_(message), speed_(speed) {}
uint8_t Eval(uint32_t t) const override {
const auto pos = t / speed_;
if (pos >= morse_.size()) return 0;
return morse_.test(pos) ? 255 : 0;
}
uint16_t Period() const override { return (morse_.size() + 1) * speed_; }
};
// Speed is milliseconds per dit, which is 1000 * (60 / (50 * WPM))
// 60 is 20 wpm, 120 is 10 wpm, 90 is 15 wpm, etc.
// https://morsecode.world/international/timing.html
2023-09-01 14:15:54 -05:00
float wpm = 10;
float ms_per_dit = 1000 * (60 / (50 * wpm));
2023-08-31 21:35:49 -05:00
int word_space_ms = ms_per_dit * 7;
2023-09-02 18:45:50 -05:00
// Hardcoding messages and WPM for now, will come back and make it more flexible.
// Extra space at the end to get around https://github.com/jandelgado/jled/issues/122 on cycle mode
2023-09-11 21:09:27 -05:00
MorseEffect morseEffectTEST("TEST TEST TEST DE W1CDN", ms_per_dit);
MorseEffect morseEffectMOE("MOE", ms_per_dit);
MorseEffect morseEffectMOI("MOI", ms_per_dit);
MorseEffect morseEffectMOS("MOS", ms_per_dit);
MorseEffect morseEffectMOH("MOH", ms_per_dit);
MorseEffect morseEffectMO5("MO5", ms_per_dit);
2023-08-31 21:35:49 -05:00
2023-09-04 20:23:14 -05:00
// CW for keyer
auto morseTEST =
2023-09-04 20:23:14 -05:00
JLed(keyer).UserFunc(&morseEffectTEST).DelayAfter(word_space_ms).Forever();
2023-08-31 21:35:49 -05:00
auto morseMOE =
2023-09-04 20:23:14 -05:00
JLed(keyer).UserFunc(&morseEffectMOE).DelayAfter(word_space_ms).Forever();
2023-08-31 21:35:49 -05:00
auto morseMOI =
2023-09-04 20:23:14 -05:00
JLed(keyer).UserFunc(&morseEffectMOI).DelayAfter(word_space_ms).Forever();
2023-08-31 21:35:49 -05:00
auto morseMOS =
2023-09-04 20:23:14 -05:00
JLed(keyer).UserFunc(&morseEffectMOS).DelayAfter(word_space_ms).Forever();
2023-08-31 21:35:49 -05:00
auto morseMOH =
2023-09-04 20:23:14 -05:00
JLed(keyer).UserFunc(&morseEffectMOH).DelayAfter(word_space_ms).Forever();
2023-08-31 21:35:49 -05:00
auto morseMO5 =
2023-09-04 20:23:14 -05:00
JLed(keyer).UserFunc(&morseEffectMO5).DelayAfter(word_space_ms).Forever();
auto morseToSend = morseTEST; // set this up to overwrite later
2023-09-04 20:23:14 -05:00
// CW for blinker
2023-09-13 21:54:43 -05:00
// auto morseTEST_blink =
// JLed(blinker).UserFunc(&morseEffectTEST).DelayAfter(word_space_ms).Forever();
// auto morseMOE_blink =
// JLed(blinker).UserFunc(&morseEffectMOE).DelayAfter(word_space_ms).Forever();
// auto morseMOI_blink =
// JLed(blinker).UserFunc(&morseEffectMOI).DelayAfter(word_space_ms).Forever();
// auto morseMOS_blink =
// JLed(blinker).UserFunc(&morseEffectMOS).DelayAfter(word_space_ms).Forever();
// auto morseMOH_blink =
// JLed(blinker).UserFunc(&morseEffectMOH).DelayAfter(word_space_ms).Forever();
// auto morseMO5_blink =
// JLed(blinker).UserFunc(&morseEffectMO5).DelayAfter(word_space_ms).Forever();
// auto morseToSend_blink = morseTEST_blink; // set this up to overwrite later
2023-09-04 20:23:14 -05:00
// Cycle stuff
2023-09-13 21:54:43 -05:00
// auto morse_cycle = morseEffectMOS;
// int period = morse_cycle.Period() + word_space_ms;
// int repeats = step_length / period;
// int remainder_wait = step_length - (period * repeats);
// int total_wait = ((step_length * (n_transmitters - 1) + remainder_wait));
// auto blinker_continuous = JLed(blinker).UserFunc(&morse_cycle).Repeat(repeats).DelayAfter(word_space_ms);
// auto blinker_continuous_wait = JLed(blinker).Off(total_wait);
// JLed morses_blink[] = {
// blinker_continuous,
// blinker_continuous_wait
// };
// auto morses_sequence_blink = JLedSequence(JLedSequence::eMode::SEQUENCE, morses_blink);
// JLedSequence* sequence = NULL;
// JLedSequence* make_sequence(JLedSequence* seq, const char* message, int wpm, int step_length, int n_transmitters){
// int ms_per_dit = 60;//1000 * (60 / (50 * wpm));
// int word_space_ms = ms_per_dit * 7;
// MorseEffect morse_effect(message, ms_per_dit);
// int period = morse_effect.Period();
// int repeats = 2;//step_length / period;
// int remainder_wait = step_length - (period * repeats);
// int total_wait = ((step_length * (n_transmitters - 1) + remainder_wait));
// Serial.print("total_wait: "); Serial.println(total_wait);
// JLed morses_blink[] = {
// JLed(blinker).UserFunc(&morse_effect).Repeat(repeats).DelayAfter(word_space_ms),
// JLed(blinker).Off(total_wait)
// };
// if (seq){
// delete seq;
// //seq = new JLedSequence(JLedSequence::eMode::SEQUENCE, leds);
// seq = new JLedSequence(JLedSequence::eMode::SEQUENCE, morses_blink);
// }
// return seq;
// }
// // Initial definition of the sequence
// JLedSequence* morses_sequence_blink_test = make_sequence(sequence, "MOE", 10, 10000, 2);
2023-09-12 21:32:11 -05:00
2023-09-05 20:41:55 -05:00
//================================================================================
// start_program(): a function to start the planned program at the planned time
//================================================================================
2023-09-11 21:09:27 -05:00
// bool start_program(){
// Serial.println("The scheduled program has started.");
// startProgram = true;
// return false;
// }
2023-09-05 20:41:55 -05:00
2023-08-27 22:35:16 -05:00
//================================================================================
// setup(): stuff that only gets done once, after power up (KB1OIQ's description)
//================================================================================
2023-08-22 12:23:47 -05:00
void setup() {
Serial.begin(115200);
2023-08-22 14:13:47 -05:00
2023-09-13 21:06:16 -05:00
// Get arduinomorse ready to go
sender.setup();
2023-09-12 21:32:11 -05:00
2023-09-08 10:39:24 -05:00
pinMode(alarmPin, INPUT_PULLUP); // Set alarm pin as pullup
2023-09-02 18:45:50 -05:00
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(__DATE__, __TIME__));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2023, 9, 2, 17, 32, 0));
}
2023-09-10 12:35:02 -05:00
// Report the RTC time
Serial.print("RTC time on startup: ");
Serial.println(rtc.now().unixtime());
Serial.println(rtc.now().timestamp());
2023-09-08 10:39:24 -05:00
// Are there any RTC alarms set?
DateTime alarm_one = rtc.getAlarm1(); // Get the current time
char buff[] = "Alarm 1 set for at hh:mm:ss DDD, DD MMM YYYY";
Serial.print(alarm_one.toString(buff));
Serial.println(" (only HH:MM:SS day-of-month are accurate)");
2023-09-08 10:39:24 -05:00
2023-08-22 14:13:47 -05:00
// Initialize the output variables as outputs
2023-09-04 20:23:14 -05:00
pinMode(keyer, OUTPUT);
2023-09-13 21:54:43 -05:00
//pinMode(blinker, OUTPUT);
2023-08-22 14:13:47 -05:00
// Set outputs to LOW
2023-09-04 20:23:14 -05:00
digitalWrite(keyer, LOW);
2023-09-13 21:54:43 -05:00
//digitalWrite(blinker, LOW);
2023-08-22 14:13:47 -05:00
2023-08-22 12:23:47 -05:00
// Initialize SPIFFS
SPIFFS.begin(true);
2023-08-22 12:23:47 -05:00
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
if(!SPIFFS.begin()){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
2023-09-08 15:07:57 -05:00
2023-08-26 20:55:28 -05:00
// Read in existing data
yourInputString = readFile(SPIFFS, "/inputString.txt");
yourInputSend = readFile(SPIFFS, "/inputSend.txt").toInt();
2023-08-31 21:35:49 -05:00
yourInputWPM = readFile(SPIFFS, "/inputWPM.txt").toInt();
yourInputMsg = readFile(SPIFFS, "/inputMsg.txt").toInt();
yourInputFloat = readFile(SPIFFS, "/inputFloat.txt").toFloat();
yourInputStartTimeUnix = readFile(SPIFFS, "/inputStartTimeUnix.txt").toInt();
2023-09-10 12:35:02 -05:00
yourInputStepLength = readFile(SPIFFS, "/inputStepLength.txt").toInt();
yourInputCycleID = readFile(SPIFFS, "/inputCycleID.txt").toInt();
yourInputNtransmitters = readFile(SPIFFS, "/inputNtransmitters.txt").toInt();
2023-08-26 20:55:28 -05:00
2023-09-01 10:01:49 -05:00
// On restart, keep doing what you were doing before
yourInputMsg_old = yourInputMsg;
if(yourInputMsg == 0){
2023-09-13 21:54:43 -05:00
// morseToSend = morseTEST;
// morseToSend_blink = morseTEST_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("test test test de w1cdn "));
2023-09-01 10:01:49 -05:00
} else if(yourInputMsg == 1){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOE;
// morseToSend_blink = morseMOE_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("moe "));
2023-09-01 10:01:49 -05:00
} else if(yourInputMsg == 2){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOI;
// morseToSend_blink = morseMOI_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("moi "));
2023-09-01 10:01:49 -05:00
} else if(yourInputMsg == 3){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOS;
// morseToSend_blink = morseMOS_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("mos "));
2023-09-01 10:01:49 -05:00
} else if(yourInputMsg == 4){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOH;
// morseToSend_blink = morseMOH_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("moh "));
2023-09-01 10:01:49 -05:00
} else if(yourInputMsg == 5){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMO5;
// morseToSend_blink = morseMO5_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("mo5 "));
2023-09-01 10:01:49 -05:00
}
2023-09-13 21:54:43 -05:00
//sender.startSending();
2023-09-01 10:01:49 -05:00
2023-08-22 12:23:47 -05:00
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Send web page with input fields to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/get?inputString=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET inputString value on <ESP_IP>/get?inputString=<inputMessage>
if (request->hasParam(PARAM_STRING)) {
inputMessage = request->getParam(PARAM_STRING)->value();
writeFile(SPIFFS, "/inputString.txt", inputMessage.c_str());
yourInputString = inputMessage;
2023-08-22 12:23:47 -05:00
}
// GET inputSend value on <ESP_IP>/get?inputSend=<inputMessage>
if (request->hasParam(PARAM_SEND)) {
inputMessage = request->getParam(PARAM_SEND)->value();
writeFile(SPIFFS, "/inputSend.txt", inputMessage.c_str());
yourInputSend = inputMessage.toInt();
2023-09-05 20:41:55 -05:00
// if not running a program, set the program running off
if(yourInputSend != 2){
startProgram = false;
programRunning = false;
2023-09-05 20:41:55 -05:00
}
2023-08-22 12:23:47 -05:00
}
2023-08-31 21:35:49 -05:00
// GET inputWPM value on <ESP_IP>/get?inputWPM=<inputMessage>
if (request->hasParam(PARAM_WPM)) {
inputMessage = request->getParam(PARAM_WPM)->value();
writeFile(SPIFFS, "/inputWPM.txt", inputMessage.c_str());
yourInputWPM = inputMessage.toInt();
}
// GET inputMsg value on <ESP_IP>/get?inputMsg=<inputMessage>
if (request->hasParam(PARAM_MSG)) {
inputMessage = request->getParam(PARAM_MSG)->value();
writeFile(SPIFFS, "/inputMsg.txt", inputMessage.c_str());
// save previous state
yourInputMsg_old = yourInputMsg;
2023-08-31 21:35:49 -05:00
yourInputMsg = inputMessage.toInt();
}
2023-09-10 12:35:02 -05:00
// 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();
}
2023-09-02 18:45:50 -05:00
// GET inputTimeUnix value on <ESP_IP>/get?inputTimeUnix=<inputMessage>
if (request->hasParam(PARAM_TIME)) {
inputMessage = request->getParam(PARAM_TIME)->value();
//https://stackoverflow.com/a/22733127/2152245
yourInputTime = atol(inputMessage.c_str());
Serial.print("yourInputTime: ");
2023-09-02 18:45:50 -05:00
Serial.println(yourInputTime);
2023-09-02 20:02:59 -05:00
// update the RTC time
rtc.adjust(DateTime(yourInputTime));
DateTime now = rtc.now();
// Might work to fix random errors? If date is far in the future,
// try to update again.
// replace if with while if you want it to try a bunch...
if(now.year() > 2040){
Serial.print("Year is ");
Serial.println(now.year());
Serial.println("RTC can't set time. Trying again.");
rtc.adjust(DateTime(yourInputTime));
}
Serial.print("UTC time from browser: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(now.dayOfTheWeek());
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print("rtc.now().unixtime(): ");
Serial.println(rtc.now().unixtime());
2023-09-02 18:45:50 -05:00
}
2023-08-22 12:23:47 -05:00
// GET inputFloat value on <ESP_IP>/get?inputFloat=<inputMessage>
if (request->hasParam(PARAM_FLOAT)) {
2023-08-22 12:23:47 -05:00
inputMessage = request->getParam(PARAM_FLOAT)->value();
writeFile(SPIFFS, "/inputFloat.txt", inputMessage.c_str());
yourInputFloat = inputMessage.toFloat();
2023-08-22 12:23:47 -05:00
}
// GET inputStartTimeUnix value on <ESP_IP>/get?inputStartTimeUnix=<inputMessage>
if (request->hasParam(PARAM_START)) {
inputMessage = request->getParam(PARAM_START)->value();
2023-09-05 20:41:55 -05:00
Serial.println(inputMessage);
// if a start time isn't entered, don't overwrite the old one
//if(!(inputMessage != NULL && inputMessage[0] == '\0')){
writeFile(SPIFFS, "/inputStartTimeUnix.txt", inputMessage.c_str());
yourInputStartTimeUnix = atol(inputMessage.c_str());
//}
Serial.println(yourInputStartTimeUnix);
2023-09-08 08:39:14 -05:00
// Use alarm built into RTC
rtc.setAlarm1(DateTime(yourInputStartTimeUnix), DS3231_A1_Date);
2023-09-08 08:39:14 -05:00
//rtc.setAlarm1(DateTime(2020, 6, 25, 15, 34, 0), DS3231_A2_Date);
DateTime alarm_one = rtc.getAlarm1(); // Get the current alarm time
char buff[] = "Alarm 1 set for at hh:mm:ss DDD, DD MMM YYYY";
Serial.print(alarm_one.toString(buff));
Serial.println(" (only HH:MM:SS day-of-month are accurate)");
}
2023-09-07 20:20:53 -05:00
// https://techtutorialsx.com/2018/01/14/esp32-arduino-http-server-external-and-internal-redirects/
2023-09-06 21:36:10 -05:00
request->redirect("/");
2023-08-22 12:23:47 -05:00
});
server.onNotFound(notFound);
server.begin();
2023-08-27 22:35:16 -05:00
2023-08-22 12:23:47 -05:00
}
void loop() {
2023-08-26 20:55:28 -05:00
// Timers
timer.tick();
2023-09-13 21:06:16 -05:00
//morses_sequence_blink_test->Forever().Update();
2023-09-12 21:32:11 -05:00
2023-09-10 12:35:02 -05:00
// See which message we are sending
// Only do this when the message has been updated.
if(yourInputMsg != yourInputMsg_old){
2023-09-01 14:15:54 -05:00
//morseToSend.Stop(JLed::eStopMode::FULL_OFF).Update();
2023-09-08 22:55:31 -05:00
if(yourInputMsg == 0){
2023-09-13 21:54:43 -05:00
// morseToSend = morseTEST;
//morseToSend_blink = morseTEST_blink;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("test test test de w1cdn "));
2023-09-08 22:55:31 -05:00
} else if(yourInputMsg == 1){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOE;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("moe "));
2023-09-13 21:54:43 -05:00
// morseToSend_blink = morseMOE_blink;
2023-09-08 22:55:31 -05:00
} else if(yourInputMsg == 2){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOI;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("moi "));
2023-09-13 21:54:43 -05:00
// morseToSend_blink = morseMOI_blink;
2023-09-08 22:55:31 -05:00
} else if(yourInputMsg == 3){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOS;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("mos "));
2023-09-13 21:54:43 -05:00
// morseToSend_blink = morseMOS_blink;
2023-09-08 22:55:31 -05:00
} else if(yourInputMsg == 4){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMOH;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("moh "));
2023-09-13 21:54:43 -05:00
// morseToSend_blink = morseMOH_blink;
2023-09-08 22:55:31 -05:00
} else if(yourInputMsg == 5){
2023-09-13 21:54:43 -05:00
// morseToSend = morseMO5;
2023-09-13 21:06:16 -05:00
sender.setMessage(String("mo5 "));
2023-09-13 21:54:43 -05:00
// morseToSend_blink = morseMO5_blink;
2023-09-08 22:55:31 -05:00
}
// Keeps the key/led from locking up
yourInputMsg_old = yourInputMsg;
}
2023-08-31 21:35:49 -05:00
2023-09-10 12:35:02 -05:00
// 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){
2023-09-11 21:09:27 -05:00
//auto morse_cycle = morseEffectMOS;
//int period = morse_cycle.Period() + word_space_ms;
//int repeats = step_length / period;
//int remainder_wait = step_length - (period * repeats);
//int total_wait = ((step_length * (n_transmitters - 1) + remainder_wait));
// Nothing makes it out of this scope...
// blinker_continuous = JLed(blinker).UserFunc(&morse_cycle).Repeat(repeats).DelayAfter(word_space_ms);
// blinker_continuous_wait = JLed(blinker).Off(total_wait);
// JLed morses_blink[] = {
// blinker_continuous,
// blinker_continuous_wait
// };
// auto morses_sequence_blink = JLedSequence(JLedSequence::eMode::SEQUENCE, morses_blink);
2023-09-13 21:06:16 -05:00
//morses_sequence_blink.Forever().Update();
Serial.println("Start sending");
2023-09-14 12:44:10 -05:00
//int period = morse_cycle.Period() + word_space_ms;
//int repeats = step_length / period;
//int remainder_wait = step_length - (period * repeats);
//int total_wait = ((step_length * (n_transmitters - 1)));
start_millis = millis();
stop_millis = start_millis + step_length;
pause_millis = stop_millis + step_length;
2023-09-13 21:06:16 -05:00
sender.startSending(); //arduinomorse
2023-09-10 12:35:02 -05:00
programRunning = true;
startProgram = false;
2023-09-13 21:06:16 -05:00
// Serial.println(yourInputSend);
// Serial.println(programRunning);
2023-09-10 12:35:02 -05:00
}
2023-08-31 21:35:49 -05:00
// if you want to send continuous code, and it's not sending, then start it up
2023-09-14 16:36:22 -05:00
if((yourInputSend == 1)){;// & (morseToSend.IsRunning() == false)){
//jled
2023-09-13 21:54:43 -05:00
// morseToSend.Reset().Update();
// morseToSend_blink.Reset().Update();
2023-09-14 16:36:22 -05:00
if (!sender.continueSending()){
// Set the internal counters to the message's beginning.
// Here, this results in repeating the message indefinitely.
sender.startSending();
}
2023-08-30 22:10:29 -05:00
// if you want to send continuous code, and it is sending, keep sending
2023-09-14 16:36:22 -05:00
// } else if((yourInputSend == 1) & (morseToSend.IsRunning() == true)){
2023-09-13 21:06:16 -05:00
//morseToSend.Update();
2023-09-08 22:55:31 -05:00
//morseToSend_blink.Update();
2023-09-13 21:54:43 -05:00
// if you want to send cycle code and it is sending, keep sending
// } else if((yourInputSend == 2) & (programRunning == true)){//&(morses_sequence_blink.Update() == true)
// //morseToSend.Update();
// //morseToSend_blink.Update();
// //morses_sequence_blink.Update();
// //Serial.println("Continue cycle");
// sender.continueSending();
// if you want to send cycle code and it's not sending, then start it up
2023-09-13 21:54:43 -05:00
} else if((yourInputSend == 2) & (programRunning == true)){//& (morses_sequence_blink.Update() == false)
//morseToSend.Reset().Update();
//morseToSend_blink.Reset().Update();
//morses_sequence_blink.Reset();
//Serial.println("Start up cycle");
2023-09-14 12:44:10 -05:00
if((millis() > start_millis) & (millis() < stop_millis)){
if (!sender.continueSending()){
// Set the internal counters to the message's beginning.
// Here, this results in repeating the message indefinitely.
sender.startSending();
}
} else if((millis() > stop_millis) & (millis() < pause_millis)){
2023-09-14 12:46:35 -05:00
// do nothing in this case -- in between cycles
2023-09-14 12:44:10 -05:00
} else if((millis() > pause_millis)){
startProgram = true;
2023-09-13 21:54:43 -05:00
}
// if the cycle program is not running
2023-09-10 12:35:02 -05:00
} else if((yourInputSend == 2) & (programRunning == false)){
2023-09-13 21:06:16 -05:00
//Serial.println("Program is over, stop sending")
//morses_sequence_blink.Stop();
//sender.setMessage(String(""));
// if you don't want to send code
2023-09-14 12:44:10 -05:00
} else if(yourInputSend == 0){
2023-09-13 21:54:43 -05:00
//Serial.println("Stop sending");
// stop sending and make sure the pin is off
2023-09-13 21:54:43 -05:00
// morseToSend.Stop(JLed::eStopMode::FULL_OFF).Update();
// morseToSend_blink.Stop(JLed::eStopMode::FULL_OFF).Update();
2023-09-13 21:06:16 -05:00
//morses_sequence_blink.Stop();
2023-09-14 16:36:22 -05:00
sender.setMessage(String("")); // Not sure this is the right way to stop things.
}
//morseToSend.Update();
2023-09-13 21:06:16 -05:00
//sender.continueSending();
2023-08-22 12:23:47 -05:00
}