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"
2023-08-30 22:04:32 -05:00
# 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 ;
2023-09-02 22:11:51 -05:00
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 " ;
2023-08-31 20:41:24 -05:00
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 " ;
2023-09-04 21:53:09 -05:00
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
2023-08-31 09:10:30 -05:00
// Global variables
String yourInputString ;
2023-08-31 20:41:24 -05:00
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
2023-08-31 09:10:30 -05:00
float yourInputFloat ;
2023-09-02 22:11:51 -05:00
uint32_t yourInputTime ; //to keep time
2023-09-04 21:53:09 -05:00
uint32_t yourInputStartTimeUnix ;
2023-09-09 16:01:41 -05:00
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
2023-09-09 12:53:34 -05:00
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 ;
2023-08-31 09:10:30 -05:00
2023-08-31 20:41:24 -05:00
// 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 " >
2023-09-06 21:21:05 -05:00
// 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 ) {
2023-09-06 21:21:05 -05:00
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
2023-09-05 11:08:01 -05:00
window . onload = function ( ) {
2023-09-06 18:08:36 -05:00
s = % inputStartTimeUnix % ;
2023-09-05 16:55:42 -05:00
current_start = new Date ( s * 1000 ) ;
2023-09-06 21:21:05 -05:00
document . getElementById ( ' current - start ' ) . innerHTML = current_start . toLocaleString ( ) ;
// Show the local time as a string
local_time_unix = new Date ( ) . toLocaleString ( ) ; //toUTCString();
2023-09-06 16:57:57 -05:00
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
2023-09-06 21:21:05 -05:00
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-09-05 11:08:01 -05:00
}
2023-09-05 16:55:42 -05:00
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 >
2023-09-06 16:57:57 -05:00
< 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 :
2023-08-31 20:41:24 -05:00
< 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 >
2023-09-08 15:00:48 -05:00
< 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 " >
2023-09-04 17:26:03 -05:00
< 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 >
2023-09-08 15:00:48 -05:00
< 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
2023-09-04 21:53:09 -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-04 21:53:09 -05:00
2023-09-02 22:13:11 -05:00
< input type = " submit " value = " Submit " " >
2023-08-22 12:23:47 -05:00
< / form >
2023-09-05 11:08:01 -05:00
< 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 " ) ;
}
2023-08-31 20:41:24 -05:00
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 " ) ;
2023-09-04 21:53:09 -05:00
} 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 ;
2023-08-30 22:04:32 -05:00
//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_ ;
2023-08-29 20:24:17 -05:00
2023-08-30 22:04:32 -05:00
public :
explicit MorseEffect ( const char * message , uint16_t speed = 200 )
: morse_ ( message ) , speed_ ( speed ) { }
2023-08-29 20:24:17 -05:00
2023-08-30 22:04:32 -05:00
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.
2023-09-09 13:14:28 -05:00
// 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
2023-09-04 17:26:03 -05:00
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 ( ) ;
2023-09-04 17:26:03 -05:00
auto morseToSend = morseTEST ; // set this up to overwrite later
2023-08-29 20:24:17 -05:00
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
2023-09-09 12:53:34 -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-11 21:47:37 -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?
2023-09-08 15:00:48 -05:00
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
2023-08-31 09:10:30 -05:00
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
2023-08-31 09:10:30 -05:00
yourInputString = readFile ( SPIFFS , " /inputString.txt " ) ;
2023-08-31 20:41:24 -05:00
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 ( ) ;
2023-08-31 09:10:30 -05:00
yourInputFloat = readFile ( SPIFFS , " /inputFloat.txt " ) . toFloat ( ) ;
2023-09-05 16:55:42 -05:00
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 ( ) ) ;
2023-08-31 09:10:30 -05:00
yourInputString = inputMessage ;
2023-08-22 12:23:47 -05:00
}
2023-08-31 20:41:24 -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 ) {
2023-09-09 16:01:41 -05:00
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 ( ) ) ;
2023-09-01 09:39:00 -05:00
// 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 ( ) ;
2023-09-02 22:11:51 -05:00
//https://stackoverflow.com/a/22733127/2152245
yourInputTime = atol ( inputMessage . c_str ( ) ) ;
2023-09-06 22:07:48 -05:00
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 ) ) ;
2023-09-08 15:00:48 -05:00
DateTime now = rtc . now ( ) ;
2023-09-06 22:07:48 -05:00
// Might work to fix random errors? If date is far in the future,
// try to update again.
2023-09-08 15:00:48 -05:00
// replace if with while if you want it to try a bunch...
if ( now . year ( ) > 2040 ) {
Serial . print ( " Year is " ) ;
Serial . println ( now . year ( ) ) ;
2023-09-06 22:07:48 -05:00
Serial . println ( " RTC can't set time. Trying again. " ) ;
rtc . adjust ( DateTime ( yourInputTime ) ) ;
}
2023-09-08 15:00:48 -05:00
2023-09-02 22:11:51 -05:00
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 ( ) ;
2023-09-06 22:07:48 -05:00
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>
2023-08-30 22:26:23 -05:00
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 ( ) ) ;
2023-08-31 09:10:30 -05:00
yourInputFloat = inputMessage . toFloat ( ) ;
2023-08-22 12:23:47 -05:00
}
2023-09-04 21:53:09 -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 ( ) ) ;
//}
2023-09-04 21:53:09 -05:00
Serial . println ( yourInputStartTimeUnix ) ;
2023-09-08 08:39:14 -05:00
// Use alarm built into RTC
2023-09-08 15:00:48 -05:00
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);
2023-09-08 15:00:48 -05:00
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-04 21:53:09 -05:00
}
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
2023-08-29 20:24:17 -05:00
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
2023-09-01 09:39:00 -05:00
// 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
}
2023-09-09 16:01:41 -05:00
// Keeps the key/led from locking up
2023-09-04 17:26:03 -05:00
yourInputMsg_old = yourInputMsg ;
2023-09-01 09:39:00 -05:00
}
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...
2023-09-11 21:47:37 -05:00
// 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
2023-08-31 20:41:24 -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)){
2023-08-30 22:04:32 -05:00
//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
2023-08-31 20:41:24 -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();
2023-08-31 20:41:24 -05:00
// 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
}
2023-09-09 16:01:41 -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(""));
2023-08-30 22:04:32 -05:00
// 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");
2023-08-30 22:04:32 -05:00
// 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.
2023-08-30 22:04:32 -05:00
}
2023-09-04 17:26:03 -05:00
//morseToSend.Update();
2023-09-13 21:06:16 -05:00
//sender.continueSending();
2023-08-30 22:04:32 -05:00
2023-08-22 12:23:47 -05:00
}