diff --git a/vulpes/platformio.ini b/vulpes/platformio.ini index ace10bd..1a2242f 100644 --- a/vulpes/platformio.ini +++ b/vulpes/platformio.ini @@ -10,13 +10,20 @@ [env:esp32doit-devkit-v1] platform = espressif32 +;build_flags = +; -std=c++11 +; -std=gnu++11 board = esp32doit-devkit-v1 framework = arduino +upload_speed = 921600 monitor_speed = 115200 lib_deps = me-no-dev/AsyncTCP@^1.1.1 me-no-dev/ESP Async WebServer@^1.2.3 contrem/arduino-timer@^3.0.1 kj7rrv/Telegraph@^1.0.0 - ;etherkit/Etherkit Morse@^1.1.2 jandelgado/JLed@^4.13.0 + ;adafruit/RTClib@^2.1.1 + https://github.com/adafruit/RTClib.git ; >=2.1.2 + adafruit/Adafruit BusIO@^1.14.3 + ;jchristensen/DS3232RTC@^2.0.1 diff --git a/vulpes/src/main.cpp b/vulpes/src/main.cpp index 0dc2bf3..87e9548 100644 --- a/vulpes/src/main.cpp +++ b/vulpes/src/main.cpp @@ -17,18 +17,23 @@ #include #include #include -#include +// #include //#include //arduino morse //#include //etherkit morse #include // jled #include "jled/morse.h" //jled -//#include "morse_effect.h" // jled +#include // for DS3231 +#include // for DS3231 +//#include //for DS3231 +//#include // download zip from https://github.com/me-no-dev/ESPAsyncWebServer and install. #include AsyncWebServer server(80); +RTC_DS3231 rtc; // set up RTC + // Read from config.h const char* ssid = WIFI_SSID; const char* password = WIFI_PASSWORD; @@ -38,6 +43,7 @@ const char* PARAM_SEND = "inputSend"; const char* PARAM_WPM = "inputWPM"; const char* PARAM_MSG = "inputMsg"; const char* PARAM_FLOAT = "inputFloat"; +const char* PARAM_TIME = "inputTimeUnix"; // Global variables String yourInputString; @@ -46,6 +52,7 @@ int yourInputWPM; int yourInputMsg; int yourInputMsg_old; // to save previous state and check changes float yourInputFloat; +uint32_t yourInputTime; //to keep time // HTML web page to handle 3 input fields (inputString, inputSend, inputFloat) const char index_html[] PROGMEM = R"rawliteral( @@ -53,12 +60,11 @@ const char index_html[] PROGMEM = R"rawliteral( ESP Input Form -
+ inputString (current value %inputString%):
Sending program (cycle doesn't work yet) (current value: %inputSend%): @@ -80,8 +86,11 @@ const char index_html[] PROGMEM = R"rawliteral( WPM (current value %inputWPM%): (doesn't work yet)
+ Current time (UTC): %inputTimeUnix% +
+ inputFloat (current value %inputFloat%):
- +
)rawliteral"; @@ -91,7 +100,7 @@ String output26State = "off"; String output27State = "off"; // Assign output variables to GPIO pins -const int output26 = 26; +const int output26 = 32;//26 for LED; //32 for transmitter keyer const int output27 = 27; // Timers @@ -106,16 +115,16 @@ bool toggle_led(void *) { } // Toggle GPIO pin (LED or relay) -bool toggle_gpio_26(void *) { - if(output26State == "off"){ - output26State = "on"; - digitalWrite(output26, HIGH); - } else { - output26State = "off"; - digitalWrite(output26, LOW); - } - return true; // keep timer active? true -} +// bool toggle_gpio_26(void *) { +// if(output26State == "off"){ +// output26State = "on"; +// digitalWrite(output26, HIGH); +// } else { +// output26State = "off"; +// digitalWrite(output26, LOW); +// } +// return true; // keep timer active? true +// } void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); @@ -170,69 +179,71 @@ String processor(const String& var){ } else if(var == "inputFloat"){ return readFile(SPIFFS, "/inputFloat.txt"); + } else if(var == "inputTimeUnix"){ + return rtc.now().timestamp(); } return String(); } -// vvvvv Modify some functions from KB1OIQ's controller. -// This section hasn't been tested on the hardware. +// // vvvvv Modify some functions from KB1OIQ's controller. +// // This section hasn't been tested on the hardware. -//int dit_len = 60 ; //milliseconds; https://morsecode.world/international/timing.html +// //int dit_len = 60 ; //milliseconds; https://morsecode.world/international/timing.html -//================================================================================ -// stop_26(): set GPIO 26 to LOW. Used for dot(), dash(). -//================================================================================ -bool stop_26(void *){ - output26State = "off"; - digitalWrite(output26, LOW); - return false; // keep timer active? true -} +// //================================================================================ +// // stop_26(): set GPIO 26 to LOW. Used for dot(), dash(). +// //================================================================================ +// bool stop_26(void *){ +// output26State = "off"; +// digitalWrite(output26, LOW); +// return false; // keep timer active? true +// } -//================================================================================ -// dit(): transmit a single dit -//================================================================================ -void dit(int dit_len = 1000) { - output26State = "on"; - digitalWrite(output26, HIGH); - timer.in(dit_len, stop_26); -} +// //================================================================================ +// // dit(): transmit a single dit +// //================================================================================ +// void dit(int dit_len = 1000) { +// output26State = "on"; +// digitalWrite(output26, HIGH); +// timer.in(dit_len, stop_26); +// } -//================================================================================ -// dah(): transmit a single dah -//================================================================================ -void dah(int dit_len = 1000) { - output26State = "on"; - digitalWrite(output26, HIGH); - timer.in(dit_len * 3, stop_26); -} +// //================================================================================ +// // dah(): transmit a single dah +// //================================================================================ +// void dah(int dit_len = 1000) { +// output26State = "on"; +// digitalWrite(output26, HIGH); +// timer.in(dit_len * 3, stop_26); +// } -//================================================================================ -// char_space()): transmit a character space -//================================================================================ -// A function that does nothing except (hopefully) block the timer. -bool empty(void *) { - return false; - } +// //================================================================================ +// // char_space()): transmit a character space +// //================================================================================ +// // A function that does nothing except (hopefully) block the timer. +// bool empty(void *) { +// return false; +// } -void char_space(int dit_len = 1000) { +// void char_space(int dit_len = 1000) { - timer.in(dit_len, empty); -} +// timer.in(dit_len, empty); +// } -void k(){ - Serial.println("K"); - dah(); - char_space(); - dit(); - char_space(); - dah(); -} +// void k(){ +// Serial.println("K"); +// dah(); +// char_space(); +// dit(); +// char_space(); +// dah(); +// } -// ^^^^ +// // ^^^^ -//telegraph -//Telegraph telegraph(LED_BUILTIN, 10, HIGH); -Telegraph telegraph26(output26, 10, HIGH); +// //telegraph +// //Telegraph telegraph(LED_BUILTIN, 10, HIGH); +// Telegraph telegraph26(output26, 10, HIGH); //arduinomorse //LEDMorseSender sender(LED_BUILTIN); @@ -265,7 +276,7 @@ class MorseEffect : public jled::BrightnessEvaluator { float wpm = 10; float ms_per_dit = 1000 * (60 / (50 * wpm)); int word_space_ms = ms_per_dit * 7; -// Hardcoding these for now, will come back and make it more flexible. +// Hardcoding messages and WPM for now, will come back and make it more flexible. MorseEffect morseEffectCQ("CQ CQ CQ DE W1CDN", ms_per_dit); MorseEffect morseEffectMOE("MOE", ms_per_dit); MorseEffect morseEffectMOI("MOI", ms_per_dit); @@ -287,12 +298,48 @@ auto morseMO5 = JLed(output26).UserFunc(&morseEffectMO5).DelayAfter(word_space_ms).Forever(); auto morseToSend = morseCQ; // set this up to overwrite later + +// format and print a time_t value +// void printTime(time_t t) +// { +// char buf[25]; +// char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) +// strcpy(m, monthShortStr(month(t))); +// sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d", +// hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t)); +// Serial.println(buf); +// } + //================================================================================ // setup(): stuff that only gets done once, after power up (KB1OIQ's description) //================================================================================ void setup() { Serial.begin(115200); + // https://github.com/JChristensen/DS3232RTC/blob/master/examples/TimeRTC/TimeRTC.ino + // rtc.begin(); + // setSyncProvider(rtc.get); // the function to get the time from the RTC + // if(timeStatus() != timeSet) + // Serial.println("Unable to sync with the RTC"); + // else + // Serial.println("RTC has set the system time"); + + 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)); + } + // Timer example, blink main LED pinMode(LED_BUILTIN, OUTPUT); // set LED pin to OUTPUT // call the toggle_led function every 10000 millis (10 second) @@ -407,6 +454,33 @@ void setup() { yourInputMsg_old = yourInputMsg; yourInputMsg = inputMessage.toInt(); } + // GET inputTimeUnix value on /get?inputTimeUnix= + if (request->hasParam(PARAM_TIME)) { + inputMessage = request->getParam(PARAM_TIME)->value(); + Serial.println(inputMessage); + //https://stackoverflow.com/a/22733127/2152245 + yourInputTime = atol(inputMessage.c_str()); + Serial.println(yourInputTime); + // update the RTC time + rtc.adjust(DateTime(yourInputTime)); +; + DateTime now = rtc.now(); + 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(); + } // GET inputFloat value on /get?inputFloat= if (request->hasParam(PARAM_FLOAT)) { inputMessage = request->getParam(PARAM_FLOAT)->value(); @@ -440,6 +514,23 @@ void loop() { time_until_start.tick(); timer.tick(); + // DateTime now = rtc.now(); + // 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(); + + //arduinomorse //sender.continueSending();