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-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-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-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-08 22:55:31 -05:00
bool yourProgramRunning ;
bool yourProgramRunning_old ;
int step_length = 30000 ; // 30 secs
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-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-05 21:11:31 -05:00
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-04 21:53:09 -05:00
2023-09-05 20:41:55 -05:00
< p > Sending program ( cycle doesn ' t work yet ) ( current value : < b > % inputSend % < / b > ) :
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-01 14:15:54 -05:00
Message ( current value < b > % inputMsg % < / b > ) :
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-08 15:00:48 -05:00
< 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 .
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 .
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 >
< ! - - 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-22 14:13:47 -05:00
// Assign output variables to GPIO pins
2023-09-04 20:23:14 -05:00
const int keyer = 32 ; //LED_BUILTIN for on-board (dev);//26 for LED; //32 for transmitter keyer
const int blinker = LED_BUILTIN ;
2023-08-22 14:13:47 -05:00
2023-08-26 20:55:28 -05:00
// Timers
2023-08-27 22:35:16 -05:00
//auto timer = timer_create_default();
Timer < 1 > timer ;
2023-08-26 20:55:28 -05:00
// Example from https://github.com/contrem/arduino-timer#examples
bool toggle_led ( void * ) {
2023-09-08 08:39:14 -05:00
//Serial.print("Timer time: ");
//Serial.println(rtc.now().timestamp());
2023-08-26 20:55:28 -05:00
digitalWrite ( LED_BUILTIN , ! digitalRead ( LED_BUILTIN ) ) ; // toggle the LED
return true ; // keep timer active? true
}
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-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-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
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
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-09 12:53:34 -05:00
// Cycle stuff
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 [ ] = {
// 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 = JLedSequence ( JLedSequence : : eMode : : SEQUENCE , morses ) ;
2023-09-08 22:55:31 -05:00
2023-09-05 20:41:55 -05:00
//================================================================================
// start_program(): a function to start the planned program at the planned time
//================================================================================
bool start_program ( ) {
Serial . println ( " The scheduled program has started. " ) ;
2023-09-08 22:55:31 -05:00
yourProgramRunning = true ;
2023-09-05 20:41:55 -05:00
return false ;
}
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-08 21:21:19 -05:00
Serial . print ( " morseEffectTEST.Period(): " ) ;
Serial . println ( morseEffectTEST . Period ( ) ) ;
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-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 ) ;
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 ) ;
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-31 21:35:49 -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-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-04 17:26:03 -05:00
morseToSend = morseTEST ;
2023-09-04 20:23:14 -05:00
morseToSend_blink = morseTEST_blink ;
2023-09-01 10:01:49 -05:00
} else if ( yourInputMsg = = 1 ) {
morseToSend = morseMOE ;
2023-09-04 20:23:14 -05:00
morseToSend_blink = morseMOE_blink ;
2023-09-01 10:01:49 -05:00
} else if ( yourInputMsg = = 2 ) {
morseToSend = morseMOI ;
2023-09-04 20:23:14 -05:00
morseToSend_blink = morseMOI_blink ;
2023-09-01 10:01:49 -05:00
} else if ( yourInputMsg = = 3 ) {
morseToSend = morseMOS ;
2023-09-04 20:23:14 -05:00
morseToSend_blink = morseMOS_blink ;
2023-09-01 10:01:49 -05:00
} else if ( yourInputMsg = = 4 ) {
morseToSend = morseMOH ;
2023-09-04 20:23:14 -05:00
morseToSend_blink = morseMOH_blink ;
2023-09-01 10:01:49 -05:00
} else if ( yourInputMsg = = 5 ) {
morseToSend = morseMO5 ;
2023-09-04 20:23:14 -05:00
morseToSend_blink = morseMO5_blink ;
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-08 22:55:31 -05:00
yourProgramRunning = 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-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-07 20:20:53 -05:00
2023-09-08 08:39:14 -05:00
// We can't use arduino-timer for starting a program because
// it relies on millis(), which reset on power cycle.
// timer.at(millis() + 10000, toggle_led);
// Serial.println(millis());
// auto active_tasks = timer.size();
// Serial.println(active_tasks);
// 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-08 15:00:48 -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
2023-09-09 12:53:34 -05:00
if ( ( yourInputSend = = 2 ) & ( digitalRead ( alarmPin ) = = LOW ) ) {
2023-09-08 10:39:24 -05:00
// 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 ) ) ;
2023-09-08 22:55:31 -05:00
yourProgramRunning = true ;
2023-09-08 08:39:14 -05:00
2023-09-08 10:39:24 -05:00
// Disable and clear alarm
2023-09-08 15:00:48 -05:00
rtc . clearAlarm ( 1 ) ;
rtc . clearAlarm ( 2 ) ; // clear the other one just in case
2023-09-08 10:39:24 -05:00
}
2023-09-08 08:39:14 -05:00
2023-09-08 22:55:31 -05:00
// Once alarm has started the program, set things up to run
if ( yourProgramRunning = = true ) {
2023-09-09 12:53:34 -05:00
morses_sequence . Forever ( ) . Update ( ) ;
yourProgramRunning = false ;
2023-09-08 22:55:31 -05:00
} else
2023-08-31 21:35:49 -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 ) {
morseToSend = morseTEST ;
morseToSend_blink = morseTEST_blink ;
} else if ( yourInputMsg = = 1 ) {
morseToSend = morseMOE ;
morseToSend_blink = morseMOE_blink ;
} else if ( yourInputMsg = = 2 ) {
morseToSend = morseMOI ;
morseToSend_blink = morseMOI_blink ;
} else if ( yourInputMsg = = 3 ) {
morseToSend = morseMOS ;
morseToSend_blink = morseMOS_blink ;
} else if ( yourInputMsg = = 4 ) {
morseToSend = morseMOH ;
morseToSend_blink = morseMOH_blink ;
} else if ( yourInputMsg = = 5 ) {
morseToSend = morseMO5 ;
morseToSend_blink = morseMO5_blink ;
}
2023-09-04 17:26:03 -05:00
// Keeps the key from locking up
yourInputMsg_old = yourInputMsg ;
2023-09-01 09:39:00 -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-01 09:39:00 -05:00
if ( ( yourInputSend = = 1 ) & ( morseToSend . IsRunning ( ) = = false ) ) {
2023-08-30 22:04:32 -05:00
//jled
2023-09-01 09:39:00 -05:00
morseToSend . Reset ( ) . Update ( ) ;
2023-09-04 20:23:14 -05:00
morseToSend_blink . Reset ( ) . Update ( ) ;
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-01 09:39:00 -05:00
} else if ( ( yourInputSend = = 1 ) & ( morseToSend . IsRunning ( ) = = true ) ) {
morseToSend . Update ( ) ;
2023-09-04 20:23:14 -05:00
morseToSend_blink . Update ( ) ;
2023-08-31 20:41:24 -05:00
// if you want to send cycle code and it is sending, keep sending
2023-09-09 12:53:34 -05:00
} else if ( ( yourInputSend = = 2 ) & ( morses_sequence . Update ( ) = = true ) ) {
2023-09-01 09:39:00 -05:00
morseToSend . Update ( ) ;
2023-09-08 22:55:31 -05:00
//morseToSend_blink.Update();
2023-09-09 12:53:34 -05:00
morses_sequence . Update ( ) ;
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-09 12:53:34 -05:00
} else if ( ( yourInputSend = = 2 ) & ( morses_sequence . Update ( ) = = false ) ) {
2023-09-01 09:39:00 -05:00
morseToSend . Reset ( ) . Update ( ) ;
2023-09-08 22:55:31 -05:00
//morseToSend_blink.Reset().Update();
2023-09-09 12:53:34 -05:00
morses_sequence . Reset ( ) ;
2023-08-31 20:41:24 -05:00
2023-08-30 22:04:32 -05:00
// if you don't want to send code
} else {
// stop sending and make sure the pin is off
2023-09-01 09:39:00 -05:00
morseToSend . Stop ( JLed : : eStopMode : : FULL_OFF ) . Update ( ) ;
2023-09-04 20:23:14 -05:00
morseToSend_blink . Stop ( JLed : : eStopMode : : FULL_OFF ) . Update ( ) ;
2023-08-30 22:04:32 -05:00
}
2023-09-04 17:26:03 -05:00
//morseToSend.Update();
2023-08-30 22:04:32 -05:00
2023-08-22 12:23:47 -05:00
}