Compare commits

...

367 Commits

Author SHA1 Message Date
richonguzman 5ceff0064f small update to avoid sending gps = 0 2024-10-21 11:16:31 -03:00
richonguzman 8beb7c0465 readme update 2024-10-21 09:09:47 -03:00
richonguzman 112e38312d codingRate4 = 4 does not exists 2024-10-21 09:08:53 -03:00
richonguzman 5a1c6e7ed9 testing GPS 2024-10-21 08:28:35 -03:00
richonguzman 0defd5b289 added HWT with GPS 2024-10-14 17:48:14 -03:00
richonguzman cdac54c34e cleaning code 2024-10-14 17:44:01 -03:00
richonguzman 71e98487f6 readme and index update 2024-10-14 17:23:42 -03:00
richonguzman 510b5bdc59 index reads better 2024-10-14 17:15:56 -03:00
richonguzman 00db358cc3 GPS for iGate 2024-10-14 17:04:28 -03:00
richonguzman c0641986aa RxPacket freeze fix 2024-10-14 12:49:01 -03:00
richonguzman 55378bb9f3 readme Update for NTP update 2024-10-14 11:56:48 -03:00
richonguzman 79cf50a630 NTP time added 2024-10-14 11:44:22 -03:00
richonguzman 03ccd2b12e r up 2024-10-11 07:16:44 -03:00
richonguzman d5ffd26c3c double validation for DigiEcoMode start stop 2024-10-10 18:45:12 -03:00
richonguzman 2f0f991785 readme2 2024-10-09 11:46:45 -03:00
richonguzman 975b140c73 readme1 2024-10-09 11:45:01 -03:00
richonguzman f2abe34af1 readme Update Digi Eco Mode 2024-10-08 12:25:09 -03:00
richonguzman a786d83b9e Queries for DigiEcoMode 2024-10-08 12:19:22 -03:00
richonguzman bf0a0d6e4c EcoMode Digi 2024-10-08 11:04:36 -03:00
richonguzman d08e5b1b27 ready for testing LowPowerDigi 2024-10-08 01:22:10 -03:00
richonguzman f387e03b53 testing LowPowerDigi 2024-10-08 01:03:58 -03:00
richonguzman 16215f9e56 minor update for Internal Battery Sleep 2024-10-07 11:10:19 -03:00
richonguzman ce01d0aa4d minor white spaces kill 2024-10-07 09:39:31 -03:00
richonguzman b0a05f89f6 readme update 2024-10-06 23:35:51 -03:00
richonguzman 58d8736969 test for Killed Wifi Active 2024-10-06 23:23:22 -03:00
richonguzman df9060d906 testing not active 2024-10-06 23:02:10 -03:00
richonguzman 2bd6844d89 WiFiAP Active switch added 2024-10-06 22:59:58 -03:00
richonguzman 0a79b6459b added initial corrections to WiFiAP 2024-10-06 22:30:44 -03:00
richonguzman d5eb32a38b cross digi rules added 2024-10-06 11:37:25 -03:00
richonguzman d6c5741fde cross digi added 2024-10-06 11:36:37 -03:00
richonguzman 1063a82294 se viene thirdParty 2024-10-05 20:25:29 -03:00
richonguzman 6913b6b89f ahora a probar thirdParty 2024-10-05 20:23:58 -03:00
richonguzman 42c990f5cf !thirdParty con o sin path 2024-10-05 20:21:36 -03:00
richonguzman a17900e4d0 bme into wxsensor 2024-10-05 08:48:08 -03:00
richonguzman 3fd819bd4e not encoded telemetry as default 2024-09-25 11:23:38 -03:00
richonguzman 640166a50b update for wiki 2024-09-23 17:41:05 -03:00
richonguzman a9bcae62e2 readme update 2024-09-23 15:15:22 -03:00
richonguzman 3e0368383a better writting 2024-09-23 15:11:35 -03:00
richonguzman 8b790ef656 updated libraries for SDK3 2024-09-23 14:31:45 -03:00
richonguzman c110b41b99 build update for new boards 2024-09-23 12:42:03 -03:00
richonguzman be7fe23cd5 Added LLCC68 1W board 2024-09-23 12:37:35 -03:00
richonguzman 202d03c61f shortening reduced Wx report 2024-09-23 12:15:58 -03:00
richonguzman ddb45544db readme UPdate 2024-09-22 22:35:51 -03:00
richonguzman c9ea51c6da update Version 2024-09-22 22:34:00 -03:00
richonguzman 72fd2b45ec added mods to include Telemetry 2024-09-22 22:31:33 -03:00
richonguzman 0e46c64880 primera mejora Telemetria 2024-09-22 13:34:13 -03:00
richonguzman dd12330e85 killing some delays 2024-09-17 14:25:00 -03:00
richonguzman 2edb183cad minor update on Heltec WS 2024-09-11 16:14:40 -03:00
richonguzman 775677d5e8 trying heltec wireless stick oled fix 2024-09-11 15:49:58 -03:00
richonguzman a60a6d6e4b update WIRE 2024-09-10 14:26:10 -03:00
richonguzman 14abe14703 updated structs of last Stations and 25seg buffer 2024-09-10 14:06:10 -03:00
richonguzman 345fb1e937 up 2024-09-02 09:40:17 -04:00
richonguzman 916eb038e5 updated WiFi.setHostName() 2024-09-02 09:12:18 -04:00
richonguzman 40fc177828 small fix on wire begin 2024-08-30 15:46:50 -04:00
richonguzman 5dc6e99972 low external voltage RF Tx fix 2024-08-28 17:11:50 -04:00
richonguzman db5710ec6a test 2024-08-28 12:21:54 -04:00
richonguzman 65acb54dbe wrong external sleep voltage definition fix 2024-08-28 11:45:16 -04:00
richonguzman 6088c61e73 versionUpdate + utils beacon message update 2024-08-26 10:33:49 -04:00
Ricardo Guzman (Richonguzman) a8c972c5e1 Merge pull request #157 from S57PNX/main
Correct logic of serial notifications for APRS-IS and RF beacons
2024-08-26 10:32:01 -04:00
S57PNX bd3a9f91d6 Merge branch 'richonguzman:main' into main 2024-08-26 10:25:17 +02:00
richonguzman 643a18f40c Wemos S2 Mini DIY LoRa added 2024-08-23 18:05:27 -04:00
richonguzman 46e5bdd21e added led 2024-08-23 18:00:25 -04:00
richonguzman ea426f4126 board update 2024-08-22 16:27:41 -04:00
richonguzman 5cbdd318a2 test for WEMOS S2 Mini DIY LORA 2024-08-22 15:00:56 -04:00
richonguzman 735988ee1c adding WEMOS S2 MINI 2024-08-22 14:24:30 -04:00
richonguzman d5b666f458 HELTEC WS update 2024-08-22 13:25:46 -04:00
richonguzman 702f4abcbb update for gps beacon with timestamp 2024-08-21 19:11:05 -04:00
richonguzman d0070e4381 updated config 2024-08-20 19:01:04 -04:00
richonguzman f4744eab6a Heltec Wireless Paper base 2024-08-19 11:37:55 -04:00
richonguzman bd672857f4 testing for external battery block 2024-08-19 10:41:46 -04:00
richonguzman 9cc26ccdae wireless paper battery reading fix 2024-08-18 21:06:57 -04:00
richonguzman 8863838210 updated battery readings 2024-08-17 13:16:44 -04:00
richonguzman f11b6de57a fix for normal display 2024-08-16 16:00:58 -04:00
richonguzman 55d6bc325f version update 2024-08-16 15:52:55 -04:00
richonguzman ee687e6959 first test 2024-08-16 15:52:20 -04:00
S57PNX d1732a6bba Correct logic of serial notifications for APRS-IS
and RF beacons
2024-08-15 20:54:26 +02:00
richonguzman 4fb4712a33 backupDigimode avoided in only rx mode 2024-08-14 13:37:52 -04:00
richonguzman 39276b0d32 update to display h and cpp 2024-08-14 12:32:34 -04:00
richonguzman 22203a7c24 just code cleaning 2024-08-14 12:07:17 -04:00
richonguzman d8d832fde9 configuration test without fails 2024-08-14 11:50:39 -04:00
richonguzman 61db6c3132 backUpDigiMode and BME for HWSL v3 fix 2024-08-13 17:56:27 -04:00
richonguzman 9521a357b1 readmeUpdate 2024-08-13 14:49:30 -04:00
richonguzman ee95931f00 web user and password 2024-08-13 14:48:08 -04:00
richonguzman 60aa2b05ac more boards update 2024-08-13 12:46:20 -04:00
richonguzman bc5183a192 Ht-ct62 updates 2024-08-13 12:36:37 -04:00
richonguzman 1019306c7c wide2-n fix 2024-08-12 13:49:58 -04:00
richonguzman fbe00903ad version Date on footer added 2024-08-12 11:01:35 -04:00
richonguzman 291a6bc80e added mesh - diy board v1-2 2024-08-12 10:35:45 -04:00
richonguzman 3b550c7f81 mode3 fix WIDE2-2 2024-08-06 10:57:00 -04:00
richonguzman 4659f8b2ff mode3start 2024-08-06 10:11:50 -04:00
richonguzman 62d157d7f0 state add at boot 2024-08-06 09:12:01 -04:00
richonguzman b0e116ee1d Readme Update Digis 2024-08-05 17:42:59 -04:00
richonguzman 00b12c2bf5 version update 2024-08-05 15:43:42 -04:00
richonguzman 85b21565db index fix 2024-08-05 15:43:02 -04:00
richonguzman b9e2c0e8f0 digimode 3 improvement 2024-08-05 15:42:33 -04:00
richonguzman b763b4af78 RNAAAA add + WIDE2 description in index 2024-08-05 15:20:58 -04:00
richonguzman 5553e7ae5c added mode 3 for digirepeater 2024-08-05 14:37:16 -04:00
richonguzman 1afd039c3f digi mode 3 added 2024-08-03 21:55:32 -04:00
richonguzman 1888084f31 WSL v3 wire1 add 2024-08-02 16:15:10 -04:00
richonguzman dc92b822c8 fixed missing wire begin 2024-08-02 15:28:31 -04:00
richonguzman 3c305259e0 update to recover from wifi AP 2024-08-02 13:08:54 -04:00
richonguzman 497d648c17 ready for testing 2024-07-18 14:41:09 -04:00
richonguzman d267f6699c HWSL_V3_Display add 2024-07-17 16:20:20 -04:00
richonguzman 16ce6bc6d2 a7670 voltage calibration fix 2024-07-17 10:47:42 -04:00
richonguzman 008b6250ea Non Ham mods only for Rx 2024-07-10 15:13:57 -04:00
richonguzman ddb83d1368 voltageCalibrationCorrection 2024-07-10 09:49:13 -04:00
richonguzman 26e2dec2b2 font size update 2024-07-09 10:41:26 -04:00
richonguzman 174507377b fix for other boards 2024-07-09 08:39:59 -04:00
richonguzman 864ed44a5d favicon and battery adc calibration 2024-07-08 23:29:04 -04:00
richonguzman 5d69cfbe1c 1 2024-07-08 23:06:03 -04:00
richonguzman e57d356fd1 new ADC calibration test 2024-07-08 23:02:45 -04:00
richonguzman 8381f0916c variable name change 2024-07-05 13:12:21 -04:00
richonguzman beca09293a queryUppercase fix 2024-07-05 11:58:18 -04:00
richonguzman dcca18eeac readme Update 2024-07-01 18:30:11 -04:00
richonguzman 2494acea55 espacio en blanco 2024-06-30 10:36:15 -04:00
richonguzman 0c50ce8de4 tyeofpacket update 2024-06-30 09:24:21 -04:00
richonguzman 2f07d35861 readmeupdate7 2024-06-28 16:20:07 -04:00
richonguzman 91240c5be6 readmeupdate6 2024-06-28 16:19:18 -04:00
richonguzman b4308a95d5 readmeupdate5 2024-06-28 16:18:41 -04:00
richonguzman 6c301795d6 readmeupdate4 2024-06-28 16:18:13 -04:00
richonguzman 5f0c6f4986 readmeupdate3 2024-06-28 16:15:56 -04:00
richonguzman 7c989e6e9e readmeupdate2 2024-06-28 16:15:22 -04:00
richonguzman 2bcda6d3a4 readme update 2024-06-28 16:14:42 -04:00
richonguzman 848492dc36 updated QueryAnswer for 3rdPartyPacket 2024-06-28 16:05:04 -04:00
richonguzman 413bef67fb readme update 2024-06-27 16:25:58 -04:00
richonguzman 3fa4c9371a new battery web config 2024-06-27 16:02:20 -04:00
richonguzman e846c38f97 externalBatdivider 2024-06-27 15:39:53 -04:00
richonguzman b8446e3f1d bat and sh gone 2024-06-27 13:19:51 -04:00
richonguzman c3984bc8da casi listo para prueba 2024-06-26 23:42:24 -04:00
richonguzman 601b72da9f funciona 2024-06-26 18:13:02 -04:00
richonguzman 5d9493314d casi 2024-06-26 17:56:11 -04:00
richonguzman 86cf12d6c1 carga datos base 2024-06-26 17:10:07 -04:00
richonguzman e5e2c6a980 readmeUpdate 2024-06-26 13:26:17 -04:00
richonguzman 3b9d49c5f9 personalNote implementation 2024-06-26 13:24:36 -04:00
richonguzman ab9443140b personalNote1 2024-06-26 13:05:45 -04:00
richonguzman ad1129c588 callsign validation process fix 2024-06-25 16:36:49 -04:00
richonguzman 8bb0b0446c more 3rd party filtering 2024-06-24 13:25:30 -04:00
richonguzman 6b1d319901 fix firstColon on last position 2024-06-24 11:36:40 -04:00
richonguzman 1ceaf159ba colonIndex fix3 2024-06-24 11:18:42 -04:00
richonguzman f1de8d2df0 colonIndex upload fix 2024-06-24 11:16:52 -04:00
richonguzman b9b4f46c66 typeOfPacket fix3 2024-06-24 11:02:38 -04:00
richonguzman 22b2c679d2 typeofPacket initial fix 2024-06-24 10:54:21 -04:00
richonguzman 7baa98bf7e first 3rdparty correction 2024-06-24 10:32:58 -04:00
richonguzman 35e79709e3 HeltecWSL V3 battery reading fix 2024-06-21 15:33:56 -04:00
richonguzman f4bae74c26 build fix 2024-06-21 11:38:54 -04:00
richonguzman 04e721ac5a build correction 2024-06-21 11:15:52 -04:00
richonguzman 1922d7453b readmeUpdate 3rd Party 2024-06-21 11:11:40 -04:00
richonguzman f1bd751585 readmeUpdate3rdParty 2024-06-21 11:02:34 -04:00
richonguzman c346bc0f39 version and readme update 2024-06-21 10:58:54 -04:00
richonguzman bbc1996918 update const String 2024-06-21 02:13:34 -04:00
richonguzman 505bb3d5a4 version update 2024-06-20 21:14:30 -04:00
richonguzman b97457146a many updates const String and 3rd party 2024-06-20 21:12:54 -04:00
richonguzman 64b51fea72 first test with new 3rdParty 2024-06-20 14:06:14 -04:00
richonguzman d82cf9235d starting with builing Tx packet 2024-06-18 23:42:09 -04:00
richonguzman d83bb19bc8 A7670 code cleanup 2024-06-18 19:55:33 -04:00
richonguzman 0feb0045d0 build update 2024-06-18 19:36:17 -04:00
richonguzman 4999c89820 all boards with 915 versions added 2024-06-18 19:30:34 -04:00
richonguzman f5048edf84 all sx1276 added 2024-06-18 18:43:25 -04:00
richonguzman 691f60925a only digi with packetbuffer25seg 2024-06-18 16:45:01 -04:00
richonguzman 4bf4e781df not callsign filtering from aprs-is feed 2024-06-18 15:29:00 -04:00
richonguzman 0c09f5a934 callsign filter changed 2024-06-18 15:15:27 -04:00
richonguzman 494be4a393 readmeupdate5 2024-06-17 21:41:29 -04:00
richonguzman 16e79d291c readmeupdate4 2024-06-17 21:40:54 -04:00
richonguzman c9a52d5b61 readmeupdate3 2024-06-17 21:40:30 -04:00
richonguzman 7d813524e3 readme update2 2024-06-17 21:39:26 -04:00
richonguzman 2d7d02f2df update readme 2024-06-17 21:37:53 -04:00
richonguzman 562b0a46ea update of Configuration images 2024-06-17 20:32:39 -04:00
richonguzman 69c074a834 readmeMods 2024-06-16 20:55:54 -04:00
richonguzman bf04507ed0 new webflasher image 2024-06-16 20:53:36 -04:00
richonguzman e653d39004 build updated for missing letter in sx1268 tbeam 2024-06-15 09:50:30 -04:00
richonguzman 68edade5b4 readyForNewRelease1.0.3 2024-06-15 09:01:33 -04:00
richonguzman 685d629ef6 callsign test corrected 2024-06-14 23:25:47 -04:00
richonguzman b7f6d84ac8 build test 2024-06-14 15:15:43 -04:00
richonguzman dda4b06714 update 2024-06-14 11:01:32 -04:00
richonguzman 6095b4ff72 Si7021 fix for HELTEC V3 2024-06-13 13:36:18 -04:00
richonguzman f77d7078b6 updateVersion 2024-06-12 09:34:13 -04:00
richonguzman 1dc1a291cd not funny 2024-06-12 09:23:01 -04:00
richonguzman 4396078d76 readmeUpdate 2024-06-10 17:02:27 -04:00
richonguzman 9924fb9a38 test 2024-06-10 14:13:28 -04:00
richonguzman 72a6c48553 testing ESP32C31WLORA 2024-06-10 14:09:30 -04:00
richonguzman 217e5b07e1 ESP32C3 1W DIY TEST 2024-06-10 14:00:15 -04:00
richonguzman ce7ed2519f version update 2024-06-10 13:17:01 -04:00
richonguzman 72f0c80a29 betterCallsign Validation process 2024-06-10 11:33:26 -04:00
richonguzman 62db4c18da testing SI7021 2024-06-09 22:25:15 -04:00
richonguzman 7e91317730 update 2024-06-08 15:59:16 -04:00
richonguzman 49cffe7d0c avoid 3 bytes again 2024-06-08 15:50:55 -04:00
richonguzman 7537c1ee50 readmeUpdate 2024-06-08 15:28:16 -04:00
richonguzman b2a8def481 update for NOCALL-10 2024-06-08 15:26:49 -04:00
richonguzman b3441ece02 WIDE fix when not present 2024-06-08 14:39:15 -04:00
richonguzman 6ee86f7557 const corrections 2024-06-08 14:12:20 -04:00
richonguzman 0f5330141f testing state 2024-06-08 13:57:58 -04:00
richonguzman d04b009a49 test1 2024-06-08 12:52:47 -04:00
richonguzman 397a94cc47 callsignValidationTest 2024-06-07 17:29:55 -04:00
richonguzman a8e1a48d62 version update 2024-06-07 00:16:03 -04:00
richonguzman d75be8f007 code cleaning 2024-06-07 00:10:04 -04:00
richonguzman c89ca7316f more const cleaning 2024-06-05 23:49:16 -04:00
richonguzman 18de124c04 switch and display cleaning 2024-06-05 23:20:34 -04:00
richonguzman 01cee5d51e libraries update 2024-06-04 13:33:34 -04:00
richonguzman 005f114a97 more - less code 2024-06-03 00:02:43 -04:00
richonguzman e133d50cd9 syslog Fix 2024-05-31 15:09:28 -04:00
richonguzman d3ebe43ebb readme update 2024-05-31 07:58:40 -04:00
richonguzman c67f5b60e5 minor code cleaning 2024-05-30 20:04:46 -04:00
richonguzman d2923cc0b6 SignalReport Query Added 2024-05-30 19:58:33 -04:00
richonguzman a87cc0be58 testing lowerMemory Ussssage 2024-05-30 16:27:07 -04:00
richonguzman e63d54d9f0 signalReport available 2024-05-30 15:38:30 -04:00
richonguzman f6793c01c4 syslog call and code update 2024-05-30 15:12:34 -04:00
richonguzman 12bcc76452 deepSleepReboot update 2024-05-29 15:46:07 -04:00
richonguzman 4cf3a333c9 deepSleep update 2024-05-29 15:43:23 -04:00
richonguzman c5217842ff Battery Monitor for T-Beams 2024-05-27 11:46:14 -04:00
richonguzman e9bb0391f2 update for minSleepVoltage recovery 2024-05-26 21:51:22 -04:00
richonguzman edd2ff65b9 update3 2024-05-25 14:08:57 -04:00
richonguzman dcc0340c90 buildUpdate2.3 2024-05-25 14:00:27 -04:00
richonguzman 4aa8f1aba8 buildUpdate2.2 2024-05-25 13:58:52 -04:00
richonguzman 7c7b8507eb buildUpdate2.1 2024-05-25 13:57:45 -04:00
richonguzman 3d1ae2fa70 buildUpdate2 2024-05-25 13:57:26 -04:00
richonguzman 095cc7edae buildUpdate1 2024-05-25 12:57:39 -04:00
richonguzman c1d1069785 update6-12 2024-05-24 18:36:43 -04:00
richonguzman bc29afa94e update6-11 2024-05-24 18:19:24 -04:00
richonguzman eeba0df050 update6-10 2024-05-24 18:12:39 -04:00
richonguzman 8f40563ae5 update6-5 2024-05-24 17:39:05 -04:00
richonguzman 8bcf95548c update6-4 2024-05-24 17:34:40 -04:00
richonguzman 6809d96b59 update6-3 2024-05-24 17:30:04 -04:00
richonguzman 09bf14f8d1 update6-2 2024-05-24 17:13:57 -04:00
richonguzman 666c57738b update6-1 2024-05-24 17:02:07 -04:00
richonguzman e4d41380bf update6 2024-05-24 16:48:55 -04:00
richonguzman afdde6ad2d update4 2024-05-24 16:15:04 -04:00
richonguzman f7ce94c494 update3 2024-05-24 16:07:02 -04:00
richonguzman ce69b0c950 update2 2024-05-24 15:55:21 -04:00
richonguzman 6e381fe7fc update 2024-05-24 15:45:17 -04:00
richonguzman dcc549c5ba update build comming 2024-05-24 15:18:21 -04:00
richonguzman 618be275af battery monitor update 2024-05-24 14:42:39 -04:00
richonguzman 2c71e3ed65 update for HT-CT62 2024-05-24 14:27:39 -04:00
richonguzman 3589f54d02 full update for BatteryHealthMonitor 2024-05-24 14:24:40 -04:00
richonguzman c6687529da comienzo dormir ext 2024-05-24 13:05:28 -04:00
richonguzman 3c2c49aa01 updated 2024-05-24 11:59:06 -04:00
richonguzman 9044b93090 ordenando 2024-05-24 11:48:12 -04:00
richonguzman 076f3bfcb5 funciona 2024-05-24 11:08:08 -04:00
richonguzman c6888adca8 battery5-1 2024-05-24 10:43:06 -04:00
richonguzman b06b91d258 starting 2024-05-24 10:00:21 -04:00
richonguzman bbdcf8ce0d new names ok 2024-05-23 22:52:17 -04:00
richonguzman 992641578d battery 5 andando 2024-05-23 20:39:21 -04:00
richonguzman f70d836285 reorden index 2024-05-23 20:29:35 -04:00
richonguzman d50b0767c4 battery basico funciona 2024-05-23 20:22:12 -04:00
richonguzman fc8d3fd9fb justo antes de fallar 2024-05-23 20:13:05 -04:00
richonguzman 345a6c2c21 a 2024-05-23 19:27:10 -04:00
richonguzman 5986125661 wifiInterval not used 2024-05-23 18:29:08 -04:00
richonguzman 6090b83d34 web edit 2024-05-22 19:24:28 -04:00
richonguzman 7cc1a759cc readme update 2024-05-22 19:20:27 -04:00
richonguzman 51f9e0f0cc Reboot Mode Added 2024-05-22 19:19:25 -04:00
richonguzman 960df01d61 readme update again 2024-05-22 16:45:21 -04:00
richonguzman 60a8fe01a3 readme update 2024-05-22 16:43:49 -04:00
richonguzman 46d8b12896 Testing backupDigiMode return2 2024-05-22 16:41:20 -04:00
richonguzman 5296b19ef2 first test backupDigiMode 2024-05-22 16:19:45 -04:00
richonguzman 35fbd7a5dc testing backupDigiMode 2024-05-22 15:41:25 -04:00
richonguzman adf4c1fcb8 testing Mode5 return1 2024-05-22 15:29:00 -04:00
richonguzman 0921d01340 starting mods 2024-05-22 11:41:08 -04:00
richonguzman 0c81df7cc5 lora power mod 2024-05-22 10:54:20 -04:00
richonguzman 789b3732f3 fix battery calculations 2024-05-22 08:36:54 -04:00
richonguzman 8be573e2b6 new buildPacketToTx 2024-05-21 00:00:23 -04:00
richonguzman 7022046f21 new order in WebUi 2024-05-20 23:33:59 -04:00
richonguzman d19284df12 Objects received 2024-05-20 23:03:57 -04:00
richonguzman 05a5c096c3 ready to test Objects to Rf 2024-05-20 21:54:55 -04:00
richonguzman 7add09d346 tx objects 2024-05-20 17:57:58 -04:00
richonguzman 9e87c50966 welcomeMessage update 2024-05-20 11:18:01 -04:00
richonguzman 9a33df49e3 testing for heltec v2_1 2024-05-20 07:49:52 -04:00
richonguzman 916cbade8c testing new Syslog Comments info 2024-05-19 23:34:29 -04:00
richonguzman 2496c12763 WemosD1 update 2024-05-18 11:51:28 -04:00
richonguzman 166773b81d Wemos D1 added 2024-05-18 11:48:50 -04:00
richonguzman b8d000356a boards_pinout change 2024-05-18 11:27:14 -04:00
richonguzman 49d3801e83 updateNewStuff 2024-05-17 15:14:58 -04:00
richonguzman 9dead41e79 version update 2024-05-17 15:11:59 -04:00
richonguzman f3eaa28c76 lora code update 2024-05-17 09:01:15 -04:00
richonguzman 1bdfa3a117 adding Heltec WSL v3 2024-05-17 00:12:46 -04:00
richonguzman 8af1f4cea3 another Radiolib Test 2024-05-16 23:22:27 -04:00
richonguzman d3e45c57e0 test1 2024-05-16 17:52:25 -04:00
richonguzman 8024925950 HELTEC WSL V3 added 2024-05-16 15:43:13 -04:00
richonguzman 8e6346aa97 build mods 2024-05-16 14:35:53 -04:00
richonguzman cfca59cf20 const String 2 2024-05-15 17:47:29 -04:00
richonguzman 2430f92193 tnc + station const String 2024-05-15 16:41:07 -04:00
richonguzman 3cef4676a7 A7670 const String 2024-05-15 16:30:00 -04:00
richonguzman 87a1830970 adding decimal to BME Pressure measurement 2024-05-15 12:12:05 -04:00
richonguzman b8fb7cfba0 readme update 2024-05-14 11:44:28 -04:00
richonguzman 3b81460798 HELTEC_V3 BME680 fix 2024-05-14 11:43:29 -04:00
richonguzman 630ec062c1 HT_CT_62 beaconPacket fix 2024-05-14 09:23:22 -04:00
richonguzman dc39eec941 testing heltecv3 0.3 2024-05-14 09:14:25 -04:00
richonguzman bdf3fe7cbc test HELTECv3 0.2 2024-05-14 09:08:24 -04:00
richonguzman 3de3aac026 testing HeltecV3 0.1 2024-05-14 08:59:47 -04:00
richonguzman 3a148fa55d testing heltecv3 2024-05-14 08:47:57 -04:00
richonguzman c7e79eba43 bme680 fix for heltec v3 2024-05-14 02:01:24 -04:00
richonguzman 8429bb4730 25SegBuffer fix 2024-05-14 01:14:02 -04:00
richonguzman c940cb99d9 testing actions 2024-05-14 00:36:32 -04:00
richonguzman 0be60b76b0 mayor code cleaning 2024-05-13 23:30:15 -04:00
richonguzman 794cc0640f buffer implemented 2024-05-13 21:47:52 -04:00
richonguzman c5dcfd86b2 buffer 0.1 2024-05-13 21:24:44 -04:00
richonguzman 4d4598e09e buffer added to digimode 2024-05-13 21:00:42 -04:00
richonguzman 2e4ee4792e 1 2024-05-13 20:29:08 -04:00
richonguzman bee09386e1 less lora state validations 2024-05-13 18:12:51 -04:00
richonguzman 0a15813ef2 WebUpdate for auto BME detect 2024-05-13 17:17:07 -04:00
richonguzman 6ecb733bea saving works kinda 2024-05-13 16:08:27 -04:00
richonguzman 1345ddd608 index1.1 2024-05-13 14:48:07 -04:00
richonguzman 5c0fba60b5 index mod1 2024-05-13 14:40:30 -04:00
richonguzman 67c2a61f09 first test mod WebUI 2024-05-13 14:13:00 -04:00
richonguzman f1e712a363 bme autodetect 2024-05-13 14:00:07 -04:00
richonguzman 7753618756 test startup delay 1 2024-05-13 08:50:34 -04:00
richonguzman 61168d9217 Startup delay test added 2024-05-13 08:45:19 -04:00
richonguzman d9af677f69 tft rotation fix 2024-05-12 22:57:45 -04:00
richonguzman cc976a4a4a small code refactor 2024-05-12 22:02:12 -04:00
Ricardo Guzman (Richonguzman) e6402409fc bme comment fix 2024-05-12 11:42:28 -04:00
richonguzman 12860410fd code cleaning1 2024-05-11 12:59:25 -04:00
richonguzman 886b661a62 CodeCleaning 2024-05-11 12:59:07 -04:00
richonguzman 53461f289c batteryReading for Heltec WT 2024-05-11 12:38:05 -04:00
richonguzman 54496a9f86 readme update 2024-05-11 12:29:10 -04:00
richonguzman 5e0294fb14 typeOfPacket fix 2024-05-11 12:27:13 -04:00
richonguzman d7c1c70f10 TFT fix and ??? in beacon Rx 2024-05-11 12:19:19 -04:00
richonguzman ad507cb4c9 Heltec WT added1 2024-05-11 12:02:08 -04:00
richonguzman c54843622c setRxBoostedGainMode 2024-05-10 23:18:27 -04:00
richonguzman 2d820bbcc4 callsign always as uppercase 2024-05-10 16:36:28 -04:00
richonguzman 691f967aaf git Ignore update 2024-05-10 10:20:04 -04:00
richonguzman 3b85a3a5bf small battery measurement update 2024-05-09 13:49:09 -04:00
richonguzman 983467e059 BME warning fix 2024-05-08 15:05:43 -04:00
richonguzman 2b6066f62e versionUpdate 2024-05-05 08:17:18 -04:00
richonguzman b81d986c58 blackSpacekiller 2024-05-05 08:16:58 -04:00
richonguzman 71c5e608b6 better heared station function 2024-05-05 08:16:15 -04:00
richonguzman db24293b91 better definitions 2024-05-02 15:31:31 -04:00
richonguzman 611ea87264 better battery code 2024-05-02 13:41:21 -04:00
richonguzman 04a7f89891 code cleaning in power_utils 2024-05-02 12:57:18 -04:00
richonguzman d744f0a0f0 heltec v3 battery test 2024-05-01 08:06:31 -04:00
richonguzman a14c570db0 heltecV3 battery readings fix 2024-04-30 17:18:02 -04:00
richonguzman 708742f43d update display toggle 2024-04-29 09:19:25 -04:00
richonguzman e182dd163e code cleaning 2024-04-28 09:30:56 -04:00
richonguzman b2b388da99 syslog update 2024-04-28 09:06:45 -04:00
richonguzman c6929e161a readme update1.1 2024-04-26 20:56:44 -04:00
richonguzman 26e4984225 readme update1 2024-04-26 20:55:54 -04:00
richonguzman fe41189418 black space again 2024-04-23 22:40:03 -04:00
richonguzman 9742e25100 sx1276 && 915 added 2024-04-23 22:25:20 -04:00
richonguzman e2c3edd0f1 delete old images 2024-04-23 17:13:03 -04:00
richonguzman ffc3bd7624 batteryPin measurement A7670 2024-04-23 16:37:49 -04:00
richonguzman 7743cbe221 battery pin update 2024-04-23 16:36:08 -04:00
richonguzman da0178bc56 battery and led pin add 2024-04-23 16:28:19 -04:00
richonguzman 5f145751c0 ESP32 & A7670 & LoRa added 2024-04-23 14:10:04 -04:00
richonguzman cda72194db Add ESP32 & Modem A7670 2024-04-23 13:57:21 -04:00
richonguzman 47e6623881 first test of Modem 2024-04-23 12:30:57 -04:00
richonguzman 7e4fdff0a3 digi packet process fix 2024-04-23 10:53:53 -04:00
richonguzman eb472b1506 first library cleaning in platformio 2024-04-23 10:29:46 -04:00
richonguzman f2a6bbf0a9 start addA7670 2024-04-23 09:16:39 -04:00
richonguzman 3df25d71e2 readme update 2024-04-22 13:38:03 -04:00
richonguzman 1b5a89b31b Merge branch 'main' of https://github.com/richonguzman/LoRa_APRS_iGate 2024-04-22 13:33:21 -04:00
richonguzman bd8c8e2eb1 readme change and version update 2024-04-22 13:31:02 -04:00
richonguzman 2b0cc514f0 WEMOS LOLIN32 added for testing 2024-04-22 13:25:52 -04:00
richonguzman deb4ea6974 heltec v3 battery 2024-04-20 14:02:11 -04:00
richonguzman 5333a68d04 ht-ce62 fix 2024-04-20 13:17:25 -04:00
richonguzman 7ab5ffa81d more cleaning 2024-04-20 12:38:45 -04:00
richonguzman 3964354844 QTH images add for wiki 2024-04-20 12:18:19 -04:00
Ricardo Guzman (Richonguzman) 1eee529f9f qth image add 2024-04-20 12:15:15 -04:00
richonguzman 38b81ffbd7 version update 2024-04-20 11:09:11 -04:00
richonguzman 7dfbaf45ef readme update 5 2024-04-20 11:08:50 -04:00
richonguzman 13adc2d2d0 upload images 2024-04-20 11:00:04 -04:00
Ricardo Guzman (Richonguzman) ce088035ff adding pinpoint and aprsis32 2024-04-20 10:57:47 -04:00
richonguzman 4eb46d59f6 readme update 4 2024-04-20 10:55:09 -04:00
richonguzman 2cbb6c1a1a readme update3 2024-04-20 10:52:26 -04:00
Ricardo Guzman (Richonguzman) 507a365b88 new webflasher image 2024-04-20 10:50:47 -04:00
richonguzman 5f04468285 readme update2 2024-04-20 10:43:38 -04:00
richonguzman fc2a35a058 readme update 2024-04-20 10:41:48 -04:00
richonguzman 7987ceb262 final mods to test outputbuffer 2024-04-20 10:06:22 -04:00
richonguzman 8f1629abbc lastRxTime added to process buffer 2024-04-20 09:37:22 -04:00
richonguzman b4f2daca42 outputBuffer Created-all LoRa send to Buffer 2024-04-20 09:27:20 -04:00
richonguzman ce058ed424 HELTEC V3 battery input fix 2024-04-19 11:06:26 -04:00
96 changed files with 5121 additions and 2730 deletions
+118 -22
View File
@@ -11,17 +11,68 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
target: target:
- "ttgo-lora32-v21" - name: ttgo-lora32-v21
- "heltec-lora32-v2" chip: esp32
- "heltec_wifi_lora_32_V3" - name: ttgo-lora32-v21_915
- "ESP32_DIY_LoRa" chip: esp32
- "ESP32_DIY_1W_LoRa" - name: heltec-lora32-v2
- "ttgo-t-beam-v1_2" chip: esp32
- "ttgo-t-beam-v1" - name: heltec_wifi_lora_32_V3
- "ttgo-t-beam-v1_SX1268" chip: esp32s3
- "ttgo-t-beam-v1_2_SX1262" - name: heltec_wireless_stick
- "heltec_wireless_stick" chip: esp32s3
- "heltec_ht-ct62" - name: heltec_wireless_stick_lite_v3
chip: esp32s3
- name: heltec_wireless_stick_lite_v3_display
chip: esp32s3
- name: ESP32_DIY_LoRa
chip: esp32
- name: ESP32_DIY_LoRa_915
chip: esp32
- name: ESP32_DIY_1W_LoRa
chip: esp32
- name: ESP32_DIY_1W_LoRa_915
chip: esp32
- name: ESP32_DIY_1W_LoRa_LLCC68
chip: esp32
- name: ESP32_DIY_1W_LoRa_Mesh_V1_2
chip: esp32
- name: ttgo-t-beam-v1_2
chip: esp32
- name: ttgo-t-beam-v1_2_915
chip: esp32
- name: ttgo-t-beam-v1
chip: esp32
- name: ttgo-t-beam-v1_915
chip: esp32
- name: ttgo-t-beam-v1_SX1268
chip: esp32
- name: ttgo-t-beam-v1_2_SX1262
chip: esp32
- name: ESP32_DIY_LoRa_A7670
chip: esp32
- name: ESP32_DIY_LoRa_A7670_915
chip: esp32
- name: heltec_wireless_tracker
chip: esp32s3
- name: heltec_ht-ct62
chip: esp32c3
- name: heltec_wireless_paper
chip: esp32s3
- name: OE5HWN_MeshCom
chip: esp32
- name: WEMOS-LOLIN32-OLED-DIY
chip: esp32
- name: WEMOS-D1-R32-RA02
chip: esp32
- name: WEMOS_S2_MINI_DIY_LoRa
chip: esp32s2
- name: esp32c3_DIY_1W_LoRa
chip: esp32c3
- name: esp32c3_DIY_1W_LoRa_915
chip: esp32c3
- name: ESP32_C3_OctopusLab_LoRa
chip: esp32c3
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -33,25 +84,70 @@ jobs:
run: pip install --upgrade platformio run: pip install --upgrade platformio
- name: Build target - name: Build target
run: pio run -e ${{ matrix.target }} run: |
pio run -e ${{ matrix.target.name }}
- name: Build FS - name: Build FS
run: pio run --target buildfs -e ${{ matrix.target }} run: |
pio run --target buildfs -e ${{ matrix.target.name }}
- name: Move Files - name: Move Files
run: | run: |
mkdir -p installer/firmware mkdir -p installer/firmware
cp .pio/build/${{ matrix.target }}/firmware.bin installer/ota_update.bin cp .pio/build/${{ matrix.target.name }}/firmware.bin installer/ota_update.bin
cp .pio/build/${{ matrix.target }}/firmware.bin installer/firmware/ cp .pio/build/${{ matrix.target.name }}/firmware.bin installer/firmware/
cp .pio/build/${{ matrix.target }}/bootloader.bin installer/firmware/ cp .pio/build/${{ matrix.target.name }}/bootloader.bin installer/firmware/
cp .pio/build/${{ matrix.target }}/partitions.bin installer/firmware/ cp .pio/build/${{ matrix.target.name }}/partitions.bin installer/firmware/
cp .pio/build/${{ matrix.target }}/spiffs.bin installer/firmware/ cp .pio/build/${{ matrix.target.name }}/spiffs.bin installer/firmware/
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin installer/firmware/ cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin installer/firmware/
- name: Merge for web flashing - name: Merge for web flashing
run: | run: |
python installer/bin/esptool/esptool.py --chip esp32 merge_bin -o installer/web_upgrade.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 installer/firmware/bootloader.bin 0x8000 installer/firmware/partitions.bin 0xe000 installer/firmware/boot_app0.bin 0x10000 installer/firmware/firmware.bin if [ "${{ matrix.target.chip }}" == "esp32" ]; then
python installer/bin/esptool/esptool.py --chip esp32 merge_bin -o installer/web_factory.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 installer/firmware/bootloader.bin 0x8000 installer/firmware/partitions.bin 0xe000 installer/firmware/boot_app0.bin 0x10000 installer/firmware/firmware.bin 2686976 installer/firmware/spiffs.bin python installer/bin/esptool/esptool.py --chip esp32 merge_bin \
-o installer/web_factory.bin \
--flash_mode dio \
--flash_freq 40m \
--flash_size 4MB \
0x1000 installer/firmware/bootloader.bin \
0x8000 installer/firmware/partitions.bin \
0xe000 installer/firmware/boot_app0.bin \
0x10000 installer/firmware/firmware.bin \
0x3D0000 installer/firmware/spiffs.bin
elif [ "${{ matrix.target.chip }}" == "esp32s2" ]; then
python installer/bin/esptool/esptool.py --chip esp32s2 merge_bin \
-o installer/web_factory.bin \
--flash_mode dio \
--flash_freq 40m \
--flash_size 4MB \
0x1000 installer/firmware/bootloader.bin \
0x8000 installer/firmware/partitions.bin \
0xe000 installer/firmware/boot_app0.bin \
0x10000 installer/firmware/firmware.bin \
0x3D0000 installer/firmware/spiffs.bin
elif [ "${{ matrix.target.chip }}" == "esp32s3" ]; then
python installer/bin/esptool/esptool.py --chip esp32s3 merge_bin \
-o installer/web_factory.bin \
--flash_mode dio \
--flash_freq 40m \
--flash_size 8MB \
0x0000 installer/firmware/bootloader.bin \
0x8000 installer/firmware/partitions.bin \
0xe000 installer/firmware/boot_app0.bin \
0x10000 installer/firmware/firmware.bin \
0x3D0000 installer/firmware/spiffs.bin
elif [ "${{ matrix.target.chip }}" == "esp32c3" ]; then
python installer/bin/esptool/esptool.py --chip esp32c3 merge_bin \
-o installer/web_factory.bin \
--flash_mode dio \
--flash_freq 40m \
--flash_size 4MB \
0x1000 installer/firmware/bootloader.bin \
0x8000 installer/firmware/partitions.bin \
0xe000 installer/firmware/boot_app0.bin \
0x10000 installer/firmware/firmware.bin \
0x3D0000 installer/firmware/spiffs.bin
fi
- name: Install Zip - name: Install Zip
run: sudo apt-get install zip run: sudo apt-get install zip
@@ -66,5 +162,5 @@ jobs:
with: with:
upload_url: ${{ github.event.release.upload_url }} upload_url: ${{ github.event.release.upload_url }}
asset_path: ./installer.zip asset_path: ./installer.zip
asset_name: ${{ matrix.target }}.zip asset_name: ${{ matrix.target.name }}.zip
asset_content_type: application/zip asset_content_type: application/zip
+5 -14
View File
@@ -11,18 +11,9 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
target: target:
- "ttgo-lora32-v21" - name: ttgo-lora32-v21
- "heltec-lora32-v2" chip: esp32
- "heltec_wifi_lora_32_V3"
- "ESP32_DIY_LoRa"
- "ESP32_DIY_1W_LoRa"
- "ttgo-t-beam-v1_2"
- "ttgo-t-beam-v1"
- "ttgo-t-beam-v1_SX1268"
- "ttgo-t-beam-v1_2_SX1262"
- "heltec_wireless_stick"
- "heltec_ht-ct62"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -34,7 +25,7 @@ jobs:
run: pip install --upgrade platformio run: pip install --upgrade platformio
- name: Build target - name: Build target
run: pio run -e ${{ matrix.target }} run: pio run -e ${{ matrix.target.name }}
- name: Build FS - name: Build FS
run: pio run --target buildfs -e ${{ matrix.target }} run: pio run --target buildfs -e ${{ matrix.target.name }}
+67 -33
View File
@@ -1,52 +1,86 @@
# Richonguzman / CA2RXU LoRa APRS iGate/Digirepeater # CA2RXU LoRa APRS iGate/Digirepeater
This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world. This firmware is for using ESP32 based boards with LoRa Modules and GPS to live in the APRS world.
![Screenshot](https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/images/iGateOledScreen.jpeg) ![Screenshot](https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/images/iGateOledScreen.jpeg)
__(NOTE: This iGate Firmware was develop to work with all LoRa APRS Trackers and specially with this firmware <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker</a>)__ __(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a href="https://github.com/richonguzman/LoRa_APRS_Tracker" target="_blank">LoRa APRS Tracker Firmware</a>))__
<br />
___________________________________________________ ____________________________________________________
## You can support this project to continue to grow: ## You can support this project to continue to grow:
[<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/paypalme.png">](http://paypal.me/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/paypalme.png">](http://paypal.me/richonguzman)
____________________________________________________ <br />
This next generation LoRa iGate can work as: # WEB FLASHER/INSTALLER is <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">here</a>
- pure RX-iGate,
- Rx+Tx-iGate and distribute messages and weather forecasts to heard trackers, and
- Digipeater in simplex or split-frequency environment.
In all configurations the display shows the current stationMode, heard packets and events the iGate is currently performing.
But under the hood is much more:
- Web Configuration UI.
- Sending events to remote syslog server.
- OTA update capability (for Firmware and Filesystem).
- RX first, TX will only be done if there is no traffic on the frequency.
- automatic update of the Lora symbol at APRS-IS, black "L" for pure RX, red "L" for TX capability, green star "L" for digipeater and blue round "L" for WX iGate.
- support for multiple WLAN with corresponding coordinates.
- support for BME/BMP280 and BME680 sensors, sending to WX data to APRS-IS.
and more will come:
- More Web UI Station Information
____________________________________________________ ____________________________________________________
# WIKI # WIKI
### Supported Boards and buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/Z.-------Supported-Boards-and-Buying-Links" target="_blank">here</a>. ### FAQ, BME280, TNC and more --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/00.-FAQ-(frequently-asked-questions)" target="_blank">here</a>.
### Installation Guide --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/01.-Installation-Guide" target="_blank">here</a>. ### Installation Guide --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/01.-Installation-Guide" target="_blank">here</a>.
<br />
*(Wiki has all configuration explanation, supported boards list, adding BME/BMP Wx modules and more)* # SUPPORTED BOARDS
### Buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/108.-Supported-Boards-and-Buying-Links" target="_blank">here</a>.
(NOTE: all boards with 433-868-915 MHz versions)
- TTGO Lilygo LoRa32 v2.1 / v1.6 (they work the same).
- TTGO T-Beam v1.0 , v1.1, v1.2 (also variations with SX1262 and SX1268 LoRa Modules).
- HELTEC V2, V3 , Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker.
- ESP32 Wroom + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
- ESP32C3 + Ebyte 400M30S(or 900M30S) 1W LoRa Module for another DIY version.
- ESP32 + 4G/LTE A7670 Modem + SX1278 DIY Version.
- Wemos Lolin32 Oled + SX1278 DIY Version.
<br />
____________________________________________________
## Timeline (Versions): ## Timeline (Versions):
- 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km).
- 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset).
- 2024.10.08 New EcoMode for Remote Digirepeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP and all was 150mA). APRS Message/Queries can start/stop this mode too.
- 2024.10.06 Cross Frequency Digirepeater Rules added.
- 2024.09.23 Libraries Update for SDK3
- 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet.
- 2024.08.23 Wemos S2 Mini DIY LoRa added.
- 2024.08.19 HELTEC Wireless Paper working (still missing Epaper code).
- 2024.08.13 Web Authentication for WebUI. Thanks Mitja S57PNX.
- 2024.08.05 WIDE2-n added to WIDE1-n in Digirepeater Modes.
- 2024.06.27 External Voltage Divider Resistor configuration on WebUI. Thanks Tilen S54B.
- 2024.06.26 Personal Note information on WebUI for the Station. Thanks Tilen S54B.
- 2024.06.24 Callsign Validation fix. Thanks Helge SA7SKY.
- 2024.06.21 Tx packets coming from APRS-IS are (now) formatted into 3rd Party (as they should have been since the beginning). Thanks Lynn KJ4ERJ and Geoffrey F4FXL.
- 2024.06.18 All boards with 433 / 868 / 915 MHz versions.
- 2024.06.10 ESP32C3 + 1W LoRa Module (E22 400M30S) support added.
- 2024.06.09 Si7021 module added (with autodetected I2C Address)
- 2024.06.08 Callsign Validation for all Station that iGate/Digi hears.
- 2024.05.27 Battery Monitor for internal and External Voltages (to make board sleep and avoid low discharge of batterys) T-Beam boards now with Battery readings as well.
- 2024.05.23 Forced Reboot Mode added.
- 2024.05.22 Experimental backup-Digirepeater-Mode when "only" iGate mode loses WiFi connection added.
- 2024.05.20 WebConfig update to control whether Messages and Objects should be Tx to RF.
- 2024.05.17 HELTEC Wireless Stick Lite v3 support added.
- 2024.05.14 BME modules will be autodetected (I2C Address and if it is BME280/BMP280/BME680).
- 2024.05.13 PacketBuffer for Rx (25 Seg).
- 2024.05.11 HELTEC Wireless Tracker support added.
- 2024.04.23 T-LoRa32 v1.6/v2.1 with 915MHz support added.
- 2024.04.23 ESP32 + 4G/LTE MODEM A7670SA + LoRa (SX1278) support added.
- 2024.04.22 Wemos Lolin32 OLED DIY LoRa support added .
- 2024.04.21 WEB INSTALLER (thanks Damian SQ2CPA).
- 2024.04.20 New Output Buffer process: no more packets lost.
- 2024.04.13 Received Packets added on WebUI. - 2024.04.13 Received Packets added on WebUI.
- 2024.04.09 iGate/Digirepeater own GPS beacon is encoded (Base91) now. - 2024.04.09 iGate/Digirepeater own GPS beacon is encoded (Base91) now.
- 2024.03.18 OE5HWN MeshCom board support added. - 2024.03.18 OE5HWN MeshCom board support added.
@@ -55,22 +89,22 @@ ____________________________________________________
- 2024.01.19 TextSerialOutputForApp added to get text from Serial-Output over USB into PC for PinPoint App (https://www.pinpointaprs.com) and APRSIS32 App (http://aprsisce.wikidot.com) - 2024.01.19 TextSerialOutputForApp added to get text from Serial-Output over USB into PC for PinPoint App (https://www.pinpointaprs.com) and APRSIS32 App (http://aprsisce.wikidot.com)
- 2024.01.12 Added iGate Mode to also repeat packets (like a iGate+DigiRepeater) in stationMode 2 and 5. - 2024.01.12 Added iGate Mode to also repeat packets (like a iGate+DigiRepeater) in stationMode 2 and 5.
- 2024.01.11 Added iGate Mode to enable APRS-IS and LoRa beacon report at the same time. - 2024.01.11 Added iGate Mode to enable APRS-IS and LoRa beacon report at the same time.
- 2024.01.05 Added support for Lilygo TTGO T-Beam V1, V1.2, V1 + SX1268, V1.2 + SX1262. - 2024.01.05 Lilygo TTGO T-Beam V1, V1.2, V1 + SX1268, V1.2 + SX1262 support added.
- 2024.01.02 Added support for EByte 400M30S 1Watt LoRa module for DIY ESP32 iGate. - 2024.01.02 EByte 400M30S 1 Watt LoRa module for DIY ESP32 iGate support added.
- 2023.12.27 HELTEC V3 board support added. Thanks Luc ON2ON. - 2023.12.27 HELTEC V3 board support added. Thanks Luc ON2ON.
- 2023.12.26 Added BME680 module to BME/BMP280 modules supported. - 2023.12.26 BME680 module support added.
- 2023.12.07 MIC-E process and syslog added. - 2023.12.07 MIC-E process and Syslog added.
- 2023.12.06 HELTEC V2 board support added. - 2023.12.06 HELTEC V2 board support added.
- 2023.11.26 Small correction to enable Syslog in stationMode5. - 2023.11.26 Small correction to enable Syslog in stationMode5.
- 2023.10.09 Added "WIDE1-1" to Tx packets from iGate to be *repeated* by Digirepeaters. - 2023.10.09 Added "WIDE1-1" to Tx packets from iGate to be *repeated* by Digirepeaters.
- 2023.10.09 Added Support also for BMP280 module. - 2023.10.09 BMP280 module support added.
- 2023.08.20 Added External Voltage Measurement (Max 15V!) - 2023.08.20 Added External Voltage Measurement (Max 15V!)
- 2023.08.05 Ground Height Correction for Pressure readings added. - 2023.08.05 Ground Height Correction for Pressure readings added.
- 2023.07.31 StationMode5 added: iGate when WiFi and APRS available, DigiRepeater when not. - 2023.07.31 StationMode5 added: iGate when WiFi and APRS available, DigiRepeater when not.
- 2023.07.16 Small OTA, BME module update. - 2023.07.16 Small OTA, BME module update.
- 2023.07.05 Adding monitor info of Battery connected. - 2023.07.05 Adding monitor info of Battery connected.
- 2023.06.18 Info on Oled Screen mayor update, added RSSI and Distance to Listened Station. - 2023.06.18 Info on Oled Screen mayor update, added RSSI and Distance to Listened Station.
- 2023.06.17 Support for BME280 Module (Temperature, Humidity, Pressure) added. - 2023.06.17 BME280 Module (Temperature, Humidity, Pressure) support added.
- 2023.06.12 Syslog added. - 2023.06.12 Syslog added.
- 2023.06.10 OTA update support for Firmware and Filesystem. - 2023.06.10 OTA update support for Firmware and Filesystem.
- 2023.06.08 Adding Digirepeater Functions. - 2023.06.08 Adding Digirepeater Functions.
@@ -84,4 +118,4 @@ ____________________________________________________
__________________________________________ __________________________________________
# Hope You Enjoy this, 73 !! CA2RXU , Valparaiso, Chile # Hope You Enjoy this, 73! CA2RXU, Valparaiso, Chile
+41 -17
View File
@@ -3,7 +3,7 @@
"wifi": { "wifi": {
"autoAP": { "autoAP": {
"password": "1234567890", "password": "1234567890",
"powerOff": 10 "timeout": 10
}, },
"AP": [] "AP": []
}, },
@@ -18,21 +18,18 @@
"sendViaAPRSIS": false, "sendViaAPRSIS": false,
"sendViaRF": false "sendViaRF": false
}, },
"digi": {
"mode": 0
},
"tnc": {
"enableServer": false,
"enableSerial": false,
"acceptOwn": false
},
"aprs_is": { "aprs_is": {
"active": false, "active": false,
"passcode": "XYZVW", "passcode": "XYZVW",
"server": "rotate.aprs2.net", "server": "rotate.aprs2.net",
"port": 14580, "port": 14580,
"filter": "m/10", "filter": "m/10",
"toRF": false "messagesToRF": false,
"objectsToRF": false
},
"digi": {
"mode": 0,
"ecoMode": false
}, },
"lora": { "lora": {
"txFreq": 433775000, "txFreq": 433775000,
@@ -49,24 +46,51 @@
"timeout": 4, "timeout": 4,
"turn180": false "turn180": false
}, },
"battery": {
"sendInternalVoltage": false,
"monitorInternalVoltage": false,
"internalSleepVoltage": 2.9,
"sendExternalVoltage": false,
"externalVoltagePin": 34,
"monitorExternalVoltage": false,
"externalSleepVoltage": 10.9,
"voltageDividerR1": 100.0,
"voltageDividerR2": 27.0,
"sendVoltageAsTelemetry": true
},
"wxsensor": {
"active": false,
"heightCorrection": 0,
"temperatureCorrection": 0.0
},
"syslog": { "syslog": {
"active": false, "active": false,
"server": "192.168.0.100", "server": "192.168.0.100",
"port": 514 "port": 514
}, },
"bme": { "tnc": {
"active": false "enableServer": false,
"enableSerial": false,
"acceptOwn": false
}, },
"ota": { "ota": {
"username": "", "username": "",
"password": "" "password": ""
}, },
"webadmin": {
"username": "admin",
"password": ""
},
"ntp": {
"gmtCorrection": 0
},
"other": { "other": {
"rememberStationTime": 30, "rememberStationTime": 30,
"sendBatteryVoltage": false,
"externalVoltageMeasurement": false,
"externalVoltagePin": 34,
"lowPowerMode": false, "lowPowerMode": false,
"lowVoltageCutOff": 0 "lowVoltageCutOff": 0,
} "backupDigiMode": false,
"rebootMode": false,
"rebootModeTime": 6
},
"personalNote": ""
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

+972 -502
View File
File diff suppressed because it is too large Load Diff
+146 -106
View File
@@ -74,16 +74,15 @@ logCheckbox.addEventListener("change", function () {
function loadSettings(settings) { function loadSettings(settings) {
currentSettings = settings; currentSettings = settings;
// General // General
document.getElementById("callsign").value = settings.callsign; document.getElementById("callsign").value = settings.callsign;
// document.getElementById("stationMode").value = settings.stationMode; document.getElementById("beacon.comment").value = settings.beacon.comment;
document.getElementById("bme.active").checked = settings.bme.active; document.getElementById("beacon.path").value = settings.beacon.path;
document.getElementById("beacon.comment").value = settings.beacon.comment; document.getElementById("beacon.symbol").value = settings.beacon.symbol;
document.getElementById("beacon.symbol").value = settings.beacon.symbol; document.getElementById("beacon.overlay").value = settings.beacon.overlay;
document.getElementById("beacon.overlay").value = settings.beacon.overlay; document.getElementById("personalNote").value = settings.personalNote;
document.getElementById("action.symbol").value = settings.beacon.overlay + settings.beacon.symbol;
document.getElementById("action.symbol").value = settings.beacon.overlay + settings.beacon.symbol; document.querySelector(".list-networks").innerHTML = "";
document.querySelector(".list-networks").innerHTML = "";
// Networks // Networks
const wifiNetworks = settings.wifi.AP || []; const wifiNetworks = settings.wifi.AP || [];
@@ -119,103 +118,107 @@ function loadSettings(settings) {
}); });
// APRS-IS // APRS-IS
document.getElementById("aprs_is.active").checked = settings.aprs_is.active; document.getElementById("aprs_is.active").checked = settings.aprs_is.active;
document.getElementById("aprs_is.toRF").checked = settings.aprs_is.toRF; document.getElementById("aprs_is.messagesToRF").checked = settings.aprs_is.messagesToRF;
document.getElementById("aprs_is.server").value = settings.aprs_is.server; document.getElementById("aprs_is.objectsToRF").checked = settings.aprs_is.objectsToRF;
document.getElementById("aprs_is.port").value = settings.aprs_is.port; document.getElementById("aprs_is.server").value = settings.aprs_is.server;
document.getElementById("aprs_is.filter").value = settings.aprs_is.filter; document.getElementById("aprs_is.port").value = settings.aprs_is.port;
document.getElementById("aprs_is.passcode").value = document.getElementById("aprs_is.filter").value = settings.aprs_is.filter;
settings.aprs_is.passcode; document.getElementById("aprs_is.passcode").value = settings.aprs_is.passcode;
// Beacon
document.getElementById("beacon.latitude").value = settings.beacon.latitude;
document.getElementById("beacon.longitude").value = settings.beacon.longitude;
document.getElementById("beacon.interval").value = settings.beacon.interval;
document.getElementById("other.rememberStationTime").value = settings.other.rememberStationTime;
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF;
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
// Digi
document.getElementById("digi.mode").value = settings.digi.mode;
document.getElementById("digi.ecoMode").checked = settings.digi.ecoMode;
// LoRa
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
document.getElementById("lora.rxFreq").value = settings.lora.rxFreq;
document.getElementById("lora.txActive").checked = settings.lora.txActive;
document.getElementById("lora.rxActive").checked = settings.lora.rxActive;
document.getElementById("lora.spreadingFactor").value = settings.lora.spreadingFactor;
document.getElementById("lora.signalBandwidth").value = settings.lora.signalBandwidth;
document.getElementById("lora.codingRate4").value = settings.lora.codingRate4;
document.getElementById("lora.power").value = settings.lora.power;
// Display // Display
document.getElementById("display.alwaysOn").checked = document.getElementById("display.alwaysOn").checked = settings.display.alwaysOn;
settings.display.alwaysOn; document.getElementById("display.turn180").checked = settings.display.turn180;
document.getElementById("display.turn180").checked = document.getElementById("display.timeout").value = settings.display.timeout;
settings.display.turn180;
document.getElementById("display.timeout").value = settings.display.timeout;
if (settings.display.alwaysOn) { if (settings.display.alwaysOn) {
timeoutInput.disabled = true; timeoutInput.disabled = true;
} }
// WiFi Auto AP // BATTERY
document.getElementById("wifi.autoAP.password").value = document.getElementById("battery.sendInternalVoltage").checked = settings.battery.sendInternalVoltage;
settings.wifi.autoAP.password; document.getElementById("battery.monitorInternalVoltage").checked = settings.battery.monitorInternalVoltage;
document.getElementById("wifi.autoAP.powerOff").value = document.getElementById("battery.internalSleepVoltage").value = settings.battery.internalSleepVoltage.toFixed(1);
settings.wifi.autoAP.powerOff; document.getElementById("battery.sendExternalVoltage").checked = settings.battery.sendExternalVoltage;
document.getElementById("battery.externalVoltagePin").value = settings.battery.externalVoltagePin;
// Digi document.getElementById("battery.voltageDividerR1").value = settings.battery.voltageDividerR1.toFixed(1);
// document.getElementById("digi.comment").value = settings.digi.comment; document.getElementById("battery.voltageDividerR2").value = settings.battery.voltageDividerR2.toFixed(1);
// document.getElementById("digi.latitude").value = settings.digi.latitude; document.getElementById("battery.monitorExternalVoltage").checked = settings.battery.monitorExternalVoltage;
// document.getElementById("digi.longitude").value = settings.digi.longitude; document.getElementById("battery.externalSleepVoltage").value = settings.battery.externalSleepVoltage.toFixed(1);
document.getElementById("digi.mode").value = settings.digi.mode; document.getElementById("battery.sendVoltageAsTelemetry").checked = settings.battery.sendVoltageAsTelemetry;
// TNC // TELEMETRY WX SENSOR
if (settings.tnc) { document.getElementById("wxsensor.active").checked = settings.wxsensor.active;
document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer; document.getElementById("wxsensor.heightCorrection").value = settings.wxsensor.heightCorrection;
document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial; document.getElementById("wxsensor.temperatureCorrection").value = settings.wxsensor.temperatureCorrection.toFixed(1);
document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn;
} // SYSLOG
document.getElementById("syslog.active").checked = settings.syslog.active;
// OTA document.getElementById("syslog.server").value = settings.syslog.server;
document.getElementById("ota.username").value = settings.ota.username; document.getElementById("syslog.port").value = settings.syslog.port;
document.getElementById("ota.password").value = settings.ota.password;
// Beacon
document.getElementById("beacon.interval").value = settings.beacon.interval;
document.getElementById("other.rememberStationTime").value =
settings.other.rememberStationTime;
document.getElementById("other.sendBatteryVoltage").checked =
settings.other.sendBatteryVoltage;
document.getElementById("other.externalVoltageMeasurement").checked =
settings.other.externalVoltageMeasurement;
document.getElementById("other.externalVoltagePin").value =
settings.other.externalVoltagePin;
// document.getElementById("beacon.igateSendsLoRaBeacon").value =
// settings.beacon.igateSendsLoRaBeacon;
// document.getElementById("beacon.igateRepeatLoRaPackets").value =
// settings.beacon.igateRepeatLoRaPackets;
document.getElementById("beacon.path").value = settings.beacon.path;
document.getElementById("beacon.latitude").value = settings.beacon.latitude;
document.getElementById("beacon.longitude").value =
settings.beacon.longitude;
document.getElementById("beacon.sendViaAPRSIS").checked =
settings.beacon.sendViaAPRSIS;
document.getElementById("beacon.sendViaRF").checked =
settings.beacon.sendViaRF;
// Syslog
document.getElementById("syslog.active").checked = settings.syslog.active;
document.getElementById("syslog.server").value = settings.syslog.server;
document.getElementById("syslog.port").value = settings.syslog.port;
if (settings.syslog.active) { if (settings.syslog.active) {
serverField.disabled = false; serverField.disabled = false;
portField.disabled = false; portField.disabled = false;
} }
// LoRa // TNC
// document.getElementById("lora.digirepeaterTxFreq").value = if (settings.tnc) {
// settings.lora.digirepeaterTxFreq; document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer;
// document.getElementById("lora.iGateFreq").value = settings.lora.iGateFreq; document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial;
// document.getElementById("lora.digirepeaterRxFreq").value = document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn;
// settings.lora.digirepeaterRxFreq; }
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
document.getElementById("lora.rxFreq").value = settings.lora.rxFreq; // Reboot
document.getElementById("lora.txActive").checked = settings.lora.txActive; document.getElementById("other.rebootMode").checked = settings.other.rebootMode;
document.getElementById("lora.rxActive").checked = settings.lora.rxActive; document.getElementById("other.rebootModeTime").value = settings.other.rebootModeTime;
document.getElementById("lora.spreadingFactor").value =
settings.lora.spreadingFactor; // WiFi Auto AP
document.getElementById("lora.signalBandwidth").value = document.getElementById("wifi.autoAP.password").value = settings.wifi.autoAP.password;
settings.lora.signalBandwidth; document.getElementById("wifi.autoAP.timeout").value = settings.wifi.autoAP.timeout;
document.getElementById("lora.codingRate4").value =
settings.lora.codingRate4; // OTA
document.getElementById("lora.power").value = settings.lora.power; document.getElementById("ota.username").value = settings.ota.username;
document.getElementById("ota.password").value = settings.ota.password;
// Webadmin
document.getElementById("webadmin.active").checked = settings.webadmin.active;
document.getElementById("webadmin.username").value = settings.webadmin.username;
document.getElementById("webadmin.password").value = settings.webadmin.password;
// NTP
document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection;
// Experimental // Experimental
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode; document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode;
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode;
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
updateImage(); updateImage();
refreshSpeedStandard(); refreshSpeedStandard();
@@ -246,7 +249,7 @@ document.getElementById('reboot').addEventListener('click', function (e) {
showToast("Your device will be rebooted in a while"); showToast("Your device will be rebooted in a while");
}); });
const bmeCheckbox = document.querySelector("input[name='bme.active']"); const wxsensorCheckbox = document.querySelector("input[name='wxsensor.active']");
const stationModeSelect = document.querySelector("select[name='stationMode']"); const stationModeSelect = document.querySelector("select[name='stationMode']");
@@ -276,26 +279,67 @@ function updateImage() {
} }
function toggleFields() { function toggleFields() {
const externalVoltageMeasurementCheckbox = document.querySelector( const sendExternalVoltageCheckbox = document.querySelector(
'input[name="other.externalVoltageMeasurement"]' 'input[name="battery.sendExternalVoltage"]'
); );
const externalVoltagePinInput = document.querySelector( const externalVoltagePinInput = document.querySelector(
'input[name="other.externalVoltagePin"]' 'input[name="battery.externalVoltagePin"]'
); );
externalVoltagePinInput.disabled = externalVoltagePinInput.disabled = !sendExternalVoltageCheckbox.checked;
!externalVoltageMeasurementCheckbox.checked; voltageDividerR1.disabled = !sendExternalVoltageCheckbox.checked;
voltageDividerR2.disabled = !sendExternalVoltageCheckbox.checked;
const WebadminCheckbox = document.querySelector(
'input[name="webadmin.active"]'
);
const WebadminUsername = document.querySelector(
'input[name="webadmin.username"]'
);
const WebadminPassword = document.querySelector(
'input[name="webadmin.password"]'
);
WebadminUsername.disabled = !WebadminCheckbox.checked;
WebadminPassword.disabled = !WebadminCheckbox.checked;
} }
const externalVoltageMeasurementCheckbox = document.querySelector( const sendExternalVoltageCheckbox = document.querySelector(
'input[name="other.externalVoltageMeasurement"]' 'input[name="battery.sendExternalVoltage"]'
); );
const externalVoltagePinInput = document.querySelector( const externalVoltagePinInput = document.querySelector(
'input[name="other.externalVoltagePin"]' 'input[name="battery.externalVoltagePin"]'
); );
externalVoltageMeasurementCheckbox.addEventListener("change", function () { const voltageDividerR1 = document.querySelector(
'input[name="battery.voltageDividerR1"]'
);
const voltageDividerR2 = document.querySelector(
'input[name="battery.voltageDividerR2"]'
);
sendExternalVoltageCheckbox.addEventListener("change", function () {
externalVoltagePinInput.disabled = !this.checked; externalVoltagePinInput.disabled = !this.checked;
voltageDividerR1.disabled = !this.checked;
voltageDividerR2.disabled = !this.checked;
});
const WebadminCheckbox = document.querySelector(
'input[name="webadmin.active"]'
);
const WebadminUsername = document.querySelector(
'input[name="webadmin.username"]'
);
const WebadminPassword = document.querySelector(
'input[name="webadmin.password"]'
);
WebadminCheckbox.addEventListener("change", function () {
WebadminUsername.disabled = !this.checked;
WebadminPassword.disabled = !this.checked;
}); });
document.querySelector(".new button").addEventListener("click", function () { document.querySelector(".new button").addEventListener("click", function () {
@@ -469,13 +513,9 @@ function loadReceivedPackets(packets) {
packets.forEach((packet) => { packets.forEach((packet) => {
const element = document.createElement("tr"); const element = document.createElement("tr");
date.setTime(packet.millis);
const p = date.toUTCString().split(' ')
element.innerHTML = ` element.innerHTML = `
<td>${p[p.length-2]}</td> <td>${packet.rxTime}</td>
<td>${packet.packet}</td> <td>${packet.packet}</td>
<td>${packet.RSSI}</td> <td>${packet.RSSI}</td>
<td>${packet.SNR}</td> <td>${packet.SNR}</td>
Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

-39
View File
@@ -1,39 +0,0 @@
@echo off
echo Loading...
where /q python.exe
if %errorlevel% neq 0 (
echo "Python is not installed. Please install it and try again."
exit /b
)
where /q pip
if %errorlevel% neq 0 (
echo "pip is not installed. Please install it and try again."
exit /b
)
pip show pyserial >nul 2>&1
if %errorlevel% neq 0 (
echo "Installing pyserial..."
pip install pyserial
)
echo Your firmware will be upgraded without factory reset.
echo:
echo IF THIS IS YOUR FIRST FLASH ON THIS BOARD PLEASE USE install_with_factory_reset.bat INSTEAD!
echo:
echo Available COM ports:
python.exe -c "import serial.tools.list_ports; print('\n'.join([str(c) for c in serial.tools.list_ports.comports()]))"
echo:
set /p port="Enter COM port (for example COM5): "
python.exe ./bin/esptool/esptool.py --chip esp32 --port "%port%" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
pause
-15
View File
@@ -1,15 +0,0 @@
#!/bin/bash
echo "Your firmware will be upgraded without factory reset."
echo "IF THIS IS YOUR FIRST FLASH ON THIS BOARD PLEASE USE install_with_factory_reset.sh INSTEAD!"
read -p "Enter COM port (for example /dev/ttyS5): " port
PYTHON_CMD=python
if command -v python3 &> /dev/null
then
PYTHON_CMD=python3
fi
PYTHON_CMD ./bin/esptool/esptool.py --chip esp32 --port "$port" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
echo "Firmware flashed"
-44
View File
@@ -1,44 +0,0 @@
@echo off
echo Loading...
where /q python.exe
if %errorlevel% neq 0 (
echo "Python is not installed. Please install it and try again."
exit /b
)
where /q pip
if %errorlevel% neq 0 (
echo "pip is not installed. Please install it and try again."
exit /b
)
pip show pyserial >nul 2>&1
if %errorlevel% neq 0 (
echo "Installing pyserial..."
pip install pyserial
)
echo Your current configuration will be LOST!!!
echo Your current configuration will be LOST!!!
echo Your current configuration will be LOST!!!
echo:
echo If you already have this board flashed with our firmware please use install_upgrade.bat instead!
echo:
echo Available COM ports:
python.exe -c "import serial.tools.list_ports; print('\n'.join([str(c) for c in serial.tools.list_ports.comports()]))"
echo:
set /p port="Enter COM port (for example COM5): "
python.exe bin/esptool/esptool.py --chip esp32 --port "%port%" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 2686976 firmware/spiffs.bin
python.exe bin/esptool/esptool.py --chip esp32 --port "%port%" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
pause
-17
View File
@@ -1,17 +0,0 @@
#!/bin/bash
echo "Your firmware will be upgraded without factory reset."
echo "IF THIS IS YOUR FIRST FLASH ON THIS BOARD PLEASE USE install_with_factory_reset.sh INSTEAD!"
read -p "Enter COM port (for example /dev/ttyS5): " port
PYTHON_CMD=python
if command -v python3 &> /dev/null
then
PYTHON_CMD=python3
fi
$PYTHON_CMD ./bin/esptool/esptool.py --chip esp32 --port "$port" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 2686976 firmware/spiffs.bin
$PYTHON_CMD ./bin/esptool/esptool.py --chip esp32 --port "$port" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 firmware/bootloader.bin 0x8000 firmware/partitions.bin 0xe000 firmware/boot_app0.bin 0x10000 firmware/firmware.bin
echo "Firmware flashed"
+382 -50
View File
@@ -12,7 +12,8 @@
default_envs = ttgo-lora32-v21 default_envs = ttgo-lora32-v21
[env] [env]
platform = espressif32 @ 6.3.1 platform = espressif32 @ 6.7.0
board_build.partitions = min_spiffs.csv
framework = arduino framework = arduino
monitor_speed = 115200 monitor_speed = 115200
board_build.embed_files = board_build.embed_files =
@@ -21,137 +22,468 @@ board_build.embed_files =
data_embed/script.js.gz data_embed/script.js.gz
data_embed/bootstrap.css.gz data_embed/bootstrap.css.gz
data_embed/bootstrap.js.gz data_embed/bootstrap.js.gz
lib_deps = data_embed/favicon.png.gz
bblanchon/ArduinoJson@^6.20.2
adafruit/Adafruit GFX Library @ 1.11.5
adafruit/Adafruit SSD1306 @ 2.5.7
mikalhart/TinyGPSPlus @ 1.0.3
adafruit/Adafruit Unified Sensor@^1.1.9
adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BMP280 Library@^2.6.8
adafruit/Adafruit BME680 Library@^2.0.4
jgromes/RadioLib @ 6.1.0
lewisxhe/XPowersLib@^0.1.8
ayushsharma82/ElegantOTA@^3.1.0
ottowinter/ESPAsyncWebServer-esphome@3.0.0
esphome/AsyncTCP-esphome@2.1.1
extra_scripts = extra_scripts =
pre:tools/compress.py pre:tools/compress.py
debug_tool = esp-prog debug_tool = esp-prog
[common]
lib_deps =
jgromes/RadioLib @ 6.6.0
mikalhart/TinyGPSPlus @ 1.0.3
bblanchon/ArduinoJson @ 6.21.3
adafruit/Adafruit Unified Sensor @ 1.1.14
adafruit/Adafruit BME280 Library @ 2.2.4
adafruit/Adafruit BMP280 Library @ 2.6.8
adafruit/Adafruit BME680 Library @ 2.0.4
adafruit/Adafruit Si7021 Library @ 1.5.3
ayushsharma82/ElegantOTA @ 3.1.5
mathieucarbou/ESPAsyncWebServer @ 3.2.3
mathieucarbou/AsyncTCP @ 3.2.5
arduino-libraries/NTPClient @ 3.2.1
[env:ttgo-lora32-v21] [env:ttgo-lora32-v21]
board = ttgo-lora32-v21 board = ttgo-lora32-v21
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DTTGO_T_LORA32_V2_1 -DTTGO_T_LORA32_V2_1
-DHAS_SX127X
-DHAS_SX1278 -DHAS_SX1278
-DHAS_ADC_CALIBRATION
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ttgo-lora32-v21_915]
board = ttgo-lora32-v21
build_flags =
-Werror -Wall
-DTTGO_T_LORA32_V2_1_915
-DHAS_SX1276
-DHAS_ADC_CALIBRATION
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:heltec-lora32-v2] [env:heltec-lora32-v2]
board = ttgo-lora32-v21 board = ttgo-lora32-v21
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DHELTEC_V2 -DHELTEC_V2
-DHAS_SX127X
-DHAS_SX1278 -DHAS_SX1278
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:heltec_wifi_lora_32_V3] [env:heltec_wifi_lora_32_V3]
board = heltec_wifi_lora_32_V3 board = heltec_wifi_lora_32_V3
board_build.mcu = esp32s3 board_build.mcu = esp32s3
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DHELTEC_V3 -DHELTEC_V3
-DHAS_SX126X
-DHAS_SX1262 -DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:heltec_wireless_stick]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
-Werror -Wall
-DHELTEC_WS
-DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:heltec_wireless_stick_lite_v3]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
-Werror -Wall
-DHELTEC_WSL_V3
-DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
[env:heltec_wireless_stick_lite_v3_display]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
-Werror -Wall
-DHELTEC_WSL_V3_DISPLAY
-DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
[env:ESP32_DIY_LoRa] [env:ESP32_DIY_LoRa]
board = esp32dev board = esp32dev
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DESP32_DIY_LoRa -DESP32_DIY_LoRa
-DHAS_SX127X
-DHAS_SX1278 -DHAS_SX1278
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_LoRa_915]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_LoRa_915
-DHAS_SX1276
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa] [env:ESP32_DIY_1W_LoRa]
board = esp32dev board = esp32dev
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DESP32_DIY_1W_LoRa -DESP32_DIY_1W_LoRa
-DHAS_SX126X
-DHAS_SX1268 -DHAS_SX1268
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa_915]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_1W_LoRa_915
-DHAS_SX1262
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa_LLCC68]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_1W_LoRa_LLCC68
-DHAS_LLCC68
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_DIY_1W_LoRa_Mesh_V1_2]
board = esp32dev
build_flags =
-Werror -Wall
-DESP32_DIY_1W_LoRa_Mesh_V1_2
-DHAS_SX1268
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ttgo-t-beam-v1_2] [env:ttgo-t-beam-v1_2]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DTTGO_T_Beam_V1_2 -DTTGO_T_Beam_V1_2
-DHAS_SX127X
-DHAS_SX1278 -DHAS_SX1278
-DHAS_AXP2101 -DHAS_AXP2101
-DHAS_GPS
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_2_915]
board = ttgo-t-beam
build_flags =
-Werror -Wall
-DTTGO_T_Beam_V1_2_915
-DHAS_SX1276
-DHAS_AXP2101
-DHAS_GPS
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1] [env:ttgo-t-beam-v1]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DTTGO_T_Beam_V1_0 -DTTGO_T_Beam_V1_0
-DHAS_SX127X
-DHAS_SX1278 -DHAS_SX1278
-DHAS_AXP192 -DHAS_AXP192
-DHAS_GPS
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_915]
board = ttgo-t-beam
build_flags =
-Werror -Wall
-DTTGO_T_Beam_V1_0_915
-DHAS_SX1276
-DHAS_AXP192
-DHAS_GPS
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_SX1268] [env:ttgo-t-beam-v1_SX1268]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DTTGO_T_Beam_V1_0_SX1268 -DTTGO_T_Beam_V1_0_SX1268
-DHAS_SX126X
-DHAS_SX1268 -DHAS_SX1268
-DHAS_AXP192 -DHAS_AXP192
-DHAS_GPS
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:ttgo-t-beam-v1_2_SX1262] [env:ttgo-t-beam-v1_2_SX1262]
board = ttgo-t-beam board = ttgo-t-beam
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DTTGO_T_Beam_V1_2_SX1262 -DTTGO_T_Beam_V1_2_SX1262
-DHAS_SX126X
-DHAS_SX1262 -DHAS_SX1262
-DHAS_AXP2101 -DHAS_AXP2101
-DHAS_GPS
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
lewisxhe/XPowersLib @ 0.2.4
[env:OE5HWN_MeshCom] [env:ESP32_DIY_LoRa_A7670]
board = esp32dev board = esp32dev
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DOE5HWN_MeshCom -DESP32_DIY_LoRa_A7670
-DHAS_SX126X -DHAS_SX1278
-DHAS_SX1268 -DHAS_A7670
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1
[env:heltec_wireless_stick] [env:ESP32_DIY_LoRa_A7670_915]
board = heltec_wifi_lora_32_V3 board = esp32dev
board_build.mcu = esp32s3 build_flags =
build_flags =
-Werror -Wall -Werror -Wall
-DHELTEC_WS -DESP32_DIY_LoRa_A7670_915
-DHAS_SX126X -DHAS_SX1276
-DHAS_SX1262 -DHAS_A7670
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
vshymanskyy/TinyGSM @ 0.12.0
vshymanskyy/StreamDebugger @ 1.0.1
[env:heltec_wireless_tracker]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
-Werror -Wall
-DHELTEC_WIRELESS_TRACKER
-DHAS_SX1262
-DHAS_GPS
-DGPS_BAUDRATE=115200
-DHAS_TFT
-D USER_SETUP_LOADED
-D TFT_WIDTH=80
-D TFT_HEIGHT=160
-D ST7735_DRIVER
-D ST7735_GREENTAB160x80
-D TFT_RGB_ORDER=TFT_BGR
-D TFT_MOSI=42
-D TFT_SCLK=41
-D TFT_CS=38
-D TFT_DC=40
-D TFT_RST=39
-D TFT_BL=21
-D TFT_BACKLIGHT_ON=1
-D TOUCH_CS=-1
-D LOAD_GLCD
-D LOAD_FONT2
-D LOAD_FONT4
-D LOAD_FONT6
-D LOAD_FONT7
-D LOAD_FONT8
-D SPI_FREQUENCY=27000000
-D USE_HSPI_PORT
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
bodmer/TFT_eSPI @ 2.5.43
[env:heltec_ht-ct62] [env:heltec_ht-ct62]
board = heltec_wireless_stick_lite board = heltec_wireless_stick_lite
board_build.mcu = esp32c3 board_build.mcu = esp32c3
build_flags = build_flags =
-Werror -Wall -Werror -Wall
-DHELTEC_HTCT62 -DHELTEC_HTCT62
-DHAS_SX126X
-DHAS_SX1262 -DHAS_SX1262
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:heltec_wireless_paper]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
-Werror -Wall
-DHELTEC_WP
-DHAS_SX1262
-DHAS_EPAPER
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
[env:OE5HWN_MeshCom]
board = esp32dev
build_flags =
-Werror -Wall
-DOE5HWN_MeshCom
-DHAS_SX1268
-DHAS_1W_LORA
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:WEMOS-LOLIN32-OLED-DIY]
board = lolin32
build_flags =
-Werror -Wall
-DWEMOS_LOLIN32_OLED_DIY_LoRa
-DHAS_SX1278
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:WEMOS-D1-R32-RA02]
board = wemos_d1_uno32
build_flags =
-Werror -Wall
-DWEMOS_D1_R32_RA02
-DHAS_SX1278
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:WEMOS_S2_MINI_DIY_LoRa]
board = lolin_s2_mini
build_flags =
-Werror -Wall
-DWEMOS_S2_MINI_DIY_LoRa
-DHAS_SX1278
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:esp32c3_DIY_1W_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DESP32C3_DIY_1W_LoRa
-DHAS_SX1268
-DHAS_1W_LORA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:esp32c3_DIY_1W_LoRa_915]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DESP32C3_DIY_1W_LoRa_915
-DHAS_SX1262
-DHAS_1W_LORA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
[env:ESP32_C3_OctopusLab_LoRa]
board = esp32-c3-devkitm-1
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DESP32_C3_OctopusLab_LoRa
-DHAS_SX1268
-DRADIO_HAS_XTAL
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
lib_deps =
${common.lib_deps}
adafruit/Adafruit GFX Library @ 1.11.9
adafruit/Adafruit SSD1306 @ 2.5.10
+205
View File
@@ -0,0 +1,205 @@
#include "configuration.h"
#include "aprs_is_utils.h"
#include "boards_pinout.h"
#include "A7670_utils.h"
#include "lora_utils.h"
#include "display.h"
#include "utils.h"
#ifdef HAS_A7670
#define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1
#include <TinyGsmClient.h>
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
extern Configuration Config;
extern String firstLine;
bool modemStartUp = false;
bool serverStartUp = false;
bool userBytesSended = false;
bool beaconBytesSended = false;
bool beaconSended = false;
bool stationBeacon = false;
extern bool modemLoggedToAPRSIS;
namespace A7670_Utils {
bool checkModemOn() {
bool modemReady = false;
Serial.print("Starting Modem ... ");
displayShow(firstLine, "Starting Modem...", " ", " ", 0);
pinMode(A7670_ResetPin, OUTPUT); //A7670 Reset
digitalWrite(A7670_ResetPin, LOW);
delay(100);
digitalWrite(A7670_ResetPin, HIGH);
delay(3000);
digitalWrite(A7670_ResetPin, LOW);
pinMode(A7670_PWR_PIN, OUTPUT);
digitalWrite(A7670_PWR_PIN, LOW);
delay(100);
digitalWrite(A7670_PWR_PIN, HIGH);
delay(1000);
digitalWrite(A7670_PWR_PIN, LOW);
int i = 20;
while (i) {
SerialAT.println("AT");
delay(500);
if (SerialAT.available()) {
String r = SerialAT.readString();
//Serial.println(r);
if ( r.indexOf("OK") >= 0 ) {
modemReady = true;
i = 1;
Serial.println("Modem Ready!\n");
displayShow(firstLine, "Starting Modem...", "---> Modem Ready", " ", 0);
return true;
}
}
if (!modemReady) {
delay(500);
}
i--;
}
return false;
}
void setup() {
SerialAT.begin(115200, SERIAL_8N1, A7670_RX_PIN, A7670_TX_PIN);
if (checkModemOn()) {;
delay(1000);
//setup_gps(); // if gps active / won't be need for now
} else {
displayShow(firstLine, "Starting Modem...", "---> Failed !!!", " ", 0);
Serial.println(F("*********** Failed to connect to the modem! ***********"));
}
}
bool checkATResponse(const String& ATMessage) {
int delayATMessage = 3000;
bool validAT = false;
//Serial.println(ATMessage);
int i = 10;
while (i) {
if (!validAT) {
SerialAT.println(ATMessage);
}
delay(500);
if (SerialAT.available()) {
String response = SerialAT.readString();
//Serial.println(response); // DEBUG of Modem AT message
if(response.indexOf("verified") >= 0) {
Serial.println("Logged! (User Validated)\n");
displayShow(firstLine, "Connecting APRS-IS...", "---> Logged!", " ", 1000);
Serial.println("#################### APRS-IS FEED ####################");
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage == "AT+NETOPEN" && response.indexOf("OK") >= 0) {
Serial.println("Port Open!");
displayShow(firstLine, "Opening Port...", "---> Port Open", " ", 0);
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage == "AT+NETOPEN" && response.indexOf("Network is already opened") >= 0) {
Serial.println("Port Open! (was already opened)");
displayShow(firstLine, "Opening Port...", "---> Port Open", " ", 0);
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage.indexOf("AT+CIPOPEN") == 0 && response.indexOf("PB DONE") >= 0) {
Serial.println("Contacted!");
displayShow(firstLine, "Connecting APRS-IS...", "---> Contacted", " ", 0);
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage.indexOf("AT+CIPSEND=0,") == 0 && response.indexOf(">") >= 0) {
Serial.print(".");
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage.indexOf(Config.callsign) >= 3 && !modemLoggedToAPRSIS && response.indexOf("OK") >= 0 && !stationBeacon) { // login info
validAT = true;
delayATMessage = 0;
} else if (ATMessage.indexOf(Config.callsign) == 0 && !beaconSended && response.indexOf("OK") >= 0 && !stationBeacon) { // self beacon or querys
validAT = true;
i = 1;
delayATMessage = 0;
} else if (stationBeacon && response.indexOf("OK") >= 0) { //upload others beacons
validAT = true;
i = 1;
delayATMessage = 0;
}
}
delay(delayATMessage);
i--;
}
return validAT;
}
void APRS_IS_connect() {
String loginInfo = "user ";
loginInfo += Config.callsign;
loginInfo += " pass ";
loginInfo += String(Config.aprs_is.passcode);
loginInfo += " vers CA2RXU_LoRa_iGate 1.3 filter ";
loginInfo += Config.aprs_is.filter;
Serial.println("-----> Connecting to APRS IS");
while (!modemStartUp) {
Serial.print("Opening Port... ");
displayShow(firstLine, "Opening Port...", " ", " ", 0);
modemStartUp = checkATResponse("AT+NETOPEN");
delay(2000);
} while (!serverStartUp) {
Serial.print("Connecting APRS-IS Server... ");
displayShow(firstLine, "Connecting APRS-IS...", " ", " ", 0);
serverStartUp = checkATResponse("AT+CIPOPEN=0,\"TCP\",\"" + String(Config.aprs_is.server) + "\"," + String(Config.aprs_is.port));
delay(2000);
} while (!userBytesSended) {
Serial.print("Writing User Login Data ");
displayShow(firstLine, "Connecting APRS-IS...", "---> User Login Data", " ", 0);
userBytesSended = checkATResponse("AT+CIPSEND=0," + String(loginInfo.length()+1));
delay(2000);
} while (!modemLoggedToAPRSIS) {
Serial.print(".");
modemLoggedToAPRSIS = checkATResponse(loginInfo);
delay(2000);
}
}
void uploadToAPRSIS(const String& packet) {
beaconBytesSended = checkATResponse("AT+CIPSEND=0," + String(packet.length()+1));
delay(2000);
if (beaconBytesSended) {
Serial.print(".");
beaconSended = checkATResponse(packet);
}
if (!beaconSended) {
Serial.println("------------------------------------> UPLOAD FAILED!!!");
} else {
Serial.println("Packet Uploaded to APRS-IS!");
}
beaconBytesSended = false;
beaconSended = false;
}
void listenAPRSIS() {
if (SerialAT.available()) {
String packetAPRSIS = SerialAT.readStringUntil('\r');
packetAPRSIS.trim();
if (!packetAPRSIS.startsWith("#") && packetAPRSIS.indexOf("+IPD") == -1 && packetAPRSIS.indexOf("RECV") == -1 && packetAPRSIS.length() > 0) {
APRS_IS_Utils::processAPRSISPacket(packetAPRSIS);
}
}
delay(1);
}
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef A7670_UTILS_H_
#define A7670_UTILS_H_
#include <Arduino.h>
namespace A7670_Utils {
bool checkModemOn();
void setup();
bool checkATResponse(const String& ATMessage);
void APRS_IS_connect();
void uploadToAPRSIS(const String& packet);
void listenAPRSIS();
}
#endif
+106 -130
View File
@@ -1,165 +1,137 @@
/*______________________________________________________________________________________________________________
██╗ ██████╗ ██████╗ █████╗ █████╗ ██████╗ ██████╗ ███████╗ ██╗ ██████╗ █████╗ ████████╗███████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗██╔════╝ ██║██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝
██║ ██║ ██║██████╔╝███████║ ███████║██████╔╝██████╔╝███████╗ ██║██║ ███╗███████║ ██║ █████╗
██║ ██║ ██║██╔══██╗██╔══██║ ██╔══██║██╔═══╝ ██╔══██╗╚════██║ ██║██║ ██║██╔══██║ ██║ ██╔══╝
███████╗╚██████╔╝██║ ██║██║ ██║ ██║ ██║██║ ██║ ██║███████║ ██║╚██████╔╝██║ ██║ ██║ ███████╗
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
Ricardo Guzman - CA2RXU
https://github.com/richonguzman/LoRa_APRS_Tracker
(donations : http://paypal.me/richonguzman)
______________________________________________________________________________________________________________*/
#include <ElegantOTA.h>
#include <TinyGPS++.h>
#include <Arduino.h> #include <Arduino.h>
#include <WiFi.h> #include <WiFi.h>
#include <vector> #include <vector>
#include "configuration.h" #include "configuration.h"
#include "battery_utils.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "station_utils.h" #include "station_utils.h"
#include "boards_pinout.h"
#include "battery_utils.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "pins_config.h"
#include "query_utils.h" #include "query_utils.h"
#include "power_utils.h" #include "power_utils.h"
#include "lora_utils.h" #include "lora_utils.h"
#include "wifi_utils.h" #include "wifi_utils.h"
#include "digi_utils.h" #include "digi_utils.h"
#include "gps_utils.h" #include "gps_utils.h"
#include "bme_utils.h"
#include "web_utils.h" #include "web_utils.h"
#include "tnc_utils.h" #include "tnc_utils.h"
#include "ntp_utils.h"
#include "wx_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
#include <ElegantOTA.h> #ifdef HAS_A7670
#include "battery_utils.h" #include "A7670_utils.h"
#endif
Configuration Config; String versionDate = "2024.10.21";
WiFiClient espClient; Configuration Config;
WiFiClient espClient;
#ifdef HAS_GPS
HardwareSerial gpsSerial(1);
TinyGPSPlus gps;
#endif
String versionDate = "2024.04.13"; uint8_t myWiFiAPIndex = 0;
uint8_t myWiFiAPIndex = 0; int myWiFiAPSize = Config.wifiAPs.size();
int myWiFiAPSize = Config.wifiAPs.size(); WiFi_AP *currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
WiFi_AP *currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
bool isUpdatingOTA = false; bool isUpdatingOTA = false;
bool statusAfterBoot = true; uint32_t lastBatteryCheck = 0;
bool beaconUpdate = true;
uint32_t lastBeaconTx = 0;
uint32_t previousWiFiMillis = 0;
uint32_t lastScreenOn = millis();
uint32_t lastWiFiCheck = 0; bool backUpDigiMode = false;
bool WiFiConnect = true; bool modemLoggedToAPRSIS = false;
bool WiFiConnected = false;
bool WiFiAutoAPStarted = false;
long WiFiAutoAPTime = false;
uint32_t lastBatteryCheck = 0;
uint32_t bmeLastReading = -60000;
String batteryVoltage;
std::vector<String> lastHeardStation;
std::vector<String> lastHeardStation_temp;
std::vector<String> packetBuffer;
std::vector<String> packetBuffer_temp;
std::vector<ReceivedPacket> receivedPackets; std::vector<ReceivedPacket> receivedPackets;
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, iGateBeaconPacket, iGateLoRaBeaconPacket; String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
//#define STARTUP_DELAY 5 //min
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_HTCT62)
pinMode(batteryPin, INPUT);
#endif
#ifdef HAS_INTERNAL_LED
pinMode(internalLedPin, OUTPUT);
#endif
if (Config.externalVoltageMeasurement) {
pinMode(Config.externalVoltagePin, INPUT);
}
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_2_SX1262)
POWER_Utils::setup(); POWER_Utils::setup();
#endif
delay(1000);
Utils::setupDisplay(); Utils::setupDisplay();
Config.check();
LoRa_Utils::setup(); LoRa_Utils::setup();
Utils::validateFreqs(); Utils::validateFreqs();
GPS_Utils::setup();
iGateBeaconPacket = GPS_Utils::generateBeacon(); #ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
iGateLoRaBeaconPacket = GPS_Utils::generateiGateLoRaBeacon(); displayShow("", " STARTUP DELAY ...", "", "", 0);
delay(STARTUP_DELAY * 60 * 1000);
#ifdef HELTEC_HTCT62 #endif
if (Config.lowPowerMode) {
gpio_wakeup_enable(GPIO_NUM_3, GPIO_INTR_HIGH_LEVEL);
esp_deep_sleep_enable_gpio_wakeup(GPIO_NUM_3, ESP_GPIO_WAKEUP_GPIO_HIGH);
long lastBeacon = 0;
LoRa_Utils::startReceive();
while (true) {
auto wakeup_reason = esp_sleep_get_wakeup_cause();
if (wakeup_reason == 7) { // packet received
Serial.println("Received packet");
String packet = LoRa_Utils::receivePacket();
Serial.println(packet);
if (Config.digi.mode == 2) { // If Digi enabled
DIGI_Utils::loop(packet); // Send received packet to Digi
}
if (packet.indexOf(Config.callsign + ":?APRSELP{") != -1) { // Send `?APRSELP` to exit low power
Serial.println("Got ?APRSELP message, exiting from low power mode");
break;
};
}
long time = esp_timer_get_time() / 1000000;
if (lastBeacon == 0 || time - lastBeacon >= Config.beacon.interval * 60) {
Serial.println("Sending beacon");
String comment = Config.beacon.comment;
if (Config.sendBatteryVoltage) {
comment += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V";
}
if (Config.externalVoltageMeasurement) {
comment += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V";
}
LoRa_Utils::sendNewPacket("APRS", iGateLoRaBeaconPacket + comment);
lastBeacon = time;
}
#ifdef HELTEC_HTCT62
if (Config.lowPowerMode) {
gpio_wakeup_enable(GPIO_NUM_3, GPIO_INTR_HIGH_LEVEL);
esp_deep_sleep_enable_gpio_wakeup(GPIO_NUM_3, ESP_GPIO_WAKEUP_GPIO_HIGH);
long lastBeacon = 0;
LoRa_Utils::startReceive(); LoRa_Utils::startReceive();
while (true) {
auto wakeup_reason = esp_sleep_get_wakeup_cause();
if (wakeup_reason == 7) { // packet received
Serial.println("Received packet");
String packet = LoRa_Utils::receivePacket();
Serial.println(packet);
if (Config.digi.mode == 2) DIGI_Utils::processLoRaPacket(packet);
Serial.println("Sleeping"); if (packet.indexOf(Config.callsign + ":?APRSELP{") != -1) { // Send `?APRSELP` to exit low power
Serial.println("Got ?APRSELP message, exiting from low power mode");
break;
};
}
long time = esp_timer_get_time() / 1000000;
if (lastBeacon == 0 || time - lastBeacon >= Config.beacon.interval * 60) {
Serial.println("Sending beacon");
String comment = Config.beacon.comment;
if (Config.battery.sendInternalVoltage) comment += " Batt=" + String(BATTERY_Utils::checkInternalVoltage(),2) + "V";
if (Config.battery.sendExternalVoltage) comment += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V";
LoRa_Utils::sendNewPacket(GPS_Utils::getiGateLoRaBeaconPacket() + comment);
lastBeacon = time;
}
long sleep = (Config.beacon.interval * 60) - (time - lastBeacon); LoRa_Utils::startReceive();
Serial.println("Sleeping");
Serial.flush(); long sleep = (Config.beacon.interval * 60) - (time - lastBeacon);
Serial.flush();
esp_sleep_enable_timer_wakeup(sleep * 1000000); esp_sleep_enable_timer_wakeup(sleep * 1000000);
esp_light_sleep_start(); esp_light_sleep_start();
Serial.println("Waked up");
Serial.println("Waked up"); }
Config.loramodule.rxActive = false;
} }
#endif
Config.loramodule.rxActive = false; DIGI_Utils::checkEcoMode();
}
#endif
WIFI_Utils::setup(); WIFI_Utils::setup();
NTP_Utils::setup();
SYSLOG_Utils::setup(); SYSLOG_Utils::setup();
BME_Utils::setup(); WX_Utils::setup();
WEB_Utils::setup(); WEB_Utils::setup();
TNC_Utils::setup(); TNC_Utils::setup();
#ifdef HAS_A7670
A7670_Utils::setup();
#endif
Utils::checkRebootMode();
} }
void loop() { void loop() {
WIFI_Utils::checkIfAutoAPShouldPowerOff(); WIFI_Utils::checkAutoAPTimeout();
if (isUpdatingOTA) { if (isUpdatingOTA) {
ElegantOTA.loop(); ElegantOTA.loop();
@@ -172,40 +144,40 @@ void loop() {
thirdLine = Utils::getLocalIP(); thirdLine = Utils::getLocalIP();
WIFI_Utils::checkWiFi(); // Always use WiFi, not related to IGate/Digi mode WIFI_Utils::checkWiFi();
// Utils::checkWiFiInterval();
if (Config.aprs_is.active && !espClient.connected()) { #ifdef HAS_A7670
APRS_IS_Utils::connect(); if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
} #else
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) APRS_IS_Utils::connect();
#endif
NTP_Utils::update();
TNC_Utils::loop(); TNC_Utils::loop();
Utils::checkDisplayInterval(); Utils::checkDisplayInterval();
Utils::checkBeaconInterval(); Utils::checkBeaconInterval();
APRS_IS_Utils::checkStatus(); // Need that to update display, maybe split this and send APRSIS status to display func? APRS_IS_Utils::checkStatus(); // Need that to update display, maybe split this and send APRSIS status to display func?
String packet = ""; String packet = "";
if (Config.loramodule.rxActive) { if (Config.loramodule.rxActive) {
packet = LoRa_Utils::receivePacket(); // We need to fetch LoRa packet above APRSIS and Digi packet = LoRa_Utils::receivePacket(); // We need to fetch LoRa packet above APRSIS and Digi
} }
if (packet != "") { if (packet != "") {
if (Config.aprs_is.active) { // If APRSIS enabled if (Config.aprs_is.active) { // If APRSIS enabled
APRS_IS_Utils::processLoRaPacket(packet); // Send received packet to APRSIS APRS_IS_Utils::processLoRaPacket(packet); // Send received packet to APRSIS
} }
if (Config.digi.mode == 2) { // If Digi enabled if (Config.loramodule.txActive && (Config.digi.mode == 2 || Config.digi.mode == 3 || backUpDigiMode)) { // If Digi enabled
DIGI_Utils::loop(packet); // Send received packet to Digi STATION_Utils::clean25SegBuffer();
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
} }
if (Config.tnc.enableServer) { // If TNC server enabled if (Config.tnc.enableServer) { // If TNC server enabled
TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS
} }
if (Config.tnc.enableSerial) { // If Serial KISS enabled if (Config.tnc.enableSerial) { // If Serial KISS enabled
TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS
} }
@@ -214,6 +186,10 @@ void loop() {
if (Config.aprs_is.active) { // If APRSIS enabled if (Config.aprs_is.active) { // If APRSIS enabled
APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
} }
STATION_Utils::processOutputPacketBuffer();
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
Utils::checkRebootTime();
Utils::checkSleepByLowBatteryVoltage(1);
} }
+232 -117
View File
@@ -4,33 +4,40 @@
#include "station_utils.h" #include "station_utils.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "query_utils.h" #include "query_utils.h"
#include "lora_utils.h" #include "A7670_utils.h"
#include "digi_utils.h" #include "digi_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern WiFiClient espClient; extern WiFiClient espClient;
extern uint32_t lastScreenOn; extern uint32_t lastScreenOn;
extern String firstLine; extern String firstLine;
extern String secondLine; extern String secondLine;
extern String thirdLine; extern String thirdLine;
extern String fourthLine; extern String fourthLine;
extern String fifthLine; extern String fifthLine;
extern String sixthLine; extern String sixthLine;
extern String seventhLine; extern String seventhLine;
extern bool modemLoggedToAPRSIS;
extern bool backUpDigiMode;
uint32_t lastRxTime = millis();
#ifdef HAS_A7670
extern bool stationBeacon;
#endif
namespace APRS_IS_Utils { namespace APRS_IS_Utils {
void upload(String line) { void upload(const String& line) {
espClient.print(line + "\r\n"); espClient.print(line + "\r\n");
} }
void connect() { void connect() {
uint8_t count = 0;
String aprsauth;
Serial.print("Connecting to APRS-IS ... "); Serial.print("Connecting to APRS-IS ... ");
uint8_t count = 0;
while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) { while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
Serial.println("Didn't connect with server..."); Serial.println("Didn't connect with server...");
delay(1000); delay(1000);
@@ -46,11 +53,15 @@ namespace APRS_IS_Utils {
} }
else { else {
Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")"); Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")");
// String filter = "t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance; // String filter = "t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance;
aprsauth = "user " + Config.callsign + " pass " + Config.aprs_is.passcode + " vers CA2RXU_LoRa_iGate 1.3 filter " + Config.aprs_is.filter; String aprsAuth = "user ";
upload(aprsauth); aprsAuth += Config.callsign;
aprsAuth += " pass ";
aprsAuth += Config.aprs_is.passcode;
aprsAuth += " vers CA2RXU_LoRa_iGate 2.0 filter ";
aprsAuth += Config.aprs_is.filter;
upload(aprsAuth);
delay(200); delay(200);
} }
} }
@@ -59,73 +70,102 @@ namespace APRS_IS_Utils {
String wifiState, aprsisState; String wifiState, aprsisState;
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
wifiState = "OK"; wifiState = "OK";
} } else {
else { if (backUpDigiMode || Config.digi.ecoMode) {
wifiState = "AP"; wifiState = "--";
} else {
if (!Config.display.alwaysOn) { wifiState = "AP";
display_toggle(true); }
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
} }
lastScreenOn = millis(); lastScreenOn = millis();
} }
if (!Config.aprs_is.active) { if (!Config.aprs_is.active) {
aprsisState = "OFF"; aprsisState = "OFF";
} else {
#ifdef HAS_A7670
if (modemLoggedToAPRSIS) {
aprsisState = "OK";
} else {
aprsisState = "--";
}
#else
if (espClient.connected()) {
aprsisState = "OK";
} else {
aprsisState = "--";
}
#endif
if(aprsisState == "--" && !Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
lastScreenOn = millis();
}
} }
else if (espClient.connected()) { secondLine = "WiFi: ";
aprsisState = "OK"; secondLine += wifiState;
} secondLine += " APRS-IS: ";
else { secondLine += aprsisState;
aprsisState = "--";
if (!Config.display.alwaysOn) {
display_toggle(true);
}
lastScreenOn = millis();
}
secondLine = "WiFi: " + wifiState + " APRS-IS: " + aprsisState;
} }
String createPacket(String packet) { String checkForStartingBytes(const String& packet) {
if (packet.indexOf("\x3c\xff\x01") != -1) {
return packet.substring(0, packet.indexOf("\x3c\xff\x01"));
} else {
return packet;
}
}
String buildPacketToUpload(const String& packet) {
String buildedPacket = packet.substring(3, packet.indexOf(":"));
if (!(Config.aprs_is.active && Config.digi.mode == 0)) { // Check if NOT only IGate if (!(Config.aprs_is.active && Config.digi.mode == 0)) { // Check if NOT only IGate
return packet.substring(3, packet.indexOf(":")) + ",qAR," + Config.callsign + packet.substring(packet.indexOf(":")); buildedPacket += ",qAR,";
} } else {
else { buildedPacket += ",qAO,";
return packet.substring(3, packet.indexOf(":")) + ",qAO," + Config.callsign + packet.substring(packet.indexOf(":"));
} }
buildedPacket += Config.callsign;
buildedPacket += checkForStartingBytes(packet.substring(packet.indexOf(":")));
return buildedPacket;
} }
bool processReceivedLoRaMessage(String sender, String packet) { bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty) {
String ackMessage, receivedMessage; String receivedMessage;
if (packet.indexOf("{") > 0) { // ack? if (packet.indexOf("{") > 0) { // ack?
ackMessage = "ack" + packet.substring(packet.indexOf("{") + 1); String ackMessage = "ack";
ackMessage.concat(packet.substring(packet.indexOf("{") + 1));
ackMessage.trim(); ackMessage.trim();
delay(4000);
//Serial.println(ackMessage); //Serial.println(ackMessage);
String addToBuffer = Config.callsign;
addToBuffer += ">APLRG1";
if (!thirdParty) addToBuffer += ",RFONLY";
if (Config.beacon.path != "") {
addToBuffer += ",";
addToBuffer += Config.beacon.path;
}
addToBuffer += "::";
String processedSender = sender;
for (int i = sender.length(); i < 9; i++) { for (int i = sender.length(); i < 9; i++) {
sender += ' '; processedSender += ' ';
}
if (Config.beacon.path == "") {
LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1,RFONLY::" + sender + ":" + ackMessage);
} else {
LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1,RFONLY," + Config.beacon.path + "::" + sender + ":" + ackMessage);
} }
addToBuffer += processedSender;
addToBuffer += ":";
addToBuffer += ackMessage;
STATION_Utils::addToOutputPacketBuffer(addToBuffer);
receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{")); receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{"));
} } else {
else {
receivedMessage = packet.substring(packet.indexOf(":") + 1); receivedMessage = packet.substring(packet.indexOf(":") + 1);
} }
if (receivedMessage.indexOf("?") == 0) { if (receivedMessage.indexOf("?") == 0) {
delay(2000); if (!Config.display.alwaysOn && Config.display.timeout != 0) {
if (!Config.display.alwaysOn) { displayToggle(true);
display_toggle(true);
} }
LoRa_Utils::sendNewPacket("APRS", QUERY_Utils::process(receivedMessage, sender, "LoRa")); STATION_Utils::addToOutputPacketBuffer(QUERY_Utils::process(receivedMessage, sender, false, thirdParty));
lastScreenOn = millis(); lastScreenOn = millis();
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0); displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0);
return true; return true;
} }
else { else {
@@ -133,106 +173,181 @@ namespace APRS_IS_Utils {
} }
} }
void processLoRaPacket(String packet) { void processLoRaPacket(const String& packet) {
if (espClient.connected()) { if (espClient.connected() || modemLoggedToAPRSIS) {
bool queryMessage = false;
String aprsPacket, Sender, AddresseeAndMessage, Addressee;
if (packet != "") { if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("TCPIP") == -1) && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) { if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
Sender = packet.substring(3, packet.indexOf(">")); int firstColonIndex = packet.indexOf(":");
STATION_Utils::updateLastHeard(Sender); if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
//STATION_Utils::updatePacketBuffer(packet); const String& Sender = packet.substring(3, packet.indexOf(">"));
Utils::typeOfPacket(aprsPacket, "LoRa-APRS"); if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) {
if (Sender != Config.callsign) { // avoid listening yourself by digirepeating
AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
queryMessage = processReceivedLoRaMessage(Sender, AddresseeAndMessage);
}
if (!queryMessage) {
aprsPacket = createPacket(packet);
if (!Config.display.alwaysOn) {
display_toggle(true);
}
lastScreenOn = millis();
upload(aprsPacket);
Utils::println("---> Uploaded to APRS-IS");
STATION_Utils::updateLastHeard(Sender); STATION_Utils::updateLastHeard(Sender);
Utils::typeOfPacket(aprsPacket, "LoRa-APRS"); Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
bool queryMessage = false;
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
}
if (!queryMessage) {
const String& aprsPacket = buildPacketToUpload(packet);
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
}
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
}
} }
} }
} }
} }
} }
} }
void processAPRSISPacket(String packet) { String buildPacketToTx(const String& aprsisPacket, uint8_t packetType) {
String Sender, AddresseeAndMessage, Addressee, receivedMessage; String packet = aprsisPacket;
packet.trim();
String outputPacket = Config.callsign;
outputPacket += ">APLRG1";
if (Config.beacon.path != "") {
outputPacket += ",";
outputPacket += Config.beacon.path;
}
outputPacket += ":}";
outputPacket += packet.substring(0, packet.indexOf(",")); // Callsign>Tocall
outputPacket.concat(",TCPIP,");
outputPacket.concat(Config.callsign);
outputPacket.concat("*");
switch (packetType) {
case 0: // gps
if (packet.indexOf(":=") > 0) {
outputPacket += packet.substring(packet.indexOf(":="));
} else {
outputPacket += packet.substring(packet.indexOf(":!"));
}
break;
case 1: // messages
outputPacket += packet.substring(packet.indexOf("::"));
break;
case 2: // status
outputPacket += packet.substring(packet.indexOf(":>"));
break;
case 3: // telemetry
outputPacket += packet.substring(packet.indexOf("::"));
break;
case 4: // mic-e
if (packet.indexOf(":`") > 0) {
outputPacket += packet.substring(packet.indexOf(":`"));
} else {
outputPacket += packet.substring(packet.indexOf(":'"));
}
break;
case 5: // object
outputPacket += packet.substring(packet.indexOf(":;"));
break;
}
return outputPacket;
}
void processAPRSISPacket(const String& packet) {
if (!packet.startsWith("#")) { if (!packet.startsWith("#")) {
if (packet.indexOf("::") > 0) { if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
Sender = packet.substring(0, packet.indexOf(">")); String Sender = packet.substring(0, packet.indexOf(">"));
AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim(); Addressee.trim();
if (Addressee == Config.callsign) { // its for me! if (Addressee == Config.callsign) { // its for me!
String receivedMessage;
if (AddresseeAndMessage.indexOf("{") > 0) { // ack? if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
String ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1); String ackMessage = "ack";
ackMessage += AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1);
ackMessage.trim(); ackMessage.trim();
delay(4000); delay(4000);
for (int i = Sender.length(); i < 9; i++) { for (int i = Sender.length(); i < 9; i++) {
Sender += ' '; Sender += ' ';
} }
String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage;// + "\n";
upload(ackPacket); String ackPacket = Config.callsign;
ackPacket += ">APLRG1,TCPIP,qAC::";
ackPacket += Sender;
ackPacket += ":";
ackPacket += ackMessage;
#ifdef HAS_A7670
A7670_Utils::uploadToAPRSIS(ackPacket);
#else
upload(ackPacket);
#endif
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{")); receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
} else { } else {
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1); receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
} }
if (receivedMessage.indexOf("?") == 0) { if (receivedMessage.indexOf("?") == 0) {
Utils::println("Received Query APRS-IS : " + packet); Utils::println("Received Query APRS-IS : " + packet);
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, "APRSIS"); String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n"))); //Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
if (!Config.display.alwaysOn) { if (!Config.display.alwaysOn && Config.display.timeout != 0) {
display_toggle(true); displayToggle(true);
} }
lastScreenOn = millis(); lastScreenOn = millis();
delay(500); delay(500);
upload(queryAnswer); #ifdef HAS_A7670
SYSLOG_Utils::log("APRSIS Tx", queryAnswer, 0, 0, 0); A7670_Utils::uploadToAPRSIS(queryAnswer);
#else
upload(queryAnswer);
#endif
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
fifthLine = "APRS-IS ----> APRS-IS"; fifthLine = "APRS-IS ----> APRS-IS";
sixthLine = Config.callsign; sixthLine = Config.callsign;
for (int j = sixthLine.length();j < 9;j++) { for (int j = sixthLine.length();j < 9;j++) {
sixthLine += " "; sixthLine += " ";
} }
sixthLine += "> " + Sender; sixthLine += "> ";
seventhLine = "QUERY = " + receivedMessage; sixthLine += Sender;
seventhLine = "QUERY = ";
seventhLine += receivedMessage;
} }
} else { } else {
Utils::print("Received from APRS-IS : " + packet); Utils::print("Received Message from APRS-IS : " + packet);
if (STATION_Utils::wasHeard(Addressee)) {
if (Config.aprs_is.toRF && STATION_Utils::wasHeard(Addressee)) { STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
LoRa_Utils::sendNewPacket("APRS", LoRa_Utils::generatePacket(packet)); displayToggle(true);
display_toggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
Utils::typeOfPacket(packet, "APRS-LoRa"); Utils::typeOfPacket(packet, 1); // APRS-LoRa
} }
} }
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
Utils::println("Received Object from APRS-IS : " + packet);
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
displayToggle(true);
lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
} }
} }
} }
void listenAPRSIS() { void listenAPRSIS() {
if (espClient.connected()) { #ifdef HAS_A7670
if (espClient.available()) { A7670_Utils::listenAPRSIS();
String aprsisPacket = espClient.readStringUntil('\r'); #else
// Serial.println(aprsisPacket); if (espClient.connected()) {
processAPRSISPacket(aprsisPacket); if (espClient.available()) {
String aprsisPacket = espClient.readStringUntil('\r');
// Serial.println(aprsisPacket);
processAPRSISPacket(aprsisPacket);
lastRxTime = millis();
}
} }
} #endif
} }
} }
+12 -8
View File
@@ -6,14 +6,18 @@
namespace APRS_IS_Utils { namespace APRS_IS_Utils {
void upload(String line); void upload(const String& line);
void connect(); void connect();
void checkStatus(); void checkStatus();
String createPacket(String unprocessedPacket); String checkForStartingBytes(const String& packet);
bool processReceivedLoRaMessage(String sender, String packet);
void processLoRaPacket(String packet); String buildPacketToUpload(const String& packet);
void processAPRSISPacket(String packet); bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty);
void listenAPRSIS(); void processLoRaPacket(const String& packet);
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType);
void processAPRSISPacket(const String& packet);
void listenAPRSIS();
} }
+230 -37
View File
@@ -1,18 +1,47 @@
#include <Arduino.h>
#include "battery_utils.h" #include "battery_utils.h"
#include "configuration.h" #include "configuration.h"
#include "pins_config.h" #include "boards_pinout.h"
#include "power_utils.h"
#include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastBatteryCheck; extern uint32_t lastBatteryCheck;
float adcReadingTransformation = (3.3/4095); bool shouldSleepLowVoltage = false;
float voltageDividerCorrection = 0.288;
// for External Voltage Measurment (MAX = 15Volts !!!) float adcReadingTransformation = (3.3/4095);
float R1 = 100.000; //in Kilo-Ohms float voltageDividerCorrection = 0.288;
float R2 = 27.000; //in Kilo-Ohms float readingCorrection = 0.125;
float readingCorrection = 0.125; float multiplyCorrection = 0.035;
float multiplyCorrection = 0.035;
float voltageDividerTransformation = 0.0;
int telemetryCounter = random(1,999);
#ifdef HAS_ADC_CALIBRATION
#include <esp_adc_cal.h>
#if defined(TTGO_T_LORA32_V2_1) || defined(TTGO_T_LORA32_V2_1_915)
#define InternalBattery_ADC_Channel ADC1_CHANNEL_7 // t_lora32 pin35
#define ExternalVoltage_ADC_Channel ADC1_CHANNEL_6 // t_lora32 pin34
#endif
#if CONFIG_IDF_TARGET_ESP32
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF
#elif CONFIG_IDF_TARGET_ESP32S2
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
#elif CONFIG_IDF_TARGET_ESP32C3
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
#elif CONFIG_IDF_TARGET_ESP32S3
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT
#endif
esp_adc_cal_characteristics_t adc_chars;
#endif
bool calibrationEnable = false;
namespace BATTERY_Utils { namespace BATTERY_Utils {
@@ -21,53 +50,217 @@ namespace BATTERY_Utils {
return (voltage - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; return (voltage - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} }
float checkBattery() { void adcCalibration() {
int sample; #ifdef HAS_ADC_CALIBRATION
int sampleSum = 0; if (calibrationEnable) {
for (int i = 0; i < 100; i++) { adc1_config_width(ADC_WIDTH_BIT_12);
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_HTCT62) adc1_config_channel_atten(InternalBattery_ADC_Channel, ADC_ATTEN_DB_12);
sample = analogRead(batteryPin); adc1_config_channel_atten(ExternalVoltage_ADC_Channel, ADC_ATTEN_DB_12);
}
#endif
}
void adcCalibrationCheck() {
#ifdef HAS_ADC_CALIBRATION
esp_err_t ret;
ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME);
/*if (ret == ESP_ERR_NOT_SUPPORTED) {
Serial.println("Calibration scheme not supported, skip software calibration");
} else if (ret == ESP_ERR_INVALID_VERSION) {
Serial.println("eFuse not burnt, skip software calibration");
} else */
if (ret == ESP_OK) {
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, 1100, &adc_chars);
//Serial.printf("eFuse Vref:%u mV\n", adc_chars.vref);
calibrationEnable = true;
} /*else {
Serial.println("Invalid Calibration Arg");
}*/
#endif
}
void setup() {
if ((Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) && Config.battery.voltageDividerR2 != 0) voltageDividerTransformation = (Config.battery.voltageDividerR1 + Config.battery.voltageDividerR2) / Config.battery.voltageDividerR2;
#if defined(HAS_ADC_CALIBRATION)
if (Config.battery.sendInternalVoltage || Config.battery.monitorInternalVoltage || Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
adcCalibrationCheck();
adcCalibration();
}
#endif
}
float checkInternalVoltage() {
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
if(POWER_Utils::isBatteryConnected()) {
return POWER_Utils::getBatteryVoltage();
} else {
return 0.0;
}
#else
int sample;
int sampleSum = 0;
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_TRACKER)
digitalWrite(ADC_CTRL, HIGH);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP)
digitalWrite(ADC_CTRL, LOW);
#endif
#endif #endif
#if defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
sample = 0; for (int i = 0; i < 100; i++) {
#if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915)
sample = 0;
#else
#ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
sample = adc1_get_raw(InternalBattery_ADC_Channel);
} else {
sample = analogRead(BATTERY_PIN);
}
#else
#ifdef BATTERY_PIN
sample = analogRead(BATTERY_PIN);
#else
sample = 0;
#endif
#endif
#endif
sampleSum += sample;
delayMicroseconds(50);
}
#ifdef ADC_CTRL
#if defined(HELTEC_WIRELESS_TRACKER)
digitalWrite(ADC_CTRL, LOW);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_V2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WP)
digitalWrite(ADC_CTRL, HIGH);
#endif
#ifdef HELTEC_WP
double inputDivider = (1.0 / (10.0 + 10.0)) * 10.0; // The voltage divider is a 10k + 10k resistor in series
#else
double inputDivider = (1.0 / (390.0 + 100.0)) * 100.0; // The voltage divider is a 390k + 100k resistor in series, 100k on the low side.
#endif
return (((sampleSum/100) * adcReadingTransformation) / inputDivider) + 0.285; // Yes, this offset is excessive, but the ADC on the ESP32s3 is quite inaccurate and noisy. Adjust to own measurements.
#else
#ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
float voltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars);
voltage *= 2; // for 100K/100K voltage divider
voltage /= 1000;
return voltage;
} else {
return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping
}
#else
return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; // raw voltage without mapping
#endif
#endif #endif
sampleSum += sample; // return mapVoltage(voltage, 3.34, 4.71, 3.0, 4.2); // mapped voltage
delayMicroseconds(50); #endif
}
float voltage = (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection;
return voltage; // raw voltage without mapping
// return mapVoltage(voltage, 3.34, 4.71, 3.0, 4.2); // mapped voltage
} }
float checkExternalVoltage() { float checkExternalVoltage() {
int sample; int sample;
int sampleSum = 0; int sampleSum = 0;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
sample = analogRead(Config.externalVoltagePin); #ifdef HAS_ADC_CALIBRATION
if (calibrationEnable){
sample = adc1_get_raw(ExternalVoltage_ADC_Channel);
} else {
sample = analogRead(Config.battery.externalVoltagePin);
}
#else
sample = analogRead(Config.battery.externalVoltagePin);
#endif
sampleSum += sample; sampleSum += sample;
delayMicroseconds(50); delayMicroseconds(50);
} }
float voltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * ((R1+R2)/R2)) - multiplyCorrection; float extVoltage;
#ifdef HAS_ADC_CALIBRATION
return voltage; // raw voltage without mapping if (calibrationEnable){
extVoltage = esp_adc_cal_raw_to_voltage(sampleSum / 100, &adc_chars) * voltageDividerTransformation; // in mV
extVoltage /= 1000;
} else {
extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
}
#else
extVoltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * voltageDividerTransformation) - multiplyCorrection;
#endif
return extVoltage; // raw voltage without mapping
// return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage // return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage
} }
void checkIfShouldSleep() { void checkIfShouldSleep() {
if (lastBatteryCheck == 0 || millis() - lastBatteryCheck >= 15 * 60 * 1000) { if (lastBatteryCheck == 0 || millis() - lastBatteryCheck >= 15 * 60 * 1000) {
lastBatteryCheck = millis(); lastBatteryCheck = millis();
if (checkInternalVoltage() < Config.lowVoltageCutOff) {
float voltage = checkBattery();
if (voltage < Config.lowVoltageCutOff) {
ESP.deepSleep(1800000000); // 30 min sleep (60s = 60e6) ESP.deepSleep(1800000000); // 30 min sleep (60s = 60e6)
} }
} }
} }
void startupBatteryHealth() {
#ifdef BATTERY_PIN
if (Config.battery.monitorInternalVoltage && checkInternalVoltage() < Config.battery.internalSleepVoltage + 0.1) {
shouldSleepLowVoltage = true;
}
#endif
#ifndef HELTEC_WP
if (Config.battery.monitorExternalVoltage && checkExternalVoltage() < Config.battery.externalSleepVoltage + 0.1) {
shouldSleepLowVoltage = true;
}
#endif
if (shouldSleepLowVoltage) {
Utils::checkSleepByLowBatteryVoltage(0);
}
}
String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType) { // 0 = internal battery(0-4,2V) , 1 = external battery(0-15V)
String encodedBytes;
int tempValue;
if (firstBytes) {
tempValue = value;
} else {
switch (voltageType) {
case 0:
tempValue = value * 100; // Internal voltage calculation
break;
case 1:
tempValue = (value * 100) / 2; // External voltage calculation
break;
default:
tempValue = value;
break;
}
}
int firstByte = tempValue / 91;
tempValue -= firstByte * 91;
encodedBytes = char(firstByte + 33);
encodedBytes += char(tempValue + 33);
return encodedBytes;
}
String generateEncodedTelemetry() {
String telemetry = "|";
telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0);
telemetryCounter++;
if (telemetryCounter == 1000) {
telemetryCounter = 0;
}
if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(checkInternalVoltage(), false, 0);
if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(checkExternalVoltage(), false, 1);
telemetry += "|";
return telemetry;
}
} }
+10 -3
View File
@@ -6,9 +6,16 @@
namespace BATTERY_Utils { namespace BATTERY_Utils {
float checkBattery(); void adcCalibration();
float checkExternalVoltage(); void adcCalibrationCheck();
void checkIfShouldSleep(); void setup();
float checkInternalVoltage();
float checkExternalVoltage();
void checkIfShouldSleep(); // ????
void startupBatteryHealth();
String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType);
String generateEncodedTelemetry();
} }
-185
View File
@@ -1,185 +0,0 @@
#include "bme_utils.h"
#include "configuration.h"
#include "gps_utils.h"
#include "display.h"
#define SEALEVELPRESSURE_HPA (1013.25)
#define HEIGHT_CORRECTION 0 // in meters
#define CORRECTION_FACTOR (8.2296) // for meters
extern Configuration Config;
extern String fifthLine;
extern uint32_t bmeLastReading;
float newHum, newTemp, newPress, newGas;
namespace BME_Utils {
#ifdef BME280Sensor
Adafruit_BME280 bme;
#endif
#ifdef BMP280Sensor
Adafruit_BMP280 bme;
#endif
#ifdef BME680Sensor
Adafruit_BME680 bme;
#endif
void setup() {
if (Config.bme.active) {
bool status;
status = bme.begin(0x76); // Don't forget to join pins for righ direction on BME280!
if (!status) {
Serial.println("Could not find a valid BME280 or BMP280 sensor, check wiring!");
show_display("ERROR", "", "BME/BMP sensor active", "but no sensor found...");
while (1); // sacar esto para que quede pegado si no encuentra BME280
} else {
#ifdef BME280Sensor
bme.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::FILTER_OFF
);
Serial.println("init : BME280 Module ... done!");
#endif
#ifdef BMP280Sensor
bme.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1,
Adafruit_BMP280::SAMPLING_X1,
Adafruit_BMP280::FILTER_OFF
);
Serial.println("init : BMP280 Module ... done!");
#endif
#ifdef BME680Sensor
bme.setTemperatureOversampling(BME680_OS_1X);
bme.setHumidityOversampling(BME680_OS_1X);
bme.setPressureOversampling(BME680_OS_1X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_0);
Serial.println("init : BME680 Module ... done!");
#endif
}
} else {
Serial.println("(BME/BMP sensor not 'active' in 'igate_conf.json')");
}
}
String generateTempString(float bmeTemp) {
String strTemp;
strTemp = String((int)bmeTemp);
switch (strTemp.length()) {
case 1:
return "00" + strTemp;
break;
case 2:
return "0" + strTemp;
break;
case 3:
return strTemp;
break;
default:
return "-999";
}
}
String generateHumString(float bmeHum) {
String strHum;
strHum = String((int)bmeHum);
switch (strHum.length()) {
case 1:
return "0" + strHum;
break;
case 2:
return strHum;
break;
case 3:
if ((int)bmeHum == 100) {
return "00";
} else {
return "-99";
}
break;
default:
return "-99";
}
}
String generatePresString(float bmePress) {
String strPress;
strPress = String((int)bmePress);
switch (strPress.length()) {
case 1:
return "000" + strPress + "0";
break;
case 2:
return "00" + strPress + "0";
break;
case 3:
return "0" + strPress + "0";
break;
case 4:
return strPress + "0";
break;
case 5:
return strPress;
break;
default:
return "-99999";
}
}
String readDataSensor() {
String wx, tempStr, humStr, presStr;
uint32_t lastReading = millis() - bmeLastReading;
if (lastReading > 60*1000) {
#if defined(BME280Sensor) || defined(BMP280Sensor)
bme.takeForcedMeasurement();
newTemp = bme.readTemperature();
newPress = (bme.readPressure() / 100.0F);
#ifdef BME280Sensor
newHum = bme.readHumidity();
#endif
#ifdef BMP280Sensor
newHum = 0;
#endif
#endif
#ifdef BME680Sensor
bme.performReading();
delay(50);
if (bme.endReading()) {
newTemp = bme.temperature;
newPress = (bme.pressure / 100.0F);
newHum = bme.humidity;
newGas = bme.gas_resistance / 1000.0; // in Kilo ohms
}
#endif
bmeLastReading = millis();
}
if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
Serial.println("BME/BMP Module data failed");
wx = ".../...g...t...r...p...P...h..b.....";
fifthLine = "";
return wx;
} else {
tempStr = generateTempString((newTemp * 1.8) + 32);
#if defined(BME280Sensor) || defined(BME680Sensor)
humStr = generateHumString(newHum);
#endif
#ifdef BMP280Sensor
humStr = "..";
#endif
presStr = generatePresString(newPress + (HEIGHT_CORRECTION/CORRECTION_FACTOR));
fifthLine = "BME-> " + String(int(newTemp))+"C " + humStr + "% " + presStr.substring(0,4) + "hPa";
wx = ".../...g...t" + tempStr + "r...p...P...h" + humStr + "b" + presStr;
#ifdef BME680Sensor
wx += "Gas: " + String(newGas) + "Kohms ";
#endif
return wx;
}
}
}
-33
View File
@@ -1,33 +0,0 @@
#ifndef BME_UTILS_H_
#define BME_UTILS_H_
#include <Arduino.h>
#include <Adafruit_Sensor.h>
#define BME280Sensor // its set by default but you should comment it with "//"
//#define BMP280Sensor // and delete "//" from the one you want to use.
//#define BME680Sensor
#ifdef BME280Sensor
#include <Adafruit_BME280.h>
#endif
#ifdef BMP280Sensor
#include <Adafruit_BMP280.h>
#endif
#ifdef BME680Sensor
#include <Adafruit_BME680.h>
#endif
namespace BME_Utils {
void setup();
String generateTempString(float bmeTemp);
String generateHumString(float bmeHum);
String generatePresString(float bmePress);
String readDataSensor();
}
#endif
+284
View File
@@ -0,0 +1,284 @@
#ifndef PINS_CONFIG_H_
#define PINS_CONFIG_H_
#include <Arduino.h>
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
// LORA MODULES
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA32_V2_1_915) || defined(ESP32_DIY_LoRa_915) || defined(TTGO_T_Beam_V1_2_915) || defined(TTGO_T_Beam_V1_0_915)
#define RADIO_SCLK_PIN 5 // GPIO5 - SX1278 SCK
#define RADIO_MISO_PIN 19 // GPIO19 - SX1278 MISO
#define RADIO_MOSI_PIN 27 // GPIO27 - SX1278 MOSI
#define RADIO_CS_PIN 18 // GPIO18 - SX1278 CS ---> NSS
#define RADIO_RST_PIN 14 // GPIO14 - SX1278 RST
#define RADIO_BUSY_PIN 26 // GPIO26 - SX1278 IRQ ---->DIO0
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WIRELESS_TRACKER) || defined(HELTEC_WS) || defined(HELTEC_WP)
#define RADIO_SCLK_PIN 9 // SX1262 SCK
#define RADIO_MISO_PIN 11 // SX1262 MISO
#define RADIO_MOSI_PIN 10 // SX1262 MOSI
#define RADIO_CS_PIN 8 // SX1262 NSS
#define RADIO_RST_PIN 12 // SX1262 RST
#define RADIO_DIO1_PIN 14 // SX1262 DIO1
#define RADIO_BUSY_PIN 13 // SX1262 BUSY
#endif
#if defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915) || defined(ESP32_DIY_1W_LoRa_LLCC68) // Ebyte E22 400M30S (SX1268) or E22 900M30S (SX1262) or E220 LLCC68
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
#endif
#if defined(ESP32_DIY_1W_LoRa_Mesh_V1_2) // https://github.com/NanoVHF/Meshtastic-DIY/tree/main/PCB/ESP-32-devkit_EBYTE-E22/Mesh-v1.02-2LCD-FreePins
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_RST_PIN 23
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 32
#define RADIO_RXEN 14
#define RADIO_TXEN 13
#endif
#ifdef WEMOS_LOLIN32_OLED_DIY_LoRa
#define RADIO_SCLK_PIN 15
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 12
#define RADIO_CS_PIN 14
#define RADIO_RST_PIN 2
#define RADIO_BUSY_PIN 25
#endif
#if defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262)
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_DIO0_PIN 26
#define RADIO_RST_PIN 23
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 32
#endif
#if defined(OE5HWN_MeshCom)
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 26
#define RADIO_RXEN 14
#define RADIO_TXEN 13
#endif
#if defined(HELTEC_HTCT62)
#define RADIO_SCLK_PIN 10 // SX1262 SCK
#define RADIO_MISO_PIN 6 // SX1262 MISO
#define RADIO_MOSI_PIN 7 // SX1262 MOSI
#define RADIO_CS_PIN 8 // SX1262 NSS
#define RADIO_RST_PIN 5 // SX1262 RST
#define RADIO_DIO1_PIN 3 // SX1262 DIO1
#define RADIO_BUSY_PIN 4 // SX1262 BUSY
#endif
#if defined(ESP32_DIY_LoRa_A7670) || defined(ESP32_DIY_LoRa_A7670_915)
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 2
#define RADIO_RST_PIN 0
#define RADIO_BUSY_PIN 32
#define A7670_PWR_PIN 4
#define A7670_ResetPin 5
#define A7670_TX_PIN 26
#define A7670_RX_PIN 27
#endif
#ifdef WEMOS_D1_R32_RA02
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_BUSY_PIN 12
#define RADIO_RST_PIN 13
#define RADIO_DIO1_PIN 14
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 36
#endif
#if defined(ESP32C3_DIY_1W_LoRa) || defined(ESP32C3_DIY_1W_LoRa_915)
#define RADIO_SCLK_PIN 8
#define RADIO_MISO_PIN 9
#define RADIO_MOSI_PIN 10
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 4
#define RADIO_DIO1_PIN 2
#define RADIO_BUSY_PIN 3
#define RADIO_RXEN 6
#define RADIO_TXEN 7
#endif
#ifdef WEMOS_S2_MINI_DIY_LoRa
#define RADIO_SCLK_PIN 36
#define RADIO_MISO_PIN 37
#define RADIO_MOSI_PIN 35
#define RADIO_CS_PIN 34
#define RADIO_BUSY_PIN 38
#define RADIO_RST_PIN 33
#endif
// OLED
#if defined(TTGO_T_LORA32_V2_1) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(OE5HWN_MeshCom) || defined(ESP32_DIY_LoRa_A7670) || defined(TTGO_T_LORA32_V2_1_915) || defined(ESP32_DIY_LoRa_915) || defined(TTGO_T_Beam_V1_0_915) || defined(TTGO_T_Beam_V1_2_915) || defined(ESP32_DIY_LoRa_A7670_915) || defined(ESP32_DIY_1W_LoRa_915) || defined(ESP32_DIY_1W_LoRa_LLCC68) || defined(ESP32_DIY_1W_LoRa_Mesh_V1_2)
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif
#if defined(HELTEC_V2) || defined(HELTEC_WS)
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
#endif
#if defined(HELTEC_V3)
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 21
#endif
#ifdef WEMOS_LOLIN32_OLED_DIY_LoRa
#define OLED_SDA 5
#define OLED_SCL 4
#define OLED_RST -1
#endif
#if !defined(HELTEC_HTCT62) && !defined(HELTEC_WSL_V3) && !defined(ESP32C3_DIY_1W_LoRa) && !defined(ESP32C3_DIY_1W_LoRa_915) && !defined(WEMOS_S2_MINI_DIY_LoRa)
#define HAS_DISPLAY
#endif
// Leds and other stuff
#ifdef HELTEC_HTCT62
#define BATTERY_PIN 1
#endif
#ifdef WEMOS_S2_MINI_DIY_LoRa
#define INTERNAL_LED_PIN 15
#endif
#if defined(TTGO_T_LORA32_V2_1) || defined(TTGO_T_LORA32_V2_1_915)
#define INTERNAL_LED_PIN 25 // Green Led
#define BATTERY_PIN 35
#endif
#if defined(HELTEC_V2)
#define INTERNAL_LED_PIN 25
#define BATTERY_PIN 37
#define ADC_CTRL 21
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY) || defined(HELTEC_WS)
#define INTERNAL_LED_PIN 35
#define BATTERY_PIN 1
#define VEXT_CTRL 36
#define ADC_CTRL 37
#define BOARD_I2C_SDA 41
#define BOARD_I2C_SCL 42
#ifdef HELTEC_WSL_V3_DISPLAY
#define OLED_RST -1
#endif
#endif
#if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_LoRa_915) || defined(ESP32_DIY_1W_LoRa) || defined(ESP32_DIY_1W_LoRa_915)
#define INTERNAL_LED_PIN 2
#endif
#if defined(ESP32_DIY_LoRa_A7670) || defined(ESP32_DIY_LoRa_A7670_915)
#define INTERNAL_LED_PIN 13 // 13 for V1.1 and 12 for V1.0
#define BATTERY_PIN 35
#endif
#ifdef HELTEC_WIRELESS_TRACKER
#define INTERNAL_LED_PIN 18
#define BATTERY_PIN 1
#define ADC_CTRL 2 // HELTEC Wireless Tracker ADC_CTRL = HIGH powers the voltage divider to read BatteryPin. Only on V05 = V1.1
#define VEXT_CTRL 3 // To turn on GPS and TFT
#define BOARD_I2C_SDA 7
#define BOARD_I2C_SCL 6
#endif
#ifdef HELTEC_WP
#define INTERNAL_LED_PIN 18
#define BATTERY_PIN 20
#define ADC_CTRL 19
#define VEXT_CTRL 45
#define BOARD_I2C_SDA 37
#define BOARD_I2C_SCL 36
#define EPAPER_BUSY 7
#define EPAPER_RST 6
#define EPAPER_DC 5
#define EPAPER_CS 4
#define EPAPER_SCL 3
#define EPAPER_SDA 2
#endif
#ifdef ESP32_C3_DIY_LoRa // just testing!
#define OLED_SDA 8
#define OLED_SCL 9
#define OLED_RST 10
#define RADIO_SCLK_PIN 4
#define RADIO_MISO_PIN 5
#define RADIO_MOSI_PIN 6
#define RADIO_CS 7
#define RADIO_RST_PIN 3
#define RADIO_IRQ_PIN 2
#endif
#if defined(ESP32_C3_OctopusLab_LoRa)
#define OLED_SDA 0
#define OLED_SCL 1
#define OLED_RST -1
#define RADIO_SCLK_PIN 6
#define RADIO_MISO_PIN 4
#define RADIO_MOSI_PIN 7
#define RADIO_CS_PIN 5
#define RADIO_DIO1_PIN 3
#define RADIO_RST_PIN -1
#define RADIO_BUSY_PIN 8
#endif
#if defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_2_915) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_915) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262)
#define GPS_RX 12
#define GPS_TX 34
#endif
#if defined( HELTEC_WIRELESS_TRACKER)
#define GPS_RX 34
#define GPS_TX 33
#endif
/* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev )
SX1278-------------------> ESP32 ttgo-lora32-v21 and ESP32 WROOM Dev
GND GND
DIO1 -
DIO2 -
DIO3 -
VCC 3.3V
MISO 19
MOSI 27
SCLK 5
NSS 18
DIO0 26
REST 14
GND - */
#endif
+235 -242
View File
@@ -3,101 +3,107 @@
#include "configuration.h" #include "configuration.h"
#include "display.h" #include "display.h"
void Configuration::check() {
if (reload) {
show_display("------- UPDATE ------", "config is old", "device will update", "and then reboot", 1000);
writeFile();
ESP.restart();
}
}
void Configuration::writeFile() { void Configuration::writeFile() {
Serial.println("Saving config.."); Serial.println("Saving config..");
StaticJsonDocument<2048> data; StaticJsonDocument<2560> data;
File configFile = SPIFFS.open("/igate_conf.json", "w"); File configFile = SPIFFS.open("/igate_conf.json", "w");
if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
for (int i = 0; i < wifiAPs.size(); i++) { for (int i = 0; i < wifiAPs.size(); i++) {
data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid; data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
data["wifi"]["AP"][i]["password"] = wifiAPs[i].password; data["wifi"]["AP"][i]["password"] = wifiAPs[i].password;
// data["wifi"]["AP"][i]["latitude"] = wifiAPs[i].latitude;
// data["wifi"]["AP"][i]["longitude"] = wifiAPs[i].longitude;
} }
} }
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password; data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
data["wifi"]["autoAP"]["powerOff"] = wifiAutoAP.powerOff; data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
data["callsign"] = callsign; data["callsign"] = callsign;
// data["stationMode"] = stationMode; // only check for config version
// data["iGateComment"] = iGateComment;
// data["other"]["beaconInterval"] = beaconInterval; data["aprs_is"]["active"] = aprs_is.active;
// data["other"]["igateSendsLoRaBeacons"] = igateSendsLoRaBeacons; data["aprs_is"]["passcode"] = aprs_is.passcode;
// data["other"]["igateRepeatsLoRaPackets"] = igateRepeatsLoRaPackets; data["aprs_is"]["server"] = aprs_is.server;
data["other"]["rememberStationTime"] = rememberStationTime; data["aprs_is"]["port"] = aprs_is.port;
data["other"]["sendBatteryVoltage"] = sendBatteryVoltage; data["aprs_is"]["filter"] = aprs_is.filter;
data["other"]["externalVoltageMeasurement"] = externalVoltageMeasurement; data["aprs_is"]["messagesToRF"] = aprs_is.messagesToRF;
data["other"]["externalVoltagePin"] = externalVoltagePin; data["aprs_is"]["objectsToRF"] = aprs_is.objectsToRF;
data["digi"]["mode"] = digi.mode; data["beacon"]["comment"] = beacon.comment;
// data["digi"]["comment"] = digi.comment; data["beacon"]["interval"] = beacon.interval;
// data["digi"]["latitude"] = digi.latitude; data["beacon"]["latitude"] = beacon.latitude;
// data["digi"]["longitude"] = digi.longitude; data["beacon"]["longitude"] = beacon.longitude;
data["beacon"]["overlay"] = beacon.overlay;
data["beacon"]["symbol"] = beacon.symbol;
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
data["beacon"]["path"] = beacon.path;
data["tnc"]["enableServer"] = tnc.enableServer; data["beacon"]["gpsActive"] = beacon.gpsActive;
data["tnc"]["enableSerial"] = tnc.enableSerial; data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
data["aprs_is"]["active"] = aprs_is.active; data["digi"]["mode"] = digi.mode;
data["aprs_is"]["passcode"] = aprs_is.passcode; data["digi"]["ecoMode"] = digi.ecoMode;
data["aprs_is"]["server"] = aprs_is.server;
data["aprs_is"]["port"] = aprs_is.port;
data["aprs_is"]["filter"] = aprs_is.filter;
data["aprs_is"]["toRF"] = aprs_is.toRF;
data["beacon"]["comment"] = beacon.comment; data["lora"]["rxFreq"] = loramodule.rxFreq;
// data["beacon"]["igateRepeatsLoRaPackets"] = beacon.igateRepeatsLoRaPackets; data["lora"]["txFreq"] = loramodule.txFreq;
// data["beacon"]["igateSendsLoRaBeacons"] = beacon.igateSendsLoRaBeacons; data["lora"]["spreadingFactor"] = loramodule.spreadingFactor;
data["beacon"]["interval"] = beacon.interval; data["lora"]["signalBandwidth"] = loramodule.signalBandwidth;
data["beacon"]["latitude"] = beacon.latitude; data["lora"]["codingRate4"] = loramodule.codingRate4;
data["beacon"]["longitude"] = beacon.longitude; data["lora"]["power"] = loramodule.power;
data["beacon"]["overlay"] = beacon.overlay; data["lora"]["txActive"] = loramodule.txActive;
data["beacon"]["symbol"] = beacon.symbol; data["lora"]["rxActive"] = loramodule.rxActive;
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
data["beacon"]["path"] = beacon.path;
// data["lora"]["iGateFreq"] = loramodule.iGateFreq; data["display"]["alwaysOn"] = display.alwaysOn;
// data["lora"]["digirepeaterTxFreq"] = loramodule.digirepeaterTxFreq; data["display"]["timeout"] = display.timeout;
// data["lora"]["digirepeaterRxFreq"] = loramodule.digirepeaterRxFreq; data["display"]["turn180"] = display.turn180;
data["lora"]["rxFreq"] = loramodule.rxFreq;
data["lora"]["txFreq"] = loramodule.txFreq;
data["lora"]["spreadingFactor"] = loramodule.spreadingFactor;
data["lora"]["signalBandwidth"] = loramodule.signalBandwidth;
data["lora"]["codingRate4"] = loramodule.codingRate4;
data["lora"]["power"] = loramodule.power;
data["lora"]["txActive"] = loramodule.txActive;
data["lora"]["rxActive"] = loramodule.rxActive;
data["display"]["alwaysOn"] = display.alwaysOn; data["battery"]["sendInternalVoltage"] = battery.sendInternalVoltage;
data["display"]["timeout"] = display.timeout; data["battery"]["monitorInternalVoltage"] = battery.monitorInternalVoltage;
data["display"]["turn180"] = display.turn180; data["battery"]["internalSleepVoltage"] = battery.internalSleepVoltage;
data["syslog"]["active"] = syslog.active; data["battery"]["sendExternalVoltage"] = battery.sendExternalVoltage;
data["syslog"]["server"] = syslog.server; data["battery"]["externalVoltagePin"] = battery.externalVoltagePin;
data["syslog"]["port"] = syslog.port; data["battery"]["monitorExternalVoltage"] = battery.monitorExternalVoltage;
data["battery"]["externalSleepVoltage"] = battery.externalSleepVoltage;
data["battery"]["voltageDividerR1"] = battery.voltageDividerR1;
data["battery"]["voltageDividerR2"] = battery.voltageDividerR2;
data["bme"]["active"] = bme.active; data["battery"]["sendVoltageAsTelemetry"] = battery.sendVoltageAsTelemetry;
data["wxsensor"]["active"] = wxsensor.active;
data["wxsensor"]["heightCorrection"] = wxsensor.heightCorrection;
data["wxsensor"]["temperatureCorrection"] = wxsensor.temperatureCorrection;
data["ota"]["username"] = ota.username; data["syslog"]["active"] = syslog.active;
data["ota"]["password"] = ota.password; data["syslog"]["server"] = syslog.server;
data["syslog"]["port"] = syslog.port;
data["other"]["lowPowerMode"] = lowPowerMode; data["tnc"]["enableServer"] = tnc.enableServer;
data["other"]["lowVoltageCutOff"] = lowVoltageCutOff; data["tnc"]["enableSerial"] = tnc.enableSerial;
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
data["other"]["rebootMode"] = rebootMode;
data["other"]["rebootModeTime"] = rebootModeTime;
data["ota"]["username"] = ota.username;
data["ota"]["password"] = ota.password;
data["other"]["rememberStationTime"] = rememberStationTime;
data["other"]["backupDigiMode"] = backupDigiMode;
data["other"]["lowPowerMode"] = lowPowerMode;
data["other"]["lowVoltageCutOff"] = lowVoltageCutOff;
data["personalNote"] = personalNote;
data["webadmin"]["active"] = webadmin.active;
data["webadmin"]["username"] = webadmin.username;
data["webadmin"]["password"] = webadmin.password;
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
serializeJson(data, configFile); serializeJson(data, configFile);
@@ -112,7 +118,7 @@ bool Configuration::readFile() {
File configFile = SPIFFS.open("/igate_conf.json", "r"); File configFile = SPIFFS.open("/igate_conf.json", "r");
if (configFile) { if (configFile) {
StaticJsonDocument<2048> data; StaticJsonDocument<2560> data;
DeserializationError error = deserializeJson(data, configFile); DeserializationError error = deserializeJson(data, configFile);
if (error) { if (error) {
@@ -128,120 +134,92 @@ bool Configuration::readFile() {
wifiAPs.push_back(wifiap); wifiAPs.push_back(wifiap);
} }
wifiAutoAP.password = data["wifi"]["autoAP"]["password"].as<String>(); wifiAutoAP.password = data["wifi"]["autoAP"]["password"] | "1234567890";
wifiAutoAP.powerOff = data["wifi"]["autoAP"]["powerOff"].as<int>(); wifiAutoAP.timeout = data["wifi"]["autoAP"]["timeout"] | 10;
callsign = data["callsign"].as<String>(); callsign = data["callsign"] | "NOCALL-10";
rememberStationTime = data["other"]["rememberStationTime"].as<int>(); rememberStationTime = data["other"]["rememberStationTime"] | 30;
sendBatteryVoltage = data["other"]["sendBatteryVoltage"].as<bool>();
externalVoltageMeasurement = data["other"]["externalVoltageMeasurement"].as<bool>();
externalVoltagePin = data["other"]["externalVoltagePin"].as<int>();
aprs_is.passcode = data["aprs_is"]["passcode"].as<String>(); beacon.latitude = data["beacon"]["latitude"] | 0.0;
aprs_is.server = data["aprs_is"]["server"].as<String>(); beacon.longitude = data["beacon"]["longitude"] | 0.0;
aprs_is.port = data["aprs_is"]["port"].as<int>(); beacon.comment = data["beacon"]["comment"] | "LoRa APRS";
beacon.interval = data["beacon"]["interval"] | 15;
beacon.overlay = data["beacon"]["overlay"] | "L";
beacon.symbol = data["beacon"]["symbol"] | "a";
beacon.path = data["beacon"]["path"] | "WIDE1-1";
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
loramodule.spreadingFactor = data["lora"]["spreadingFactor"].as<int>(); beacon.gpsActive = data["beacon"]["gpsActive"] | false;
loramodule.signalBandwidth = data["lora"]["signalBandwidth"].as<long>(); beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
loramodule.codingRate4 = data["lora"]["codingRate4"].as<int>();
loramodule.power = data["lora"]["power"].as<int>();
display.alwaysOn = data["display"]["alwaysOn"].as<bool>();
display.timeout = data["display"]["timeout"].as<int>();
display.turn180 = data["display"]["turn180"].as<bool>();
syslog.active = data["syslog"]["active"].as<bool>();
syslog.server = data["syslog"]["server"].as<String>();
syslog.port = data["syslog"]["port"].as<int>();
bme.active = data["bme"]["active"].as<bool>();
ota.username = data["ota"]["username"].as<String>();
ota.password = data["ota"]["password"].as<String>();
tnc.enableServer = data["tnc"]["enableServer"].as<bool>();
tnc.enableSerial = data["tnc"]["enableSerial"].as<bool>();
tnc.acceptOwn = data["tnc"]["acceptOwn"].as<bool>();
lowPowerMode = data["other"]["lowPowerMode"].as<bool>();
lowVoltageCutOff = data["other"]["lowVoltageCutOff"].as<double>();
int stationMode = data["stationMode"].as<int>(); // deprecated but need to specify config version
if (stationMode == 0) {
// Load new settings
beacon.latitude = data["beacon"]["latitude"].as<double>();
beacon.longitude = data["beacon"]["longitude"].as<double>();
beacon.comment = data["beacon"]["comment"].as<String>();
beacon.overlay = data["beacon"]["overlay"].as<String>();
beacon.symbol = data["beacon"]["symbol"].as<String>();
beacon.interval = data["beacon"]["interval"].as<int>();
// beacon.igateSendsLoRaBeacons = data["beacon"]["igateSendsLoRaBeacons"].as<bool>();
// beacon.igateRepeatsLoRaPackets = data["beacon"]["igateRepeatsLoRaPackets"].as<bool>();
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"].as<bool>();
beacon.sendViaRF = data["beacon"]["sendViaRF"].as<bool>();
beacon.path = data["beacon"]["path"].as<String>();
digi.mode = data["digi"]["mode"].as<int>();
aprs_is.active = data["aprs_is"]["active"].as<bool>();
aprs_is.filter = data["aprs_is"]["filter"].as<String>();
aprs_is.toRF = data["aprs_is"]["toRF"].as<bool>();
loramodule.txFreq = data["lora"]["txFreq"].as<long>();
loramodule.rxFreq = data["lora"]["rxFreq"].as<long>();
loramodule.txActive = data["lora"]["txActive"].as<bool>();
loramodule.rxActive = data["lora"]["rxActive"].as<bool>();
} else {
// Load old settings and put into new variables not actual config
String iGateComment = data["iGateComment"].as<String>();
int beaconInterval = data["other"]["beaconInterval"].as<int>();
// bool igateSendsLoRaBeacons = data["other"]["igateSendsLoRaBeacons"].as<bool>();
// bool igateRepeatsLoRaPackets = data["other"]["igateRepeatsLoRaPackets"].as<bool>();
long iGateFreq = data["lora"]["iGateFreq"].as<long>();
long digirepeaterTxFreq = data["lora"]["digirepeaterTxFreq"].as<long>();
long digirepeaterRxFreq = data["lora"]["digirepeaterRxFreq"].as<long>();
String digiComment = data["digi"]["comment"].as<String>(); aprs_is.active = data["aprs_is"]["active"] | false;
double digiLatitude = data["digi"]["latitude"].as<double>(); aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV";
double digiLongitude = data["digi"]["longitude"].as<double>(); aprs_is.server = data["aprs_is"]["server"] | "rotate.aprs2.net";
aprs_is.port = data["aprs_is"]["port"] | 14580;
aprs_is.filter = data["aprs_is"]["filter"] | "m/10";
aprs_is.messagesToRF = data["aprs_is"]["messagesToRF"] | false;
aprs_is.objectsToRF = data["aprs_is"]["objectsToRF"] | false;
digi.mode = data["digi"]["mode"] | 0;
digi.ecoMode = data["digi"]["ecoMode"] | false;
beacon.latitude = digiLatitude; loramodule.txFreq = data["lora"]["txFreq"] | 433775000;
beacon.longitude = digiLongitude; loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
beacon.interval = beaconInterval; loramodule.spreadingFactor = data["lora"]["spreadingFactor"] | 12;
// beacon.igateSendsLoRaBeacons = igateSendsLoRaBeacons; loramodule.signalBandwidth = data["lora"]["signalBandwidth"] | 125000;
// beacon.igateRepeatsLoRaPackets = igateRepeatsLoRaPackets; loramodule.codingRate4 = data["lora"]["codingRate4"] | 5;
loramodule.txFreq = digirepeaterTxFreq; loramodule.power = data["lora"]["power"] | 20;
loramodule.rxFreq = digirepeaterRxFreq; loramodule.txActive = data["lora"]["txActive"] | false;
loramodule.rxActive = true; loramodule.rxActive = data["lora"]["rxActive"] | false;
beacon.sendViaAPRSIS = true;
beacon.sendViaRF = false;
switch (stationMode) { display.alwaysOn = data["display"]["alwaysOn"] | true;
case 1: // IGate only display.timeout = data["display"]["timeout"] | 4;
// aprs_is.active = true; // better don't do that automatically display.turn180 = data["display"]["turn180"] | false;
beacon.comment = iGateComment;
loramodule.rxFreq = iGateFreq;
break;
case 5: // Digi + IGate
case 2: // Digi + IGate
// aprs_is.active = true; // better don't do that automatically
// digi.mode = 2; // better don't do that automatically
beacon.comment = digiComment;
loramodule.rxFreq = iGateFreq;
break;
case 3: // Digi
case 4: // Digi
// digi.mode = 2; // better don't do that automatically
beacon.comment = digiComment;
break;
}
reload = true; battery.sendInternalVoltage = data["battery"]["sendInternalVoltage"] | false;
} battery.monitorInternalVoltage = data["battery"]["monitorInternalVoltage"] | false;
battery.internalSleepVoltage = data["battery"]["internalSleepVoltage"] | 2.9;
battery.sendExternalVoltage = data["battery"]["sendExternalVoltage"] | false;
battery.externalVoltagePin = data["battery"]["externalVoltagePin"] | 34;
battery.monitorExternalVoltage = data["battery"]["monitorExternalVoltage"] | false;
battery.externalSleepVoltage = data["battery"]["externalSleepVoltage"] | 10.9;
battery.voltageDividerR1 = data["battery"]["voltageDividerR1"] | 100.0;
battery.voltageDividerR2 = data["battery"]["voltageDividerR2"] | 27.0;
battery.sendVoltageAsTelemetry = data["battery"]["sendVoltageAsTelemetry"] | false;
wxsensor.active = data["wxsensor"]["active"] | false;
wxsensor.heightCorrection = data["wxsensor"]["heightCorrection"] | 0;
wxsensor.temperatureCorrection = data["wxsensor"]["temperatureCorrection"] | 0.0;
syslog.active = data["syslog"]["active"] | false;
syslog.server = data["syslog"]["server"] | "192.168.0.100";
syslog.port = data["syslog"]["port"] | 514;
tnc.enableServer = data["tnc"]["enableServer"] | false;
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
ota.username = data["ota"]["username"] | "";
ota.password = data["ota"]["password"] | "";
webadmin.active = data["webadmin"]["active"] | false;
webadmin.username = data["webadmin"]["username"] | "admin";
webadmin.password = data["webadmin"]["password"] | "";
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0;
lowPowerMode = data["other"]["lowPowerMode"] | false;
lowVoltageCutOff = data["other"]["lowVoltageCutOff"] | 0;
backupDigiMode = data["other"]["backupDigiMode"] | false;
rebootMode = data["other"]["rebootMode"] | false;
rebootModeTime = data["other"]["rebootModeTime"] | 6;
personalNote = data["personalNote"] | "personal note here...";
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
WiFi_AP wifiap; WiFi_AP wifiap;
@@ -260,87 +238,102 @@ bool Configuration::readFile() {
} }
void Configuration::init() { void Configuration::init() {
reload = false;
WiFi_AP wifiap; WiFi_AP wifiap;
wifiap.ssid = ""; wifiap.ssid = "";
wifiap.password = ""; wifiap.password = "";
// wifiap.latitude = 0.0; // deprecated
// wifiap.longitude = 0.0; // deprecated
wifiAPs.push_back(wifiap); wifiAPs.push_back(wifiap);
wifiAutoAP.password = "1234567890"; wifiAutoAP.password = "1234567890";
wifiAutoAP.powerOff = 15; wifiAutoAP.timeout = 10;
callsign = "N0CALL"; callsign = "N0CALL-10";
// stationMode = 1; // deprecated
// iGateComment = "LoRa_APRS_iGate Development"; // deprecated
beacon.comment = "LoRa APRS"; // new beacon.comment = "LoRa APRS";
beacon.latitude = 0.0; // new beacon.latitude = 0.0;
beacon.longitude = 0.0; // new beacon.longitude = 0.0;
beacon.interval = 15; // new beacon.interval = 15;
// beacon.igateRepeatsLoRaPackets = false; // new beacon.overlay = "L";
// beacon.igateSendsLoRaBeacons = false; // new beacon.symbol = "a";
beacon.overlay = "L"; // new beacon.sendViaAPRSIS = true;
beacon.symbol = "#"; // new beacon.sendViaRF = false;
beacon.sendViaAPRSIS = true; // new beacon.path = "WIDE1-1";
beacon.sendViaRF = false; // new
beacon.path = "WIDE1-1"; // new beacon.gpsActive = false;
beacon.gpsAmbiguity = false;
digi.mode = 0; // new digi.mode = 0;
// digi.comment = "LoRa_APRS_iGate Development"; // deprecated digi.ecoMode = false;
// digi.latitude = 0.0; // deprecated
// digi.longitude = 0.0; // deprecated
tnc.enableServer = false; tnc.enableServer = false;
tnc.enableSerial = false; tnc.enableSerial = false;
tnc.acceptOwn = false; tnc.acceptOwn = false;
aprs_is.active = false; // new aprs_is.active = false;
aprs_is.passcode = "XYZVW"; aprs_is.passcode = "XYZVW";
aprs_is.server = "rotate.aprs2.net"; aprs_is.server = "rotate.aprs2.net";
aprs_is.port = 14580; aprs_is.port = 14580;
aprs_is.filter = "m/10"; // new aprs_is.filter = "m/10";
aprs_is.toRF = false; // new aprs_is.messagesToRF = false;
aprs_is.objectsToRF = false;
// loramodule.iGateFreq = 433775000; // deprecated loramodule.txFreq = 433775000;
// loramodule.digirepeaterTxFreq = 433775000; // deprecated loramodule.rxFreq = 433775000;
// loramodule.digirepeaterRxFreq = 433900000; // deprecated loramodule.spreadingFactor = 12;
loramodule.txFreq = 433775000; // new loramodule.signalBandwidth = 125000;
loramodule.rxFreq = 433775000; // new loramodule.codingRate4 = 5;
loramodule.spreadingFactor = 12; loramodule.power = 20;
loramodule.signalBandwidth = 125000; loramodule.txActive = false;
loramodule.codingRate4 = 5; loramodule.rxActive = true;
loramodule.power = 20;
loramodule.txActive = false; // new
loramodule.rxActive = true; // new
display.alwaysOn = true; display.alwaysOn = true;
display.timeout = 4; display.timeout = 4;
display.turn180 = false; display.turn180 = false;
syslog.active = false; syslog.active = false;
syslog.server = "192.168.0.100"; syslog.server = "192.168.0.100";
syslog.port = 514; syslog.port = 514;
bme.active = false; wxsensor.active = false;
wxsensor.heightCorrection = 0;
wxsensor.temperatureCorrection = 0.0;
ota.username = ""; ota.username = "";
ota.password = ""; ota.password = "";
// beaconInterval = 15; // deprecated rememberStationTime = 30;
// igateSendsLoRaBeacons = false; // deprecated
// igateRepeatsLoRaPackets = false; // deprecated
rememberStationTime = 30;
sendBatteryVoltage = false;
externalVoltageMeasurement = false;
externalVoltagePin = 34;
lowPowerMode = false; battery.sendInternalVoltage = false;
lowVoltageCutOff = 0; battery.monitorInternalVoltage = false;
battery.internalSleepVoltage = 2.9;
Serial.println("todo escrito"); battery.sendExternalVoltage = false;
battery.externalVoltagePin = 34;
battery.monitorExternalVoltage = false;
battery.externalSleepVoltage = 10.9;
battery.voltageDividerR1 = 100.0;
battery.voltageDividerR2 = 27.0;
battery.sendVoltageAsTelemetry = true;
lowPowerMode = false;
lowVoltageCutOff = 0;
backupDigiMode = false;
rebootMode = false;
rebootModeTime = 0;
personalNote = "";
webadmin.active = false;
webadmin.username = "admin";
webadmin.password = "";
ntp.gmtCorrection = 0;
Serial.println("All is Written!");
} }
Configuration::Configuration() { Configuration::Configuration() {
+83 -63
View File
@@ -9,57 +9,53 @@ class WiFi_AP {
public: public:
String ssid; String ssid;
String password; String password;
// double latitude; // deprecated
// double longitude; // deprecated
}; };
class WiFi_Auto_AP { class WiFi_Auto_AP {
public: public:
String password; String password;
int powerOff; int timeout;
}; };
class Beacon { class BEACON {
public: public:
double latitude; // new double latitude;
double longitude; // new double longitude;
String comment; // new String comment;
String overlay; // new int interval;
String symbol; // new String overlay;
int interval; // new String symbol;
bool sendViaRF; // new String path;
bool sendViaAPRSIS; // new bool sendViaRF;
String path; // new bool sendViaAPRSIS;
}; bool gpsActive;
bool gpsAmbiguity;
class DIGI {
public:
int mode; // new
// String comment; // deprecated
// double latitude; // deprecated
// double longitude; // deprecated
}; };
class APRS_IS { class APRS_IS {
public: public:
bool active; // new bool active;
String passcode; String passcode;
String server; String server;
int port; int port;
// int reportingDistance; // deprecated String filter;
String filter; // new bool messagesToRF;
bool toRF; // new bool objectsToRF;
}; };
class DIGI {
public:
int mode;
bool ecoMode;
};
class LoraModule { class LoraModule {
public: public:
// long iGateFreq; // deprecated long txFreq;
// long digirepeaterTxFreq; // deprecated long rxFreq;
// long digirepeaterRxFreq; // deprecated bool txActive;
long txFreq; // new bool rxActive;
long rxFreq; // new
bool txActive; // new
bool rxActive; // new
int spreadingFactor; int spreadingFactor;
long signalBandwidth; long signalBandwidth;
int codingRate4; int codingRate4;
@@ -73,11 +69,25 @@ public:
bool turn180; bool turn180;
}; };
class TNC { class BATTERY {
public: public:
bool enableServer; bool sendInternalVoltage;
bool enableSerial; bool monitorInternalVoltage;
bool acceptOwn; float internalSleepVoltage;
bool sendExternalVoltage;
int externalVoltagePin;
bool monitorExternalVoltage;
float externalSleepVoltage;
float voltageDividerR1;
float voltageDividerR2;
bool sendVoltageAsTelemetry;
};
class WXSENSOR {
public:
bool active;
int heightCorrection;
float temperatureCorrection;
}; };
class SYSLOG { class SYSLOG {
@@ -87,9 +97,11 @@ public:
int port; int port;
}; };
class BME { class TNC {
public: public:
bool active; bool enableServer;
bool enableSerial;
bool acceptOwn;
}; };
class OTA { class OTA {
@@ -98,39 +110,47 @@ public:
String password; String password;
}; };
class WEBADMIN {
public:
bool active;
String username;
String password;
};
class NTP {
public:
int gmtCorrection;
};
class Configuration { class Configuration {
public: public:
bool reload; String callsign;
String callsign; int rememberStationTime;
// int stationMode; // deprecated bool lowPowerMode;
// String iGateComment; // deprecated double lowVoltageCutOff;
// int beaconInterval; // deprecated bool backupDigiMode;
// bool igateSendsLoRaBeacons; // deprecated bool rebootMode;
// bool igateRepeatsLoRaPackets; // deprecated int rebootModeTime;
int rememberStationTime; String personalNote;
bool sendBatteryVoltage; std::vector<WiFi_AP> wifiAPs;
bool externalVoltageMeasurement; WiFi_Auto_AP wifiAutoAP;
int externalVoltagePin; BEACON beacon;
bool lowPowerMode; APRS_IS aprs_is;
double lowVoltageCutOff; DIGI digi;
std::vector<WiFi_AP> wifiAPs; LoraModule loramodule;
WiFi_Auto_AP wifiAutoAP; Display display;
Beacon beacon; // new BATTERY battery;
DIGI digi; WXSENSOR wxsensor;
TNC tnc; // new SYSLOG syslog;
APRS_IS aprs_is; TNC tnc;
LoraModule loramodule; OTA ota;
Display display; WEBADMIN webadmin;
SYSLOG syslog; NTP ntp;
BME bme;
OTA ota;
void init(); void init();
void writeFile(); void writeFile();
void check();
Configuration(); Configuration();
private: private:
+127 -45
View File
@@ -3,9 +3,9 @@
#include "station_utils.h" #include "station_utils.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "query_utils.h" #include "query_utils.h"
#include "lora_utils.h"
#include "digi_utils.h" #include "digi_utils.h"
#include "wifi_utils.h" #include "wifi_utils.h"
#include "lora_utils.h"
#include "gps_utils.h" #include "gps_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
@@ -20,65 +20,143 @@ extern String fourthLine;
extern String fifthLine; extern String fifthLine;
extern String sixthLine; extern String sixthLine;
extern String seventhLine; extern String seventhLine;
extern bool backUpDigiMode;
namespace DIGI_Utils { namespace DIGI_Utils {
String generateDigiRepeatedPacket(String packet, String callsign) { String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq) {
String sender, temp0, tocall, path; if (!crossFreq) {
sender = packet.substring(0, packet.indexOf(">")); String packetToRepeat = packet.substring(0, packet.indexOf(",") + 1);
temp0 = packet.substring(packet.indexOf(">") + 1, packet.indexOf(":")); String tempPath = path;
if (temp0.indexOf(",") > 2) {
tocall = temp0.substring(0, temp0.indexOf(",")); if (path.indexOf("WIDE1-1") != -1 && (Config.digi.mode == 2 || Config.digi.mode == 3)) {
path = temp0.substring(temp0.indexOf(",") + 1, temp0.indexOf(":")); tempPath.replace("WIDE1-1", Config.callsign + "*");
if (path.indexOf("WIDE1-") >= 0) { } else if (path.indexOf("WIDE2-") != -1 && Config.digi.mode == 3) {
String hop = path.substring(path.indexOf("WIDE1-") + 6, path.indexOf("WIDE1-") + 7); if (path.indexOf(",WIDE1*") != -1) {
if (hop.toInt() >= 1 && hop.toInt() <= 7) { tempPath.remove(path.indexOf(",WIDE1*"), 7);
if (hop.toInt() == 1) {
path.replace("WIDE1-1", callsign + "*");
}
else {
path.replace("WIDE1-" + hop, callsign + "*,WIDE1-" + String(hop.toInt() - 1));
}
String repeatedPacket = sender + ">" + tocall + "," + path + packet.substring(packet.indexOf(":"));
return repeatedPacket;
} }
else { if (path.indexOf("*") != -1) {
tempPath.remove(path.indexOf("*"), 1);
}
if (path.indexOf("WIDE2-1") != -1) {
tempPath.replace("WIDE2-1", Config.callsign + "*");
} else if (path.indexOf("WIDE2-2") != -1) {
tempPath.replace("WIDE2-2", Config.callsign + "*,WIDE2-1");
} else {
return ""; return "";
} }
} }
else { packetToRepeat += tempPath;
if (thirdParty) {
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(":}")));
} else {
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(":")));
}
return packetToRepeat;
} else { // CrossFreq Digirepeater
String suffix = thirdParty ? ":}" : ":";
String packetToRepeat = packet.substring(0, packet.indexOf(suffix));
String terms[] = {",WIDE1*", ",WIDE2*", "*"};
for (String term : terms) {
int index = packetToRepeat.indexOf(term);
if (index != -1) {
packetToRepeat.remove(index, term.length());
}
}
packetToRepeat += ",";
packetToRepeat += Config.callsign;
packetToRepeat += "*";
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(suffix)));
return packetToRepeat;
}
}
String generateDigiRepeatedPacket(const String& packet, bool thirdParty){
String temp;
if (thirdParty) { // only header is used
const String& header = packet.substring(0, packet.indexOf(":}"));
temp = header.substring(header.indexOf(">") + 1);
} else {
temp = packet.substring(packet.indexOf(">") + 1, packet.indexOf(":"));
}
if (temp.indexOf(",") > 2) { // checks for path
const String& path = temp.substring(temp.indexOf(",") + 1); // after tocall
if (Config.digi.mode == 2 || backUpDigiMode) {
if (path.indexOf("WIDE1-1") != - 1) {
return buildPacket(path, packet, thirdParty, false);
} else if (path.indexOf("WIDE1-1") == -1 && (abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000)) { // CrossFreq Digi
return buildPacket(path, packet, thirdParty, true);
} else {
return "";
}
} else if (Config.digi.mode == 3) {
if (path.indexOf("WIDE1-1") != -1 || path.indexOf("WIDE2-") != -1) {
int wide1Index = path.indexOf("WIDE1-1");
int wide2Index = path.indexOf("WIDE2-");
// WIDE1-1 && WIDE2-n / only WIDE1-1 / only WIDE2-n
if ((wide1Index != -1 && wide2Index != -1 && wide1Index < wide2Index) || (wide1Index != -1 && wide2Index == -1) || (wide1Index == -1 && wide2Index != -1)) {
return buildPacket(path, packet, thirdParty, false);
}
return "";
} else if (path.indexOf("WIDE1-1") == -1 && path.indexOf("WIDE2-") == -1 && (abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000)) { // CrossFreq Digi
return buildPacket(path, packet, thirdParty, true);
} else {
return "";
}
} else {
return ""; return "";
} }
} } else if (temp.indexOf(",") == -1 && (Config.digi.mode == 2 || backUpDigiMode || Config.digi.mode == 3) && (abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000)) {
else { return buildPacket("", packet, thirdParty, true);
} else {
return ""; return "";
} }
} }
void processPacket(String packet) { void processLoRaPacket(const String& packet) {
bool queryMessage = false;
String loraPacket, Sender, AddresseeAndMessage, Addressee;
if (packet != "") { if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) { if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) {
Sender = packet.substring(3, packet.indexOf(">")); bool thirdPartyPacket = false;
if (Sender != Config.callsign) { String temp, Sender;
STATION_Utils::updateLastHeard(Sender); int firstColonIndex = packet.indexOf(":");
// STATION_Utils::updatePacketBuffer(packet); if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
Utils::typeOfPacket(packet.substring(3), "Digi"); thirdPartyPacket = true;
AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); temp = packet.substring(packet.indexOf(":}") + 2);
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); Sender = temp.substring(0, temp.indexOf(">"));
Addressee.trim(); } else {
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me! temp = packet.substring(3);
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage); Sender = packet.substring(3, packet.indexOf(">"));
}
if (Sender != Config.callsign) { // Avoid listening to own packets
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
return;
} }
if (!queryMessage && packet.indexOf("WIDE1-") > 10 && Config.digi.mode == 2) { // If should repeat packet (WIDE1 Digi) if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
loraPacket = generateDigiRepeatedPacket(packet.substring(3), Config.callsign); STATION_Utils::updateLastHeard(Sender);
if (loraPacket != "") { Utils::typeOfPacket(temp, 2); // Digi
delay(500); bool queryMessage = false;
LoRa_Utils::sendNewPacket("APRS", loraPacket); if (temp.indexOf("::") > 10) { // it's a message
display_toggle(true); String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
lastScreenOn = millis(); String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
}
if (!queryMessage) {
String loraPacket = generateDigiRepeatedPacket(packet.substring(3), thirdPartyPacket);
if (loraPacket != "") {
if (Config.lowPowerMode) {
LoRa_Utils::sendNewPacket(loraPacket);
} else {
STATION_Utils::addToOutputPacketBuffer(loraPacket);
}
displayToggle(true);
lastScreenOn = millis();
}
} }
} }
} }
@@ -86,8 +164,12 @@ namespace DIGI_Utils {
} }
} }
void loop(String packet) { void checkEcoMode() {
processPacket(packet); if (Config.digi.ecoMode) {
Config.display.alwaysOn = false;
Config.display.timeout = 0;
setCpuFrequencyMhz(10);
}
} }
} }
+4 -3
View File
@@ -6,9 +6,10 @@
namespace DIGI_Utils { namespace DIGI_Utils {
String generateDigiRepeatedPacket(String packet, String callsign); String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq);
void processPacket(String packet); String generateDigiRepeatedPacket(const String& packet, bool thirdParty);
void loop(String packet); void processLoRaPacket(const String& packet);
void checkEcoMode();
} }
+198 -165
View File
@@ -1,185 +1,218 @@
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h> #include <Wire.h>
#include "configuration.h" #include "configuration.h"
#include "pins_config.h" #include "boards_pinout.h"
#include "display.h" #include "display.h"
#ifdef HAS_DISPLAY
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);
#endif
#ifdef HAS_DISPLAY
#ifdef HAS_TFT
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#ifdef HELTEC_WIRELESS_TRACKER
#define bigSizeFont 2.5
#define smallSizeFont 1.5
#define lineSpacing 12
#endif
#else
#if HAS_EPAPER
//
#else
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#if defined(HELTEC_V3) || defined(HELTEC_WS)
#define OLED_DISPLAY_HAS_RST_PIN
#endif
#ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#endif
#endif
#endif
#endif
extern Configuration Config; extern Configuration Config;
void setup_display() { String oldHeader, oldFirstLine, oldSecondLine, oldThirdLine, oldFourthLine, oldFifthLine, oldSixthLine;
#ifdef HAS_DISPLAY
Wire.begin(OLED_SDA, OLED_SCL);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { void cleanTFT() {
Serial.println(F("SSD1306 allocation failed")); #ifdef HAS_TFT
for(;;); // Don't proceed, loop forever tft.fillScreen(TFT_BLACK);
}
if (Config.display.turn180) {
display.setRotation(2);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(1000);
#endif #endif
} }
void display_toggle(bool toggle) { void displaySetup() {
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
if (toggle) { delay(500);
display.ssd1306_command(SSD1306_DISPLAYON); #ifdef HAS_TFT
tft.init();
tft.begin();
if (Config.display.turn180) {
tft.setRotation(3);
} else {
tft.setRotation(1);
}
tft.setTextFont(0);
tft.fillScreen(TFT_BLACK);
#else
#if HAS_EPAPER
//
#else
#ifdef OLED_DISPLAY_HAS_RST_PIN
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);
#endif
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
if (Config.display.turn180) {
display.setRotation(2);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
#endif
#endif
delay(1000);
#endif
}
void displayToggle(bool toggle) {
#ifdef HAS_DISPLAY
if (toggle) {
#ifdef HAS_TFT
digitalWrite(TFT_BL, HIGH);
#else
#if HAS_EPAPER
// ... to be continued
#else
display.ssd1306_command(SSD1306_DISPLAYON);
#endif
#endif
} else {
#ifdef HAS_TFT
digitalWrite(TFT_BL, LOW);
#else
#if HAS_EPAPER
// ... to be continued
#else
display.ssd1306_command(SSD1306_DISPLAYOFF);
#endif
#endif
}
#endif
}
bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3) {
if (oldHeader != header || oldFirstLine != line1 || oldSecondLine != line2 || oldThirdLine != line3) {
oldHeader = header;
oldFirstLine = line1;
oldSecondLine = line2;
oldThirdLine = line3;
return true;
} else { } else {
display.ssd1306_command(SSD1306_DISPLAYOFF); return false;
} }
}
bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6) {
if (oldHeader != header || oldFirstLine != line1 || oldSecondLine != line2 || oldThirdLine != line3 || oldFourthLine != line4 || oldFifthLine != line5 || oldSixthLine != line6) {
oldHeader = header;
oldFirstLine = line1;
oldSecondLine = line2;
oldThirdLine = line3;
oldFourthLine = line4;
oldFifthLine = line5;
oldSixthLine = line6;
return true;
} else {
return false;
}
}
void displayShow(const String& header, const String& line1, const String& line2, const String& line3, int wait) {
#ifdef HAS_DISPLAY
const String* const lines[] = {&line1, &line2, &line3};
#ifdef HAS_TFT
if (shouldCleanTFT(header, line1, line2, line3)) {
cleanTFT();
}
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.setTextSize(bigSizeFont);
tft.setCursor(0, 0);
tft.print(header);
tft.setTextSize(smallSizeFont);
for (int i = 0; i < 3; i++) {
tft.setCursor(0, ((lineSpacing * (2 + i)) - 2));
tft.print(*lines[i]);
}
#else
#ifdef HAS_EPAPER
// ... to be continued
#else
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println(header);
for (int i = 0; i < 3; i++) {
display.setCursor(0, 8 + (8 * i));
display.println(*lines[i]);
}
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
#endif
#endif
delay(wait);
#endif #endif
} }
void show_display(String line1, int wait) { void displayShow(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6, int wait) {
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
display.clearDisplay(); const String* const lines[] = {&line1, &line2, &line3, &line4, &line5, &line6};
display.setTextColor(WHITE); #ifdef HAS_TFT
display.setTextSize(1); if (shouldCleanTFT(header, line1, line2, line3, line4, line5, line6)) {
display.setCursor(0, 0); cleanTFT();
display.println(line1); }
display.ssd1306_command(SSD1306_SETCONTRAST); tft.setTextColor(TFT_WHITE,TFT_BLACK);
display.ssd1306_command(1); tft.setTextSize(bigSizeFont);
display.display(); tft.setCursor(0, 0);
delay(wait); tft.print(header);
#endif tft.setTextSize(smallSizeFont);
} for (int i = 0; i < 6; i++) {
tft.setCursor(0, ((lineSpacing * (2 + i)) - 2));
void show_display(String line1, String line2, int wait) { tft.print(*lines[i]);
#ifdef HAS_DISPLAY }
display.clearDisplay(); #else
display.setTextColor(WHITE); #ifdef HAS_EPAPER
display.setTextSize(1); // ... to be continued
display.setCursor(0, 0); #else
display.println(line1); display.clearDisplay();
display.setCursor(0, 8); display.setTextColor(WHITE);
display.println(line2); display.setTextSize(2);
display.ssd1306_command(SSD1306_SETCONTRAST); display.setCursor(0, 0);
display.ssd1306_command(1); display.println(header);
display.display(); display.setTextSize(1);
delay(wait); for (int i = 0; i < 6; i++) {
#endif display.setCursor(0, 16 + (8 * i));
} display.println(*lines[i]);
}
void show_display(String line1, String line2, String line3, int wait) { display.ssd1306_command(SSD1306_SETCONTRAST);
#ifdef HAS_DISPLAY display.ssd1306_command(1);
display.clearDisplay(); display.display();
display.setTextColor(WHITE); #endif
display.setTextSize(1); #endif
display.setCursor(0, 0); delay(wait);
display.println(line1);
display.setCursor(0, 8);
display.println(line2);
display.setCursor(0, 16);
display.println(line3);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
#endif
}
void show_display(String line1, String line2, String line3, String line4, int wait) {
#ifdef HAS_DISPLAY
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println(line1);
display.setCursor(0, 8);
display.println(line2);
display.setCursor(0, 16);
display.println(line3);
display.setCursor(0, 24);
display.println(line4);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
#endif
}
void show_display(String line1, String line2, String line3, String line4, String line5, int wait) {
#ifdef HAS_DISPLAY
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println(line1);
display.setCursor(0, 8);
display.println(line2);
display.setCursor(0, 16);
display.println(line3);
display.setCursor(0, 24);
display.println(line4);
display.setCursor(0, 32);
display.println(line5);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
#endif
}
void show_display(String line1, String line2, String line3, String line4, String line5, String line6, int wait) {
#ifdef HAS_DISPLAY
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println(line1);
display.setCursor(0, 8);
display.println(line2);
display.setCursor(0, 16);
display.println(line3);
display.setCursor(0, 24);
display.println(line4);
display.setCursor(0, 32);
display.println(line5);
display.setCursor(0, 40);
display.println(line6);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
#endif
}
void show_display(String line1, String line2, String line3, String line4, String line5, String line6, String line7, int wait) {
#ifdef HAS_DISPLAY
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(line1);
display.setTextSize(1);
display.setCursor(0, 16);
display.println(line2);
display.setCursor(0, 24);
display.println(line3);
display.setCursor(0, 32);
display.println(line4);
display.setCursor(0, 40);
display.println(line5);
display.setCursor(0, 48);
display.println(line6);
display.setCursor(0, 56);
display.println(line7);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
#endif #endif
} }
+7 -11
View File
@@ -3,20 +3,16 @@
#include <Arduino.h> #include <Arduino.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
void cleanTFT();
void displaySetup();
void displayToggle(bool toggle);
void setup_display(); bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3);
void display_toggle(bool toggle); bool shouldCleanTFT(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6);
void show_display(String line1, int wait = 0); void displayShow(const String& header, const String& line1, const String& line2, const String& line3, int wait = 0);
void show_display(String line1, String line2, int wait = 0); void displayShow(const String& header, const String& line1, const String& line2, const String& line3, const String& line4, const String& line5, const String& line6, int wait = 0);
void show_display(String line1, String line2, String line3, int wait = 0);
void show_display(String line1, String line2, String line3, String line4, int wait = 0);
void show_display(String line1, String line2, String line3, String line4, String line5, int wait = 0);
void show_display(String line1, String line2, String line3, String line4, String line5, String line6, int wait = 0);
void show_display(String line1, String line2, String line3, String line4, String line5, String line6, String line7, int wait = 0);
#endif #endif
+130 -43
View File
@@ -1,15 +1,30 @@
#include <TinyGPS++.h> #include <TinyGPS++.h>
#include <WiFi.h> #include <WiFi.h>
#include "configuration.h" #include "configuration.h"
#include "boards_pinout.h"
#include "gps_utils.h" #include "gps_utils.h"
#include "display.h"
#include "utils.h"
extern Configuration Config; #ifdef GPS_BAUDRATE
extern WiFiClient espClient; #define GPS_BAUD GPS_BAUDRATE
String distance; #else
#define GPS_BAUD 9600
#endif
extern Configuration Config;
extern WiFiClient espClient;
extern HardwareSerial gpsSerial;
extern TinyGPSPlus gps;
String distance, iGateBeaconPacket, iGateLoRaBeaconPacket;
namespace GPS_Utils { namespace GPS_Utils {
String getiGateLoRaBeaconPacket() {
return iGateLoRaBeaconPacket;
}
char *ax25_base91enc(char *s, uint8_t n, uint32_t v) { char *ax25_base91enc(char *s, uint8_t n, uint32_t v) {
for(s += n, *s = '\0'; n; n--) { for(s += n, *s = '\0'; n; n--) {
*(--s) = v % 91 + 33; *(--s) = v % 91 + 33;
@@ -18,20 +33,32 @@ namespace GPS_Utils {
return(s); return(s);
} }
String encodeGPS(float latitude, float longitude, String overlay, String symbol) { float roundToTwoDecimals(float degrees) {
return round(degrees * 100) / 100;
}
String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol) {
String encodedData = overlay; String encodedData = overlay;
uint32_t aprs_lat, aprs_lon; uint32_t aprs_lat, aprs_lon;
aprs_lat = 900000000 - latitude * 10000000;
float processedLatitude = latitude;
float processedLongitude = longitude;
if (Config.beacon.gpsActive && Config.beacon.gpsAmbiguity) {
processedLatitude = roundToTwoDecimals(latitude);
processedLongitude = roundToTwoDecimals(longitude);
}
aprs_lat = 900000000 - processedLatitude * 10000000;
aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615; aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615;
aprs_lon = 900000000 + longitude * 10000000 / 2; aprs_lon = 900000000 + processedLongitude * 10000000 / 2;
aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615; aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615;
String Ns, Ew, helper; String Ns, Ew, helper;
if(latitude < 0) { Ns = "S"; } else { Ns = "N"; } if(processedLatitude < 0) { Ns = "S"; } else { Ns = "N"; }
if(latitude < 0) { latitude= -latitude; } if(processedLatitude < 0) { processedLatitude = -processedLatitude; }
if(longitude < 0) { Ew = "W"; } else { Ew = "E"; } if(processedLongitude < 0) { Ew = "W"; } else { Ew = "E"; }
if(longitude < 0) { longitude= -longitude; } if(processedLongitude < 0) { processedLongitude = -processedLongitude; }
char helper_base91[] = {"0000\0"}; char helper_base91[] = {"0000\0"};
int i; int i;
@@ -43,31 +70,50 @@ namespace GPS_Utils {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
encodedData += helper_base91[i]; encodedData += helper_base91[i];
} }
encodedData += symbol + " x" + "\x47"; encodedData += symbol;
encodedData += " ";
encodedData += "\x47";
return encodedData; return encodedData;
} }
String generateBeacon() { void generateBeaconFirstPart() {
String beaconPacket = Config.callsign + ">APLRG1," + Config.beacon.path; String beaconPacket = Config.callsign;
beaconPacket += ">APLRG1";
if (Config.aprs_is.active && Config.digi.mode == 0) { // If APRSIS enabled and Digi disabled if (Config.beacon.path.indexOf("WIDE") == 0) {
beaconPacket += ",qAC"; beaconPacket += ",";
} beaconPacket += Config.beacon.path;
return beaconPacket + ":!" + encodeGPS(Config.beacon.latitude, Config.beacon.longitude, Config.beacon.overlay, Config.beacon.symbol);; }
iGateBeaconPacket = beaconPacket;
iGateBeaconPacket += ",qAC:!";
iGateLoRaBeaconPacket = beaconPacket;
iGateLoRaBeaconPacket += ":!";
} }
String generateiGateLoRaBeacon() { void generateBeacons() {
return Config.callsign + ">APLRG1," + Config.beacon.path + ":!" + encodeGPS(Config.beacon.latitude, Config.beacon.longitude, Config.beacon.overlay, Config.beacon.symbol); if (Config.callsign.indexOf("NOCALL-10") != 0 && !Utils::checkValidCallsign(Config.callsign)) {
displayShow("***** ERROR ******", "CALLSIGN = NOT VALID!", "", "Only Rx Mode Active", 3000);
Config.loramodule.txActive = false;
Config.aprs_is.messagesToRF = false;
Config.aprs_is.objectsToRF = false;
Config.beacon.sendViaRF = false;
Config.digi.mode = 0;
Config.backupDigiMode = false;
}
generateBeaconFirstPart();
String encodedGPS = encodeGPS(Config.beacon.latitude, Config.beacon.longitude, Config.beacon.overlay, Config.beacon.symbol);
iGateBeaconPacket += encodedGPS;
iGateLoRaBeaconPacket += encodedGPS;
} }
double calculateDistanceTo(double latitude, double longitude) { double calculateDistanceTo(double latitude, double longitude) {
return TinyGPSPlus::distanceBetween(Config.beacon.latitude,Config.beacon.longitude, latitude, longitude) / 1000.0; return TinyGPSPlus::distanceBetween(Config.beacon.latitude,Config.beacon.longitude, latitude, longitude) / 1000.0;
} }
String decodeEncodedGPS(String packet) { String decodeEncodedGPS(const String& packet) {
String GPSPacket = packet.substring(packet.indexOf(":!")+3); const String& GPSPacket = packet.substring(packet.indexOf(":!")+3);
String encodedLatitude = GPSPacket.substring(0,4); const String& encodedLatitude = GPSPacket.substring(0,4);
String encodedLongtitude = GPSPacket.substring(4,8); const String& encodedLongtitude = GPSPacket.substring(4,8);
const String& comment = GPSPacket.substring(12);
int Y1 = int(encodedLatitude[0]); int Y1 = int(encodedLatitude[0]);
int Y2 = int(encodedLatitude[1]); int Y2 = int(encodedLatitude[1]);
@@ -80,43 +126,69 @@ namespace GPS_Utils {
int X3 = int(encodedLongtitude[2]); int X3 = int(encodedLongtitude[2]);
int X4 = int(encodedLongtitude[3]); int X4 = int(encodedLongtitude[3]);
float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0); float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0);
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1); distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
return String(decodedLatitude,5) + "N / " + String(decodedLongitude,5) + "E / " + distance + "km";
String decodedGPS = String(decodedLatitude,5);
decodedGPS += "N / ";
decodedGPS += String(decodedLongitude,5);
decodedGPS += "E / ";
decodedGPS += distance;
decodedGPS += "km";
if (comment != "") {
decodedGPS += " / ";
decodedGPS += comment;
}
return decodedGPS;
} }
String getReceivedGPS(String packet) { String getReceivedGPS(const String& packet) {
String infoGPS; String infoGPS;
if (packet.indexOf(":!") > 10) { if (packet.indexOf(":!") > 10) {
infoGPS = packet.substring(packet.indexOf(":!")+2); infoGPS = packet.substring(packet.indexOf(":!") + 2);
} else if (packet.indexOf(":=") > 10) { } else if (packet.indexOf(":=") > 10) {
infoGPS = packet.substring(packet.indexOf(":=")+2); infoGPS = packet.substring(packet.indexOf(":=") + 2);
} }
String Latitude = infoGPS.substring(0,8); const String& Latitude = infoGPS.substring(0,8);
String Longitude = infoGPS.substring(9,18); const String& Longitude = infoGPS.substring(9,18);
const String& comment = infoGPS.substring(19);
float convertedLatitude, convertedLongitude; float convertedLatitude, convertedLongitude;
String firstLatPart = Latitude.substring(0,2); const String& firstLatPart = Latitude.substring(0,2);
String secondLatPart = Latitude.substring(2,4); const String& secondLatPart = Latitude.substring(2,4);
String thirdLatPart = Latitude.substring(Latitude.indexOf(".")+1,Latitude.indexOf(".")+3); const String& thirdLatPart = Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3);
String firstLngPart = Longitude.substring(0,3);
String secondLngPart = Longitude.substring(3,5);
String thirdLngPart = Longitude.substring(Longitude.indexOf(".")+1,Longitude.indexOf(".")+3);
convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100)); convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
const String& firstLngPart = Longitude.substring(0,3);
const String& secondLngPart = Longitude.substring(3,5);
const String& thirdLngPart = Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3);
convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100)); convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
String LatSign = String(Latitude[7]); if (String(Latitude[7]) == "S") {
String LngSign = String(Longitude[8]);
if (LatSign == "S") {
convertedLatitude = -convertedLatitude; convertedLatitude = -convertedLatitude;
} }
if (LngSign == "W") { if (String(Longitude[8]) == "W") {
convertedLongitude = -convertedLongitude; convertedLongitude = -convertedLongitude;
} }
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1); distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
return String(convertedLatitude,5) + "N / " + String(convertedLongitude,5) + "E / " + distance + "km";
String decodedGPS = String(convertedLatitude,5);
decodedGPS += "N / ";
decodedGPS += String(convertedLongitude,5);
decodedGPS += "E / ";
decodedGPS += distance;
decodedGPS += "km";
if (comment != "") {
decodedGPS += " / ";
decodedGPS += comment;
}
return decodedGPS;
} }
String getDistance(String packet) { String getDistanceAndComment(const String& packet) {
uint8_t encodedBytePosition = 0; uint8_t encodedBytePosition = 0;
if (packet.indexOf(":!") > 10) { if (packet.indexOf(":!") > 10) {
encodedBytePosition = packet.indexOf(":!") + 14; encodedBytePosition = packet.indexOf(":!") + 14;
@@ -135,4 +207,19 @@ namespace GPS_Utils {
} }
} }
void setup() {
#ifdef HAS_GPS
if (Config.beacon.gpsActive) {
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_TX, GPS_RX);
}
#endif
generateBeacons();
}
void getData() {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
}
} }
+11 -8
View File
@@ -5,15 +5,18 @@
namespace GPS_Utils { namespace GPS_Utils {
String getiGateLoRaBeaconPacket();
char *ax25_base91enc(char *s, uint8_t n, uint32_t v);
String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol);
void generateBeaconFirstPart();
void generateBeacons();
String decodeEncodedGPS(const String& packet);
String getReceivedGPS(const String& packet);
String getDistanceAndComment(const String& packet);
char *ax25_base91enc(char *s, uint8_t n, uint32_t v); void setup();
String encodeGPS(float latitude, float longitude, String overlay, String symbol); void getData();
String generateBeacon();
String generateiGateLoRaBeacon();
double calculateDistanceCourse(double latitude, double longitude);
String decodeEncodedGPS(String packet);
String getReceivedGPS(String packet);
String getDistance(String packet);
} }
+108 -106
View File
@@ -2,29 +2,34 @@
#include <WiFi.h> #include <WiFi.h>
#include "configuration.h" #include "configuration.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "boards_pinout.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "pins_config.h" #include "ntp_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastRxTime;
extern std::vector<ReceivedPacket> receivedPackets; extern std::vector<ReceivedPacket> receivedPackets;
bool transmissionFlag = true; bool operationDone = true;
bool ignorePacket = false; bool transmitFlag = true;
bool operationDone = true;
#ifdef HAS_SX1262 #ifdef HAS_SX1262
SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#endif #endif
#ifdef HAS_SX1268 #ifdef HAS_SX1268
SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#endif #endif
#ifdef HAS_SX1278 #ifdef HAS_SX1278
SX1278 radio = new Module(RADIO_CS_PIN, RADIO_BUSY_PIN, RADIO_RST_PIN); SX1278 radio = new Module(RADIO_CS_PIN, RADIO_BUSY_PIN, RADIO_RST_PIN);
#endif
#ifdef HAS_SX1276
SX1276 radio = new Module(RADIO_CS_PIN, RADIO_BUSY_PIN, RADIO_RST_PIN);
#endif
#if defined(HAS_LLCC68) //LLCC68 supports spreading factor only in range of 5-11!
LLCC68 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#endif #endif
int rssi, freqError; int rssi, freqError;
@@ -39,22 +44,25 @@ namespace LoRa_Utils {
void setup() { void setup() {
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
float freq = (float)Config.loramodule.rxFreq / 1000000; float freq = (float)Config.loramodule.rxFreq / 1000000;
#if defined(RADIO_HAS_XTAL)
radio.XTAL = true;
#endif
int state = radio.begin(freq); int state = radio.begin(freq);
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
Utils::println("Initializing LoRa Module"); Utils::println("Initializing LoRa Module");
} else { } else {
Utils::println("Starting LoRa failed!"); Utils::println("Starting LoRa failed! State: " + String(state));
while (true); while (true);
} }
#ifdef HAS_SX127X #if defined(HAS_SX1262) || defined(HAS_SX1268) || defined(HAS_LLCC68)
radio.setDio0Action(setFlag, RISING); if (!Config.lowPowerMode) {
radio.setDio1Action(setFlag);
} else {
radio.setDIOMapping(1, RADIOLIB_SX126X_IRQ_RX_DONE);
}
#endif #endif
#ifdef HAS_SX126X #if defined(HAS_SX1278) || defined(HAS_SX1276)
if (!Config.lowPowerMode) { radio.setDio0Action(setFlag, RISING);
radio.setDio1Action(setFlag);
} else {
radio.setDIOMapping(1, RADIOLIB_SX126X_IRQ_RX_DONE);
}
#endif #endif
radio.setSpreadingFactor(Config.loramodule.spreadingFactor); radio.setSpreadingFactor(Config.loramodule.spreadingFactor);
float signalBandwidth = Config.loramodule.signalBandwidth/1000; float signalBandwidth = Config.loramodule.signalBandwidth/1000;
@@ -62,20 +70,31 @@ namespace LoRa_Utils {
radio.setCodingRate(Config.loramodule.codingRate4); radio.setCodingRate(Config.loramodule.codingRate4);
radio.setCRC(true); radio.setCRC(true);
#if defined(ESP32_DIY_1W_LoRa) #if defined(RADIO_RXEN) && defined(RADIO_TXEN)
radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN); radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
#endif #endif
#if defined(HAS_SX127X) || ESP32_DIY_1W_LoRa #ifdef HAS_1W_LORA // Ebyte E22 400M30S (SX1268) / 900M30S (SX1262) / Ebyte E220 400M30S (LLCC68)
state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 400M30S as it has Low Noise Amp state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 1W modules as they have Low Noise Amp
#endif radio.setCurrentLimit(140); // to be validated (100 , 120, 140)?
#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262)
state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
#endif #endif
#if defined(HAS_SX1278) || defined(HAS_SX1276)
state = radio.setOutputPower(Config.loramodule.power); // max value 20dB for 400M30S as it has Low Noise Amp
radio.setCurrentLimit(100); // to be validated (80 , 100)?
#endif
#if (defined(HAS_SX1268) || defined(HAS_SX1262)) && !defined(HAS_1W_LORA)
state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
radio.setCurrentLimit(140);
#endif
#if defined(HAS_SX1262) || defined(HAS_SX1268) || defined(HAS_LLCC68)
radio.setRxBoostedGainMode(true);
#endif
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
Utils::println("init : LoRa Module ... done!"); Utils::println("init : LoRa Module ... done!");
} else { } else {
Utils::println("Starting LoRa failed!"); Utils::println("Starting LoRa failed! State: " + String(state));
while (true); while (true);
} }
} }
@@ -92,127 +111,110 @@ namespace LoRa_Utils {
radio.setFrequency(freq); radio.setFrequency(freq);
} }
void sendNewPacket(const String& typeOfMessage, const String& newPacket) { void sendNewPacket(const String& newPacket) {
if (!Config.loramodule.txActive) return; if (!Config.loramodule.txActive) return;
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
changeFreqTx(); changeFreqTx();
} }
#ifdef HAS_INTERNAL_LED #ifdef INTERNAL_LED_PIN
digitalWrite(internalLedPin, HIGH); if (!Config.digi.ecoMode) digitalWrite(INTERNAL_LED_PIN, HIGH);
#endif #endif
int state = radio.transmit("\x3c\xff\x01" + newPacket); int state = radio.transmit("\x3c\xff\x01" + newPacket);
transmissionFlag = true; transmitFlag = true;
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log("Tx", newPacket, 0, 0, 0); SYSLOG_Utils::log(3, newPacket, 0, 0.0, 0); // TX
} }
Utils::print("---> LoRa Packet Tx : "); Utils::print("---> LoRa Packet Tx : ");
Utils::println(newPacket); Utils::println(newPacket);
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Utils::println(F("too long!"));
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Utils::println(F("timeout!"));
} else { } else {
Utils::print(F("failed, code ")); Utils::print(F("failed, code "));
Utils::println(String(state)); Utils::println(String(state));
} }
#ifdef HAS_INTERNAL_LED #ifdef INTERNAL_LED_PIN
digitalWrite(internalLedPin, LOW); if (!Config.digi.ecoMode) digitalWrite(INTERNAL_LED_PIN, LOW);
#endif #endif
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
changeFreqRx(); changeFreqRx();
} }
//ignorePacket = true;
} }
String generatePacket(String aprsisPacket) { /*String packetSanitization(const String& packet) {
String firstPart, messagePart; String sanitizedPacket = packet;
aprsisPacket.trim();
firstPart = aprsisPacket.substring(0, aprsisPacket.indexOf(","));
messagePart = aprsisPacket.substring(aprsisPacket.indexOf("::") + 2);
return firstPart + ",TCPIP,WIDE1-1," + Config.callsign + "::" + messagePart;
}
String packetSanitization(String packet) {
if (packet.indexOf("\0") > 0) { if (packet.indexOf("\0") > 0) {
packet.replace("\0", ""); sanitizedPacket.replace("\0", "");
} }
if (packet.indexOf("\r") > 0) { if (packet.indexOf("\r") > 0) {
packet.replace("\r", ""); sanitizedPacket.replace("\r", "");
} }
if (packet.indexOf("\n") > 0) { if (packet.indexOf("\n") > 0) {
packet.replace("\n", ""); sanitizedPacket.replace("\n", "");
} }
return packet; return sanitizedPacket;
} }*/
void startReceive() { void startReceive() {
radio.startReceive(); radio.startReceive();
} }
String receivePacket() { String receivePacket() {
if(!operationDone && !Config.lowPowerMode) return ""; String packet = "";
if (operationDone || Config.lowPowerMode) {
operationDone = false; operationDone = false;
if (transmitFlag && !Config.lowPowerMode) {
radio.startReceive();
transmitFlag = false;
} else {
int state = radio.readData(packet);
if (state == RADIOLIB_ERR_NONE) {
if (packet != "") {
rssi = radio.getRSSI();
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
String loraPacket = ""; if (!Config.lowPowerMode && !Config.digi.ecoMode) {
if (receivedPackets.size() >= 10) {
if (transmissionFlag && !Config.lowPowerMode) { receivedPackets.erase(receivedPackets.begin());
radio.startReceive(); }
transmissionFlag = false; ReceivedPacket receivedPacket;
} else { receivedPacket.rxTime = NTP_Utils::getFormatedTime();
int state = radio.readData(loraPacket); receivedPacket.packet = packet.substring(3);
if (state == RADIOLIB_ERR_NONE) { receivedPacket.RSSI = rssi;
if (loraPacket != "" && !ignorePacket) { receivedPacket.SNR = snr;
rssi = radio.getRSSI(); receivedPackets.push_back(receivedPacket);
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println("<--- LoRa Packet Rx : " + loraPacket);
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
if (!Config.lowPowerMode) {
ReceivedPacket receivedPacket;
receivedPacket.millis = millis();
receivedPacket.packet = loraPacket.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
if (receivedPackets.size() >= 20) {
receivedPackets.erase(receivedPackets.begin());
} }
receivedPackets.push_back(receivedPacket); if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
} SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
}
lastRxTime = millis();
return packet;
}
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
rssi = radio.getRSSI();
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println(F("CRC error!"));
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log("Rx", loraPacket, rssi, snr, freqError); SYSLOG_Utils::log(0, packet, rssi, snr, freqError); // CRC
} }
return loraPacket; packet = "";
} } else {
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) { Utils::print(F("failed, code "));
// timeout occurred while waiting for a packet Utils::println(String(state));
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) { packet = "";
Utils::println(F("CRC error!"));
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log("Rx", "RADIOLIB_ERR_CRC_MISMATCH", 0,0,0);
} }
loraPacket = "";
} else {
Utils::print(F("failed, code "));
Utils::println(String(state));
}
if (ignorePacket) {
Utils::println("<--- LoRa Packet Rx : " + loraPacket);
Utils::println("Received own packet. Ignoring");
ignorePacket = false;
return "";
} }
} }
return loraPacket; return packet;
}
void sleepRadio() {
radio.sleep();
} }
} }
+8 -8
View File
@@ -6,14 +6,14 @@
namespace LoRa_Utils { namespace LoRa_Utils {
void setup(); void setup();
void sendNewPacket(const String &typeOfMessage, const String &newPacket); void sendNewPacket(const String& newPacket);
String generatePacket(String aprsisPacket); //String packetSanitization(const String& packet);
String packetSanitization(String packet); String receivePacket();
String receivePacket(); void changeFreqTx();
void changeFreqTx(); void changeFreqRx();
void changeFreqRx(); void startReceive(); // ???
void startReceive(); void sleepRadio();
} }
+34
View File
@@ -0,0 +1,34 @@
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <WiFi.h>
#include "configuration.h"
#include "ntp_utils.h"
#include "time.h"
extern Configuration Config;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 15 * 60 * 1000); // Update interval 15 min
namespace NTP_Utils {
void setup() {
if (WiFi.status() == WL_CONNECTED && !Config.digi.ecoMode && Config.callsign != "NOCALL-10") {
int gmt = Config.ntp.gmtCorrection * 3600;
timeClient.setTimeOffset(gmt);
timeClient.begin();
}
}
void update() {
if (WiFi.status() == WL_CONNECTED && !Config.digi.ecoMode && Config.callsign != "NOCALL-10") timeClient.update();
}
String getFormatedTime() {
if (!Config.digi.ecoMode) return timeClient.getFormattedTime();
return "DigiEcoMode Active";
}
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef NTP_UTILS_H_
#define NTP_UTILS_H_
#include <Arduino.h>
namespace NTP_Utils {
void setup();
void update();
String getFormatedTime();
}
#endif
+7 -7
View File
@@ -29,31 +29,31 @@ namespace OTA_Utils {
void onOTAStart() { void onOTAStart() {
Serial.println("OTA update started!"); Serial.println("OTA update started!");
display_toggle(true); displayToggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
show_display("", "", "", " OTA update started!", "", "", "", 1000); displayShow("", "", "", " OTA update started!", "", "", "", 1000);
isUpdatingOTA = true; isUpdatingOTA = true;
} }
void onOTAProgress(size_t current, size_t final) { void onOTAProgress(size_t current, size_t final) {
if (millis() - ota_progress_millis > 1000) { if (millis() - ota_progress_millis > 1000) {
display_toggle(true); displayToggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
ota_progress_millis = millis(); ota_progress_millis = millis();
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final); Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
show_display("", "", " OTA Progress : " + String((current*100)/final) + "%", "", "", "", "", 100); displayShow("", "", " OTA Progress : " + String((current*100)/final) + "%", "", "", "", "", 100);
} }
} }
void onOTAEnd(bool success) { void onOTAEnd(bool success) {
display_toggle(true); displayToggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
if (success) { if (success) {
Serial.println("OTA update finished successfully!"); Serial.println("OTA update finished successfully!");
show_display("", "", " OTA update success!", "", " Rebooting ...", "", "", 4000); displayShow("", "", " OTA update success!", "", " Rebooting ...", "", "", 4000);
} else { } else {
Serial.println("There was an error during OTA update!"); Serial.println("There was an error during OTA update!");
show_display("", "", " OTA update fail!", "", "", "", "", 4000); displayShow("", "", " OTA update fail!", "", "", "", "", 4000);
} }
isUpdatingOTA = false; isUpdatingOTA = false;
} }
-148
View File
@@ -1,148 +0,0 @@
#ifndef PINS_CONFIG_H_
#define PINS_CONFIG_H_
#include <Arduino.h>
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
// LORA MODULES
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0)
#define RADIO_SCLK_PIN 5 // GPIO5 - SX1278 SCK
#define RADIO_MISO_PIN 19 // GPIO19 - SX1278 MISO
#define RADIO_MOSI_PIN 27 // GPIO27 - SX1278 MOSI
#define RADIO_CS_PIN 18 // GPIO18 - SX1278 CS ---> NSS
#define RADIO_RST_PIN 14 // GPIO14 - SX1278 RST
#define RADIO_BUSY_PIN 26 // GPIO26 - SX1278 IRQ ---->DIO0
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WS)
#define RADIO_SCLK_PIN 9 // SX1262 SCK
#define RADIO_MISO_PIN 11 // SX1262 MISO
#define RADIO_MOSI_PIN 10 // SX1262 MOSI
#define RADIO_CS_PIN 8 // SX1262 NSS
#define RADIO_RST_PIN 12 // SX1262 RST
#define RADIO_DIO1_PIN 14 // SX1262 DIO1
#define RADIO_BUSY_PIN 13 // SX1262 BUSY
#endif
#ifdef ESP32_DIY_1W_LoRa // Ebyte E22 400M30S / SX1268
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 12
#define RADIO_BUSY_PIN 14
#define RADIO_RXEN 32
#define RADIO_TXEN 25
#endif
#if defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262)
#define RADIO_SCLK_PIN 5
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 27
#define RADIO_CS_PIN 18
#define RADIO_DIO0_PIN 26
#define RADIO_RST_PIN 23
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 32
#endif
#if defined(OE5HWN_MeshCom)
#define RADIO_SCLK_PIN 18
#define RADIO_MISO_PIN 19
#define RADIO_MOSI_PIN 23
#define RADIO_CS_PIN 5
#define RADIO_RST_PIN 27
#define RADIO_DIO1_PIN 33
#define RADIO_BUSY_PIN 26
#define RADIO_RXEN 14
#define RADIO_TXEN 13
#endif
#ifdef HELTEC_HTCT62
#define RADIO_SCLK_PIN 10 // SX1262 SCK
#define RADIO_MISO_PIN 6 // SX1262 MISO
#define RADIO_MOSI_PIN 7 // SX1262 MOSI
#define RADIO_CS_PIN 8 // SX1262 NSS
#define RADIO_RST_PIN 5 // SX1262 RST
#define RADIO_DIO1_PIN 3 // SX1262 DIO1
#define RADIO_BUSY_PIN 4 // SX1262 BUSY
#endif
// OLED
#if defined(TTGO_T_LORA32_V2_1) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) || defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(OE5HWN_MeshCom)
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#endif
#ifdef HELTEC_V2
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WS)
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 21
#endif
#ifndef HELTEC_HTCT62
#define HAS_DISPLAY
#endif
// Leds and other stuff
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(HELTEC_WS) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
#define HAS_INTERNAL_LED
#endif
#ifdef HELTEC_HTCT62
#define batteryPin 1
#endif
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
#define internalLedPin 25 // Green Led
#define batteryPin 35
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WS)
#define internalLedPin 35
#endif
#if defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
#define internalLedPin 2
#endif
#ifdef ESP32_C3_DIY_LoRa
#define OLED_SDA 8
#define OLED_SCL 9
#define OLED_RST 10
#define RADIO_SCLK_PIN 4
#define RADIO_MISO_PIN 5
#define RADIO_MOSI_PIN 6
#define RADIO_CS 7
#define RADIO_RST_PIN 3
#define RADIO_IRQ_PIN 2
#endif
/* (Same pins for LILYGO LoRa32 and ESP32 Wroom Dev )
SX1278-------------------> ESP32 ttgo-lora32-v21 and ESP32 WROOM Dev
GND GND
DIO1 -
DIO2 -
DIO3 -
VCC 3.3V
MISO 19
MOSI 27
SCLK 5
NSS 18
DIO0 26
REST 14
GND - */
#endif
+165 -78
View File
@@ -1,18 +1,19 @@
#include "configuration.h" #include "configuration.h"
#include "battery_utils.h"
#include "boards_pinout.h"
#include "power_utils.h" #include "power_utils.h"
#include "pins_config.h"
#if defined(HAS_AXP192) || defined(HAS_AXP2101) #if defined(HAS_AXP192) || defined(HAS_AXP2101)
#define I2C_SDA 21 #define I2C_SDA 21
#define I2C_SCL 22 #define I2C_SCL 22
#define IRQ_PIN 35 #define IRQ_PIN 35
#endif #endif
#ifdef HAS_AXP192 #ifdef HAS_AXP192
XPowersAXP192 PMU; XPowersAXP192 PMU;
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
XPowersAXP2101 PMU; XPowersAXP2101 PMU;
#endif #endif
extern Configuration Config; extern Configuration Config;
@@ -20,111 +21,197 @@ extern Configuration Config;
namespace POWER_Utils { namespace POWER_Utils {
bool BatteryIsConnected = false; double getBatteryVoltage() {
String batteryVoltage = ""; #if defined(HAS_AXP192) || defined(HAS_AXP2101)
String batteryChargeDischargeCurrent = ""; return (PMU.getBattVoltage() / 1000.0);
#else
return 0.0;
#endif
}
bool isBatteryConnected() {
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
return PMU.isBatteryConnect();
#else
return false;
#endif
}
void activateMeasurement() { void activateMeasurement() {
#if defined(HAS_AXP192) || defined(HAS_AXP2101) #if defined(HAS_AXP192) || defined(HAS_AXP2101)
PMU.disableTSPinMeasure(); PMU.disableTSPinMeasure();
PMU.enableBattDetection(); PMU.enableBattDetection();
PMU.enableVbusVoltageMeasure(); PMU.enableVbusVoltageMeasure();
PMU.enableBattVoltageMeasure(); PMU.enableBattVoltageMeasure();
PMU.enableSystemVoltageMeasure(); PMU.enableSystemVoltageMeasure();
#endif #endif
} }
void activateGPS() {
#ifdef HAS_AXP192
PMU.setLDO3Voltage(3300);
PMU.enableLDO3();
#endif
#ifdef HAS_AXP2101
PMU.setALDO3Voltage(3300);
PMU.enableALDO3();
#endif
#ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, HIGH);
#endif
//gpsIsActive = true;
}
void deactivateGPS() {
#ifdef HAS_AXP192
PMU.disableLDO3();
#endif
#ifdef HAS_AXP2101
PMU.disableALDO3();
#endif
#ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, LOW);
#endif
//gpsIsActive = false;
}
void activateLoRa() { void activateLoRa() {
#ifdef HAS_AXP192 #ifdef HAS_AXP192
PMU.setLDO2Voltage(3300); PMU.setLDO2Voltage(3300);
PMU.enableLDO2(); PMU.enableLDO2();
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
PMU.setALDO2Voltage(3300); PMU.setALDO2Voltage(3300);
PMU.enableALDO2(); PMU.enableALDO2();
#endif #endif
} }
void deactivateLoRa() { void deactivateLoRa() {
#ifdef HAS_AXP192 #ifdef HAS_AXP192
PMU.disableLDO2(); PMU.disableLDO2();
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
PMU.disableALDO2(); PMU.disableALDO2();
#endif #endif
} }
bool begin(TwoWire &port) { bool begin(TwoWire &port) {
#if defined(HAS_AXP192) #if defined(HAS_AXP192)
bool result = PMU.begin(Wire, AXP192_SLAVE_ADDRESS, I2C_SDA, I2C_SCL); bool result = PMU.begin(Wire, AXP192_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
if (result) { if (result) {
PMU.disableDC2(); PMU.disableDC2();
PMU.disableLDO2(); PMU.disableLDO2();
PMU.disableLDO3(); PMU.disableLDO3();
PMU.setDC1Voltage(3300); PMU.setDC1Voltage(3300);
PMU.enableDC1(); PMU.enableDC1();
PMU.setProtectedChannel(XPOWERS_DCDC3); PMU.setProtectedChannel(XPOWERS_DCDC3);
PMU.disableIRQ(XPOWERS_AXP192_ALL_IRQ); PMU.disableIRQ(XPOWERS_AXP192_ALL_IRQ);
} }
return result; return result;
#elif defined(HAS_AXP2101) #elif defined(HAS_AXP2101)
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL); bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
if (result) { if (result) {
PMU.disableDC2(); PMU.disableDC2();
PMU.disableDC3(); PMU.disableDC3();
PMU.disableDC4(); PMU.disableDC4();
PMU.disableDC5(); PMU.disableDC5();
PMU.disableALDO1(); PMU.disableALDO1();
PMU.disableALDO4(); PMU.disableALDO4();
PMU.disableBLDO1(); PMU.disableBLDO1();
PMU.disableBLDO2(); PMU.disableBLDO2();
PMU.disableDLDO1(); PMU.disableDLDO1();
PMU.disableDLDO2(); PMU.disableDLDO2();
PMU.setDC1Voltage(3300); PMU.setDC1Voltage(3300);
PMU.enableDC1(); PMU.enableDC1();
PMU.setButtonBatteryChargeVoltage(3300); PMU.setButtonBatteryChargeVoltage(3300);
PMU.enableButtonBatteryCharge(); PMU.enableButtonBatteryCharge();
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ); PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
} }
return result; return result;
#else #else
return true; return true;
#endif #endif
} }
void setup() { void setup() {
Wire.end();
#ifdef HAS_AXP192 #ifdef HAS_AXP192
Wire.begin(SDA, SCL); Wire.begin(SDA, SCL);
if (begin(Wire)) { if (begin(Wire)) {
Serial.println("AXP192 init done!"); Serial.println("AXP192 init done!");
} else { } else {
Serial.println("AXP192 init failed!"); Serial.println("AXP192 init failed!");
} }
activateLoRa(); activateLoRa();
activateMeasurement(); activateMeasurement();
PMU.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT); PMU.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT);
PMU.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2); PMU.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
PMU.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_780MA); PMU.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_780MA);
PMU.setSysPowerDownVoltage(2600); PMU.setSysPowerDownVoltage(2600);
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
Wire.begin(SDA, SCL); Wire.begin(SDA, SCL);
if (begin(Wire)) { if (begin(Wire)) {
Serial.println("AXP2101 init done!"); Serial.println("AXP2101 init done!");
} else { } else {
Serial.println("AXP2101 init failed!"); Serial.println("AXP2101 init failed!");
} }
activateLoRa(); activateLoRa();
activateMeasurement(); activateMeasurement();
PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_200MA); PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_200MA);
PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA); PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_800MA); PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_800MA);
PMU.setSysPowerDownVoltage(2600); PMU.setSysPowerDownVoltage(2600);
#endif #endif
#ifdef BATTERY_PIN
pinMode(BATTERY_PIN, INPUT);
#endif
#ifdef INTERNAL_LED_PIN
pinMode(INTERNAL_LED_PIN, OUTPUT);
#endif
if (Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
pinMode(Config.battery.externalVoltagePin, INPUT);
}
#ifdef VEXT_CTRL
pinMode(VEXT_CTRL,OUTPUT); // GPS + TFT on HELTEC Wireless_Tracker and only for Oled in HELTEC V3
#ifndef HELTEC_WSL_V3
digitalWrite(VEXT_CTRL, HIGH);
#endif
#ifdef HELTEC_WP
digitalWrite(VEXT_CTRL, LOW);
#endif
#endif
#ifdef HAS_GPS
if (Config.beacon.gpsActive) activateGPS();
#endif
#ifdef ADC_CTRL
pinMode(ADC_CTRL, OUTPUT);
#endif
#if defined(HELTEC_WIRELESS_TRACKER)
Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WP) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.begin(BOARD_I2C_SDA, BOARD_I2C_SCL);
#endif
#if defined(HELTEC_V3) || defined(HELTEC_WS)
Wire.begin(OLED_SDA, OLED_SCL);
#endif
delay(1000);
BATTERY_Utils::setup();
BATTERY_Utils::startupBatteryHealth();
} }
} }
+14 -6
View File
@@ -2,16 +2,24 @@
#define POWER_UTILS_H_ #define POWER_UTILS_H_
#include <Arduino.h> #include <Arduino.h>
#include "XPowersLib.h" #if defined(HAS_AXP192) || defined(HAS_AXP2101)
#include "XPowersLib.h"
#else
#include <Wire.h>
#endif
namespace POWER_Utils { namespace POWER_Utils {
void activateMeasurement(); double getBatteryVoltage();
void activateLoRa(); bool isBatteryConnected();
void deactivateLoRa(); void activateMeasurement();
bool begin(TwoWire &port); void activateGPS();
void setup(); void deactivateGPS();
void activateLoRa();
void deactivateLoRa();
bool begin(TwoWire &port);
void setup();
} }
+67 -30
View File
@@ -1,52 +1,89 @@
#include "configuration.h" #include "configuration.h"
#include "station_utils.h"
#include "query_utils.h" #include "query_utils.h"
#include "lora_utils.h"
extern Configuration Config;
extern std::vector<String> lastHeardStation; extern Configuration Config;
extern std::vector<String> lastHeardStation_temp; extern std::vector<LastHeardStation> lastHeardStations;
extern String versionDate; extern String versionDate;
extern int rssi;
extern float snr;
extern int freqError;
namespace QUERY_Utils { namespace QUERY_Utils {
String process(String query, String station, String queryOrigin) { String process(const String& query, const String& station, bool queryFromAPRSIS, bool thirdParty) {
String answer; String answer;
if (query=="?APRS?" || query=="?aprs?" || query=="?Aprs?" || query=="H" || query=="h" || query=="HELP" || query=="Help" || query=="help" || query=="?") { String queryQuestion = query;
answer = "?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign"; queryQuestion.toUpperCase();
} else if (query=="?APRSV" || query=="?aprsv" || query=="?Aprsv") { if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
answer = "CA2RXU_LoRa_iGate 1.3 v" + versionDate; answer.concat("?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign");
} else if (query=="?APRSP" || query=="?aprsp" || query=="?Aprsp") { } else if (queryQuestion == "?APRSV") {
answer = "iGate QTH: " + String(Config.beacon.latitude,2) + " " + String(Config.beacon.longitude,2); answer.concat("CA2RXU_LoRa_iGate 2.0 v");
} else if (query=="?APRSL" || query=="?aprsl" || query=="?Aprsl") { answer.concat(versionDate);
if (lastHeardStation.size() == 0) { } else if (queryQuestion == "?APRSP") {
answer = "No Station Listened in the last " + String(Config.rememberStationTime) + "min."; answer.concat("iGate QTH: ");
answer.concat(String(Config.beacon.latitude,3));
answer.concat(" ");
answer.concat(String(Config.beacon.longitude,3));
} else if (queryQuestion == "?APRSL") {
if (lastHeardStations.size() == 0) {
char answerArray[50];
snprintf(answerArray, sizeof(answerArray), "No Station Listened in the last %d min.", Config.rememberStationTime);
answer.concat(answerArray);
} else { } else {
for (int i=0; i<lastHeardStation.size(); i++) { for (int i=0; i<lastHeardStations.size(); i++) {
answer += lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) + " "; answer += lastHeardStations[i].station + " ";
} }
answer.trim(); answer.trim();
} }
} else if (query.indexOf("?APRSH") == 0 || query.indexOf("?aprsh") == 0 || query.indexOf("?Aprsh") == 0) { } else if (queryQuestion == "?APRSSR") {
char signalData[35];
snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
answer.concat(signalData);
} else if (queryQuestion.indexOf("?APRSH") == 0) {
// sacar callsign despues de ?APRSH // sacar callsign despues de ?APRSH
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?"); Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
answer = "APRSH on development 73!"; answer.concat("?APRSH on development 73!");
} else if (query.indexOf("?WHERE") == 0) { } else if (queryQuestion.indexOf("?WHERE") == 0) {
// agregar callsign para completar donde esta X callsign --> posicion // agregar callsign para completar donde esta X callsign --> posicion
Serial.println("estaciones escuchadas directo (ultimos 30 min)"); Serial.println("estaciones escuchadas directo (ultimos 30 min)");
answer = "?WHERE on development 73!"; answer.concat("?WHERE on development 73!");
} else if (queryQuestion.indexOf("?APRSEEM") == 0 && Config.digi.ecoMode == true) { // Exit DigiRepeater EcoMode
answer = "DigiEcoMode:Stop";
Config.digi.ecoMode = false;
Config.display.alwaysOn = true;
Config.display.timeout = 10;
} else if (queryQuestion.indexOf("?APRSSEM") == 0 && Config.digi.ecoMode == false) { // Start DigiRepeater EcoMode
answer = "DigiEcoMode:Start";
Config.digi.ecoMode = true;
} else if (queryQuestion.indexOf("?APRSEMS") == 0) { // DigiRepeater EcoMode Status
answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
} }
for(int i = station.length(); i < 9; i++) {
station += ' '; String queryAnswer = Config.callsign;
} queryAnswer += ">APLRG1";
if (queryOrigin == "APRSIS") { if (queryFromAPRSIS) {
return Config.callsign + ">APLRG1,TCPIP,qAC::" + station + ":" + answer;// + "\n"; queryAnswer += ",TCPIP,qAC";
} else { //} if (queryOrigin == "LoRa") { } else {
if (Config.beacon.path == "") { if (!thirdParty) queryAnswer += ",RFONLY";
return Config.callsign + ">APLRG1,RFONLY::" + station + ":" + answer; if (Config.beacon.path != "") {
} else { queryAnswer += ",";
return Config.callsign + ">APLRG1,RFONLY," + Config.beacon.path + "::" + station + ":" + answer; queryAnswer += Config.beacon.path;
} }
} }
queryAnswer += "::";
String processedStation = station;
for (int i = station.length(); i < 9; i++) {
processedStation += ' ';
}
queryAnswer += processedStation;
queryAnswer += ":";
queryAnswer += answer;
return queryAnswer;
} }
} }
+1 -1
View File
@@ -6,7 +6,7 @@
namespace QUERY_Utils { namespace QUERY_Utils {
String process(String query, String station, String queryOrigin); String process(const String& query, const String& station, bool queryFromAPRSIS, bool thirdParty);
} }
+88 -57
View File
@@ -1,65 +1,68 @@
#include "station_utils.h" #include "station_utils.h"
#include "battery_utils.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "configuration.h" #include "configuration.h"
#include "lora_utils.h"
#include "display.h"
#include "utils.h" #include "utils.h"
#include <vector> #include <vector>
extern Configuration Config; extern Configuration Config;
extern std::vector<String> lastHeardStation; extern uint32_t lastRxTime;
extern std::vector<String> lastHeardStation_temp; extern String fourthLine;
extern std::vector<String> packetBuffer; extern bool shouldSleepLowVoltage;
extern std::vector<String> packetBuffer_temp;
extern String fourthLine; uint32_t lastTxTime = millis();
std::vector<LastHeardStation> lastHeardStations;
std::vector<String> outputPacketBuffer;
std::vector<Packet25SegBuffer> packet25SegBuffer;
namespace STATION_Utils { namespace STATION_Utils {
void deleteNotHeard() { void deleteNotHeard() {
for (int i = 0; i < lastHeardStation.size(); i++) { std::vector<LastHeardStation> lastHeardStation_temp;
String deltaTimeString = lastHeardStation[i].substring(lastHeardStation[i].indexOf(",") + 1); for (int i = 0; i < lastHeardStations.size(); i++) {
uint32_t deltaTime = deltaTimeString.toInt(); if (millis() - lastHeardStations[i].lastHeardTime < Config.rememberStationTime * 60 * 1000) {
if ((millis() - deltaTime) < Config.rememberStationTime * 60 * 1000) { lastHeardStation_temp.push_back(lastHeardStations[i]);
lastHeardStation_temp.push_back(lastHeardStation[i]);
} }
} }
lastHeardStation.clear(); lastHeardStations.clear();
for (int j = 0; j < lastHeardStation_temp.size(); j++) { for (int j = 0; j < lastHeardStation_temp.size(); j++) {
lastHeardStation.push_back(lastHeardStation_temp[j]); lastHeardStations.push_back(lastHeardStation_temp[j]);
} }
lastHeardStation_temp.clear(); lastHeardStation_temp.clear();
} }
void updateLastHeard(String station) { void updateLastHeard(const String& station) {
deleteNotHeard(); deleteNotHeard();
bool stationHeard = false; bool stationHeard = false;
for (int i = 0; i < lastHeardStation.size(); i++) { for (int i = 0; i < lastHeardStations.size(); i++) {
if (lastHeardStation[i].substring(0, lastHeardStation[i].indexOf(",")) == station) { if (lastHeardStations[i].station == station) {
lastHeardStation[i] = station + "," + String(millis()); lastHeardStations[i].lastHeardTime = millis();
stationHeard = true; stationHeard = true;
} }
} }
if (!stationHeard) { if (!stationHeard) {
lastHeardStation.push_back(station + "," + String(millis())); LastHeardStation lastStation;
lastStation.lastHeardTime = millis();
lastStation.station = station;
lastHeardStations.push_back(lastStation);
} }
fourthLine = "Stations (" + String(Config.rememberStationTime) + "min) = "; fourthLine = "Stations (";
if (lastHeardStation.size() < 10) { fourthLine += String(Config.rememberStationTime);
fourthLine += "min) = ";
if (lastHeardStations.size() < 10) {
fourthLine += " "; fourthLine += " ";
} }
fourthLine += String(lastHeardStation.size()); fourthLine += String(lastHeardStations.size());
// DEBUG ONLY
// Serial.print("Stations Near (last " + String(Config.rememberStationTime) + " minutes): ");
// for (int k=0; k<lastHeardStation.size(); k++) {
// Serial.print(lastHeardStation[k].substring(0,lastHeardStation[k].indexOf(","))); Serial.print(" ");
// }
// Serial.println("");
} }
bool wasHeard(String station) { bool wasHeard(const String& station) {
deleteNotHeard(); deleteNotHeard();
for (int i = 0; i < lastHeardStation.size(); i++) { for (int i = 0; i < lastHeardStations.size(); i++) {
if (lastHeardStation[i].substring(0, lastHeardStation[i].indexOf(",")) == station) { if (lastHeardStations[i].station == station) {
Utils::println(" ---> Listened Station"); Utils::println(" ---> Listened Station");
return true; return true;
} }
@@ -68,37 +71,65 @@ namespace STATION_Utils {
return false; return false;
} }
void checkBuffer() { void clean25SegBuffer() {
for (int i = 0; i < packetBuffer.size(); i++) { if (!packet25SegBuffer.empty()) {
String deltaTimeString = packetBuffer[i].substring(0, packetBuffer[i].indexOf(",")); if ((millis() - packet25SegBuffer[0].receivedTime) > 25 * 1000) {
uint32_t deltaTime = deltaTimeString.toInt(); packet25SegBuffer.erase(packet25SegBuffer.begin());
if ((millis() - deltaTime) < 60 * 1000) { // cambiar a 15 segundos?
packetBuffer_temp.push_back(packetBuffer[i]);
} }
} }
packetBuffer.clear();
for (int j = 0; j < packetBuffer_temp.size(); j++) {
packetBuffer.push_back(packetBuffer_temp[j]);
}
packetBuffer_temp.clear();
// DEBUG ONLY
// for (int i=0; i<packetBuffer.size(); i++) {
// Serial.println(packetBuffer[i]);
// }
} }
void updatePacketBuffer(String packet) { bool check25SegBuffer(const String& station, const String& textMessage) {
if ((packet.indexOf(":!") == -1) && (packet.indexOf(":=") == -1) && (packet.indexOf(":>") == -1) && (packet.indexOf(":`") == -1)) { bool shouldBeIgnored = false;
String sender = packet.substring(3, packet.indexOf(">")); if (!packet25SegBuffer.empty()) {
String tempAddressee = packet.substring(packet.indexOf("::") + 2); for (int i = 0; i < packet25SegBuffer.size(); i++) {
String addressee = tempAddressee.substring(0, tempAddressee.indexOf(":")); if (packet25SegBuffer[i].station == station && packet25SegBuffer[i].payload == textMessage) {
addressee.trim(); shouldBeIgnored = true;
String message = tempAddressee.substring(tempAddressee.indexOf(":") + 1); }
//Serial.println(String(millis()) + "," + sender + "," + addressee + "," + message); }
packetBuffer.push_back(String(millis()) + "," + sender + "," + addressee + "," + message);
checkBuffer();
} }
if (shouldBeIgnored) {
return false;
} else {
Packet25SegBuffer packet;
packet.receivedTime = millis();
packet.station = station;
packet.payload = textMessage;
packet25SegBuffer.push_back(packet);
return true;
}
}
void processOutputPacketBuffer() {
int timeToWait = 3 * 1000; // 3 segs between packet Tx and also Rx ???
uint32_t lastRx = millis() - lastRxTime;
uint32_t lastTx = millis() - lastTxTime;
bool saveNewDigiEcoModeConfig = false;
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]);
if (outputPacketBuffer[0].indexOf("DigiEcoMode:Start") != -1 || outputPacketBuffer[0].indexOf("DigiEcoMode:Stop") != -1) {
saveNewDigiEcoModeConfig = true;
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
}
outputPacketBuffer.erase(outputPacketBuffer.begin());
lastTxTime = millis();
}
if (shouldSleepLowVoltage) {
while (outputPacketBuffer.size() > 0) {
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]);
outputPacketBuffer.erase(outputPacketBuffer.begin());
delay(4000);
}
}
if (saveNewDigiEcoModeConfig) {
Config.writeFile();
displayToggle(false);
ESP.restart();
}
}
void addToOutputPacketBuffer(const String& packet) {
outputPacketBuffer.push_back(packet);
} }
} }
+19 -4
View File
@@ -1,16 +1,31 @@
#ifndef STATION_UTILS_H_ #ifndef STATION_UTILS_H_
#define STATION_UTILS_H_ #define STATION_UTILS_H_
#include <Arduino.h> #include <Arduino.h>
struct Packet25SegBuffer {
uint32_t receivedTime;
String station;
String payload;
};
struct LastHeardStation {
uint32_t lastHeardTime;
String station;
};
namespace STATION_Utils { namespace STATION_Utils {
void deleteNotHeard(); void deleteNotHeard();
void updateLastHeard(String station); void updateLastHeard(const String& station);
bool wasHeard(String station); bool wasHeard(const String& station);
void checkBuffer(); void clean25SegBuffer();
void updatePacketBuffer(String packet); bool check25SegBuffer(const String& station, const String& textMessage);
void processOutputPacketBuffer();
void addToOutputPacketBuffer(const String& packet);
} }
+89 -44
View File
@@ -11,53 +11,98 @@ WiFiUDP udpClient;
namespace SYSLOG_Utils { namespace SYSLOG_Utils {
void log(String type, String packet, int rssi, float snr, int freqError) { void log(const uint8_t type, const String& packet, const int rssi, const float snr, const int freqError) {
String syslogPacket = "<165>1 - " + Config.callsign + " CA2RXU_LoRa_iGate_1.3" + " - - - "; //RFC5424 The Syslog Protocol
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
if (type == "APRSIS Tx") { String syslogPacket = "<165>1 - ";
if (packet.indexOf(":>") > 10) { syslogPacket.concat(Config.callsign);
syslogPacket += type + " / StartUp_Status / " + packet.substring(packet.indexOf(":>")+2); syslogPacket.concat(" CA2RXU_LoRa_iGate_1.3 - - - "); //RFC5424 The Syslog Protocol
} else {
syslogPacket += type + " / QUERY / " + packet; char signalData[35];
} snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
} else if (type == "Rx") {
if (packet.indexOf("::") > 10) { switch (type) {
syslogPacket += type + " / MESSAGE / " + packet.substring(3,packet.indexOf(">")) + " ---> " + packet.substring(packet.indexOf("::")+2); case 0: // CRC
syslogPacket += " / " + String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz"; syslogPacket.concat("CRC / CRC-ERROR / ");
} else if (packet.indexOf(":!") > 10 || packet.indexOf(":=") > 10) { syslogPacket.concat(packet);
syslogPacket += type + " / GPS / " + packet.substring(3,packet.indexOf(">")) + " / "; syslogPacket.concat(signalData);
if (packet.indexOf("WIDE1-1") > 10) { break;
syslogPacket += packet.substring(packet.indexOf(">")+1,packet.indexOf(",")) + " / WIDE1-1 / "; case 1: // RX
syslogPacket.concat("RX / ");
if (packet.indexOf("::") > 10) {
syslogPacket.concat("MESSAGE / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> "); syslogPacket.concat(packet.substring(packet.indexOf("::") + 2));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":!") > 10 || packet.indexOf(":=") > 10) {
syslogPacket.concat("GPS / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" / ");
if (packet.indexOf("WIDE1-1") > 10) {
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(",")));
syslogPacket.concat(" / WIDE1-1");
} else {
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(":")));
syslogPacket.concat(" / -");
}
syslogPacket.concat(signalData);
syslogPacket.concat(" / ");
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
} else if (packet.indexOf(":>") > 10) {
syslogPacket.concat("STATUS / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":>") + 2));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":`") > 10) {
syslogPacket.concat("MIC-E / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":`") + 2));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
syslogPacket.concat("TELEMETRY / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":T#") + 3));
syslogPacket.concat(signalData);
} else if (packet.indexOf(":;") > 10) {
syslogPacket.concat("OBJECT / ");
syslogPacket.concat(packet.substring(3, packet.indexOf(">")));
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(packet.indexOf(":;") + 2));
syslogPacket.concat(signalData);
} else { } else {
syslogPacket += packet.substring(packet.indexOf(">")+1,packet.indexOf(":")) + " / - / "; syslogPacket.concat(packet);
syslogPacket.concat(signalData);
} }
syslogPacket += String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz / " + GPS_Utils::getDistance(packet); break;
} else if (packet.indexOf(":>") > 10) { case 2: // APRSIS TX
syslogPacket += type + " / STATUS / " + packet.substring(3,packet.indexOf(">")) + " ---> " + packet.substring(packet.indexOf(":>")+2); syslogPacket.concat("APRSIS TX / ");
syslogPacket += " / " + String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz"; if (packet.indexOf(":>") > 10) {
} else if (packet.indexOf(":`") > 10) { syslogPacket.concat("StartUp_Status / ");
syslogPacket += type + " / MIC-E / " + packet.substring(3,packet.indexOf(">")) + " ---> " + packet.substring(packet.indexOf(":`")+2); syslogPacket.concat(packet.substring(packet.indexOf(":>") + 2));
syslogPacket += " / " + String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz"; } else {
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) { syslogPacket.concat("QUERY / ");
syslogPacket += type + " / TELEMETRY / " + packet.substring(3,packet.indexOf(">")) + " ---> " + packet.substring(packet.indexOf(":T#")+3); syslogPacket.concat(packet);
syslogPacket += " / " + String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz"; }
} else if (packet.indexOf(":;") > 10) { break;
syslogPacket += type + " / OBJECT / " + packet.substring(3,packet.indexOf(">")) + " ---> " + packet.substring(packet.indexOf(":;")+2); case 3: // TX
syslogPacket += " / " + String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz"; syslogPacket.concat("TX / ");
} else { if (packet.indexOf("RFONLY") > 10) {
syslogPacket += type + " / " + packet; syslogPacket.concat("RFONLY / ");
syslogPacket += " / " + String(rssi) + "dBm / " + String(snr) + "dB / " + String(freqError) + "Hz"; syslogPacket.concat(packet);
} } else if (packet.indexOf("::") > 10) {
} else if (type == "Tx") { syslogPacket.concat("MESSAGE / ");
if (packet.indexOf("RFONLY") > 10) { syslogPacket.concat(packet.substring(0,packet.indexOf(">")));
syslogPacket += type + " / RFONLY / " + packet; syslogPacket.concat(" ---> ");
} else if (packet.indexOf("::") > 10) { syslogPacket.concat(packet.substring(packet.indexOf("::") + 2));
syslogPacket += type + " / MESSAGE / " + packet.substring(0,packet.indexOf(">")) + " ---> " + packet.substring(packet.indexOf("::")+2); } else {
} else { syslogPacket.concat(packet);
syslogPacket += type + " / " + packet; }
} break;
} else { default:
syslogPacket = "<165>1 - ERROR LoRa - - - ERROR / Error in Syslog Packet"; //RFC5424 The Syslog Protocol syslogPacket = "<165>1 - ERROR LoRa - - - ERROR / Error in Syslog Packet"; //RFC5424 The Syslog Protocol
break;
} }
udpClient.beginPacket(Config.syslog.server.c_str(), Config.syslog.port); udpClient.beginPacket(Config.syslog.server.c_str(), Config.syslog.port);
udpClient.write((const uint8_t*)syslogPacket.c_str(), syslogPacket.length()); udpClient.write((const uint8_t*)syslogPacket.c_str(), syslogPacket.length());
+1 -1
View File
@@ -6,7 +6,7 @@
namespace SYSLOG_Utils { namespace SYSLOG_Utils {
void log(String type ,String packet, int rssi, float snr, int freqError); void log(const uint8_t type ,const String& packet, const int rssi, const float snr, const int freqError);
void setup(); void setup();
} }
+19 -28
View File
@@ -1,8 +1,8 @@
#include <WiFi.h> #include <WiFi.h>
#include "kiss_utils.h" #include "kiss_utils.h"
#include "kiss_protocol.h" #include "kiss_protocol.h"
#include "lora_utils.h"
#include "configuration.h" #include "configuration.h"
#include "station_utils.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
@@ -22,24 +22,20 @@ String inputSerialBuffer = "";
namespace TNC_Utils { namespace TNC_Utils {
void setup() { void setup() {
if (Config.tnc.enableServer) { if (Config.tnc.enableServer && !Config.digi.ecoMode) {
tncServer.stop(); tncServer.stop();
tncServer.begin(); tncServer.begin();
} }
} }
void checkNewClients() { void checkNewClients() {
WiFiClient new_client = tncServer.available(); WiFiClient new_client = tncServer.accept();
if (new_client.connected()) { if (new_client.connected()) {
for (int i = 0; i < MAX_CLIENTS; i++) { for (int i = 0; i < MAX_CLIENTS; i++) {
WiFiClient* client = clients[i]; WiFiClient* client = clients[i];
if (client == nullptr) { if (client == nullptr) {
clients[i] = new WiFiClient(new_client); clients[i] = new WiFiClient(new_client);
Utils::println("New TNC client connected"); Utils::println("New TNC client connected");
break; break;
} }
} }
@@ -48,13 +44,11 @@ namespace TNC_Utils {
void handleInputData(char character, int bufferIndex) { void handleInputData(char character, int bufferIndex) {
String* data; String* data;
if (bufferIndex == -1) { if (bufferIndex == -1) {
data = &inputSerialBuffer; data = &inputSerialBuffer;
} else { } else {
data = &inputServerBuffer[bufferIndex]; data = &inputServerBuffer[bufferIndex];
} }
if (data->length() == 0 && character != (char)FEND) { if (data->length() == 0 && character != (char)FEND) {
return; return;
} }
@@ -74,12 +68,11 @@ namespace TNC_Utils {
String sender = frame.substring(0,frame.indexOf(">")); String sender = frame.substring(0,frame.indexOf(">"));
if (Config.tnc.acceptOwn || sender != Config.callsign) { if (Config.tnc.acceptOwn || sender != Config.callsign) {
LoRa_Utils::sendNewPacket("APRS", frame); STATION_Utils::addToOutputPacketBuffer(frame);
} else { } else {
Utils::println("Ignored own frame from KISS"); Utils::println("Ignored own frame from KISS");
} }
} }
data->clear(); data->clear();
} }
@@ -112,10 +105,10 @@ namespace TNC_Utils {
} }
} }
void sendToClients(String packet) { void sendToClients(const String& packet) {
packet = packet.substring(3); String cleanPacket = packet.substring(3);
const String kissEncoded = encodeKISS(packet); const String kissEncoded = encodeKISS(cleanPacket);
for (int i = 0; i < MAX_CLIENTS; i++) { for (int i = 0; i < MAX_CLIENTS; i++) {
auto client = clients[i]; auto client = clients[i];
@@ -129,27 +122,25 @@ namespace TNC_Utils {
} }
} }
} }
Utils::print("---> Sent to TNC : "); Utils::print("---> Sent to TNC : ");
Utils::println(packet); Utils::println(cleanPacket);
} }
void sendToSerial(String packet) { void sendToSerial(const String& packet) {
packet = packet.substring(3); String cleanPacket = packet.substring(3);
Serial.print(encodeKISS(cleanPacket));
Serial.print(encodeKISS(packet));
Serial.flush(); Serial.flush();
} }
void loop() { void loop() {
if (Config.tnc.enableServer) { if (!Config.digi.ecoMode) {
checkNewClients(); if (Config.tnc.enableServer) {
checkNewClients();
readFromClients(); readFromClients();
} }
if (Config.tnc.enableSerial) {
if (Config.tnc.enableSerial) { readFromSerial();
readFromSerial(); }
} }
} }
} }
+2 -2
View File
@@ -8,8 +8,8 @@ namespace TNC_Utils {
void setup(); void setup();
void loop(); void loop();
void sendToClients(String packet); void sendToClients(const String& packet);
void sendToSerial(String packet); void sendToSerial(const String& packet);
} }
+352 -114
View File
@@ -1,21 +1,24 @@
#include <TinyGPS++.h>
#include <WiFi.h> #include <WiFi.h>
#include "configuration.h" #include "configuration.h"
#include "station_utils.h" #include "station_utils.h"
#include "battery_utils.h" #include "battery_utils.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "boards_pinout.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "pins_config.h" #include "A7670_utils.h"
#include "wifi_utils.h"
#include "lora_utils.h" #include "lora_utils.h"
#include "wifi_utils.h"
#include "gps_utils.h" #include "gps_utils.h"
#include "bme_utils.h" #include "wx_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern WiFiClient espClient;
extern Configuration Config; extern Configuration Config;
extern WiFiClient espClient;
extern TinyGPSPlus gps;
extern String versionDate; extern String versionDate;
extern bool statusAfterBoot;
extern String firstLine; extern String firstLine;
extern String secondLine; extern String secondLine;
extern String thirdLine; extern String thirdLine;
@@ -23,125 +26,280 @@ extern String fourthLine;
extern String fifthLine; extern String fifthLine;
extern String sixthLine; extern String sixthLine;
extern String seventhLine; extern String seventhLine;
extern uint32_t lastBeaconTx;
extern uint32_t lastScreenOn;
extern bool beaconUpdate;
extern String iGateBeaconPacket; extern String iGateBeaconPacket;
extern String iGateLoRaBeaconPacket; extern String iGateLoRaBeaconPacket;
extern std::vector<String> lastHeardStation;
extern int rssi; extern int rssi;
extern float snr; extern float snr;
extern int freqError; extern int freqError;
extern String distance; extern String distance;
extern uint32_t lastWiFiCheck;
extern bool WiFiConnect;
extern bool WiFiConnected; extern bool WiFiConnected;
extern int wxModuleType;
extern bool backUpDigiMode;
extern bool shouldSleepLowVoltage;
extern bool transmitFlag;
extern std::vector<LastHeardStation> lastHeardStations;
bool statusAfterBoot = true;
bool sendStartTelemetry = true;
bool beaconUpdate = true;
uint32_t lastBeaconTx = 0;
uint32_t lastScreenOn = millis();
String beaconPacket;
String secondaryBeaconPacket;
namespace Utils { namespace Utils {
void processStatus() { void processStatus() {
String status = Config.callsign + ">APLRG1," + Config.beacon.path; String status = Config.callsign;
status.concat(">APLRG1");
if (Config.beacon.path.indexOf("WIDE") == 0) {
status.concat(",");
status.concat(Config.beacon.path);
}
if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) { if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) {
delay(1000); delay(1000);
status += ",qAC:>https://github.com/richonguzman/LoRa_APRS_iGate " + versionDate; status.concat(",qAC:>https://github.com/richonguzman/LoRa_APRS_iGate ");
status.concat(versionDate);
APRS_IS_Utils::upload(status); APRS_IS_Utils::upload(status);
SYSLOG_Utils::log("APRSIS Tx", status,0,0,0); SYSLOG_Utils::log(2, status, 0, 0.0, 0); // APRSIS TX
statusAfterBoot = false; statusAfterBoot = false;
} }
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) { if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
delay(2000); status.concat(":>https://github.com/richonguzman/LoRa_APRS_iGate ");
status += ":>https://github.com/richonguzman/LoRa_APRS_iGate " + versionDate; status.concat(versionDate);
LoRa_Utils::sendNewPacket("APRS", status); STATION_Utils::addToOutputPacketBuffer(status);
statusAfterBoot = false; statusAfterBoot = false;
} }
} }
String getLocalIP() { String getLocalIP() {
if (!WiFiConnected) { if (Config.digi.ecoMode) {
return "** WiFi AP Killed **";
} else if (!WiFiConnected) {
return "IP : 192.168.4.1"; return "IP : 192.168.4.1";
} else if (backUpDigiMode) {
return "- BACKUP DIGI MODE -";
} else { } else {
return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]); return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
} }
} }
void setupDisplay() { void setupDisplay() {
setup_display(); displaySetup();
#ifdef HAS_INTERNAL_LED #ifdef INTERNAL_LED_PIN
digitalWrite(internalLedPin,HIGH); digitalWrite(INTERNAL_LED_PIN,HIGH);
#endif #endif
Serial.println("\nStarting Station: " + Config.callsign + " Version: " + versionDate); Serial.println("\nStarting Station: " + Config.callsign + " Version: " + versionDate);
show_display(" LoRa APRS", "", " ( iGATE & DIGI )", "", "", "Richonguzman / CA2RXU", " " + versionDate, 4000); Serial.println((Config.digi.ecoMode) ? "(DigiEcoMode: ON)" : "(DigiEcoMode: OFF)");
#ifdef HAS_INTERNAL_LED displayShow(" LoRa APRS", "", "", " ( iGATE & DIGI )", "", "" , " CA2RXU " + versionDate, 4000);
digitalWrite(internalLedPin,LOW); #ifdef INTERNAL_LED_PIN
digitalWrite(INTERNAL_LED_PIN,LOW);
#endif #endif
firstLine = Config.callsign; firstLine = Config.callsign;
seventhLine = " listening..."; seventhLine = " listening...";
} }
void activeStations() { void activeStations() {
fourthLine = "Stations (" + String(Config.rememberStationTime) + "min) = "; fourthLine = "Stations (";
if (lastHeardStation.size() < 10) { fourthLine.concat(String(Config.rememberStationTime));
fourthLine.concat("min) = ");
if (lastHeardStations.size() < 10) {
fourthLine += " "; fourthLine += " ";
} }
fourthLine += String(lastHeardStation.size()); fourthLine.concat(String(lastHeardStations.size()));
} }
void sendInitialTelemetryPackets() {
String sender = Config.callsign;
for (int i = sender.length(); i < 9; i++) {
sender += ' ';
}
String baseAPRSISTelemetryPacket = Config.callsign;
baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::";
baseAPRSISTelemetryPacket += sender;
baseAPRSISTelemetryPacket += ":";
String baseRFTelemetryPacket = Config.callsign;
baseRFTelemetryPacket += ">APLRG1,WIDE1-1::";
baseRFTelemetryPacket += sender;
baseRFTelemetryPacket += ":";
String telemetryPacket1 = "EQNS.";
if (Config.battery.sendInternalVoltage) {
telemetryPacket1 += "0,0.01,0";
}
if (Config.battery.sendExternalVoltage) {
telemetryPacket1 += String(Config.battery.sendInternalVoltage ? "," : "") + "0,0.02,0";
}
String telemetryPacket2 = "UNIT.";
if (Config.battery.sendInternalVoltage) {
telemetryPacket2 += "VDC";
}
if (Config.battery.sendExternalVoltage) {
telemetryPacket2 += String(Config.battery.sendInternalVoltage ? "," : "") + "VDC";
}
String telemetryPacket3 = "PARM.";
if (Config.battery.sendInternalVoltage) {
telemetryPacket3 += "V_Batt";
}
if (Config.battery.sendExternalVoltage) {
telemetryPacket3 += String(Config.battery.sendInternalVoltage ? "," : "") + "V_Ext";
}
if (Config.beacon.sendViaAPRSIS) {
#ifdef HAS_A7670
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket1);
delay(300);
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket2);
delay(300);
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket3);
delay(300);
#else
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket1);
delay(300);
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket2);
delay(300);
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket3);
delay(300);
#endif
delay(300);
} else if (Config.beacon.sendViaRF) {
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket1);
delay(3000);
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket2);
delay(3000);
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket3);
delay(3000);
}
sendStartTelemetry = false;
}
void checkBeaconInterval() { void checkBeaconInterval() {
uint32_t lastTx = millis() - lastBeaconTx; uint32_t lastTx = millis() - lastBeaconTx;
String beaconPacket = iGateBeaconPacket;
String secondaryBeaconPacket = iGateLoRaBeaconPacket;
if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) { if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) {
beaconUpdate = true; beaconUpdate = true;
} }
#ifdef HAS_GPS
if (Config.beacon.gpsActive && gps.location.lat() == 0.0 && gps.location.lng() == 0.0 && Config.beacon.latitude == 0.0 && Config.beacon.longitude == 0.0) {
GPS_Utils::getData();
beaconUpdate = false;
}
#endif
if (beaconUpdate) { if (beaconUpdate) {
display_toggle(true); if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
Utils::println("-- Sending Beacon to APRSIS --"); }
if (sendStartTelemetry && Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)) {
sendInitialTelemetryPackets();
}
STATION_Utils::deleteNotHeard(); STATION_Utils::deleteNotHeard();
activeStations(); activeStations();
if (Config.bme.active) { beaconPacket = iGateBeaconPacket;
String sensorData = BME_Utils::readDataSensor(); secondaryBeaconPacket = iGateLoRaBeaconPacket;
beaconPacket += sensorData; #ifdef HAS_GPS
secondaryBeaconPacket += sensorData; if (Config.beacon.gpsActive && !Config.digi.ecoMode) {
} GPS_Utils::getData();
beaconPacket += Config.beacon.comment; if (gps.location.isUpdated() && gps.location.lat() != 0.0 && gps.location.lng() != 0.0) {
secondaryBeaconPacket += Config.beacon.comment; GPS_Utils::generateBeaconFirstPart();
String encodedGPS = GPS_Utils::encodeGPS(gps.location.lat(), gps.location.lng(), Config.beacon.overlay, Config.beacon.symbol);
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_HTCT62) beaconPacket = iGateBeaconPacket + encodedGPS;
if (Config.sendBatteryVoltage) { secondaryBeaconPacket = iGateLoRaBeaconPacket + encodedGPS;
beaconPacket += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V"; }
secondaryBeaconPacket += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V"; }
sixthLine = " (Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V)";
}
#endif #endif
if (Config.externalVoltageMeasurement) { if (Config.wxsensor.active && wxModuleType != 0) {
beaconPacket += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V"; String sensorData = WX_Utils::readDataSensor();
secondaryBeaconPacket += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V"; beaconPacket += sensorData;
sixthLine = " (Ext V=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V)"; secondaryBeaconPacket += sensorData;
} else if (Config.wxsensor.active && wxModuleType == 0) {
beaconPacket += ".../...g...t...";
secondaryBeaconPacket += ".../...g...t...";
}
beaconPacket += Config.beacon.comment;
secondaryBeaconPacket += Config.beacon.comment;
#if defined(BATTERY_PIN) || defined(HAS_AXP192) || defined(HAS_AXP2101)
if (Config.battery.sendInternalVoltage || Config.battery.monitorInternalVoltage) {
float internalVoltage = BATTERY_Utils::checkInternalVoltage();
if (Config.battery.monitorInternalVoltage && internalVoltage < Config.battery.internalSleepVoltage) {
beaconPacket += " **IntBatWarning:SLEEP**";
secondaryBeaconPacket += " **IntBatWarning:SLEEP**";
shouldSleepLowVoltage = true;
}
String internalVoltageInfo = String(internalVoltage,2) + "V";
if (Config.battery.sendInternalVoltage) {
sixthLine = " (Batt=";
sixthLine += internalVoltageInfo;
sixthLine += ")";
if (!Config.battery.sendVoltageAsTelemetry) {
beaconPacket += " Batt=";
beaconPacket += internalVoltageInfo;
secondaryBeaconPacket += " Batt=";
secondaryBeaconPacket += internalVoltageInfo;
}
}
}
#endif
#ifndef HELTEC_WP
if (Config.battery.sendExternalVoltage || Config.battery.monitorExternalVoltage) {
float externalVoltage = BATTERY_Utils::checkExternalVoltage();
if (Config.battery.monitorExternalVoltage && externalVoltage < Config.battery.externalSleepVoltage) {
beaconPacket += " **ExtBatWarning:SLEEP**";
secondaryBeaconPacket += " **ExtBatWarning:SLEEP**";
shouldSleepLowVoltage = true;
}
String externalVoltageInfo = String(externalVoltage,2) + "V";
if (Config.battery.sendExternalVoltage) {
sixthLine = " (Ext V=";
sixthLine += externalVoltageInfo;
sixthLine += ")";
if (!Config.battery.sendVoltageAsTelemetry) {
beaconPacket += " Ext=";
beaconPacket += externalVoltageInfo;
secondaryBeaconPacket += " Ext=";
secondaryBeaconPacket += externalVoltageInfo;
}
}
}
#endif
if (Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)){
String encodedTelemetry = BATTERY_Utils::generateEncodedTelemetry();
beaconPacket += encodedTelemetry;
secondaryBeaconPacket += encodedTelemetry;
} }
if (Config.aprs_is.active && Config.beacon.sendViaAPRSIS) { if (Config.aprs_is.active && Config.beacon.sendViaAPRSIS && !backUpDigiMode) {
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0); Utils::println("-- Sending Beacon to APRSIS --");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING IGATE BEACON", 0);
seventhLine = " listening..."; seventhLine = " listening...";
#ifdef HAS_A7670
APRS_IS_Utils::upload(beaconPacket); A7670_Utils::uploadToAPRSIS(beaconPacket);
#else
APRS_IS_Utils::upload(beaconPacket);
#endif
} }
if (Config.beacon.sendViaRF) { if (Config.beacon.sendViaRF || backUpDigiMode) {
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0); Utils::println("-- Sending Beacon to RF --");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0);
seventhLine = " listening..."; seventhLine = " listening...";
STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket);
LoRa_Utils::sendNewPacket("APRS", secondaryBeaconPacket);
} }
lastBeaconTx = millis(); lastBeaconTx = millis();
@@ -156,61 +314,59 @@ namespace Utils {
void checkDisplayInterval() { void checkDisplayInterval() {
uint32_t lastDisplayTime = millis() - lastScreenOn; uint32_t lastDisplayTime = millis() - lastScreenOn;
if (!Config.display.alwaysOn) { if (!Config.display.alwaysOn && lastDisplayTime >= Config.display.timeout * 1000) {
if (lastDisplayTime >= Config.display.timeout*1000) { displayToggle(false);
display_toggle(false);
}
}
}
void checkWiFiInterval() {
uint32_t WiFiCheck = millis() - lastWiFiCheck;
if (WiFi.status() != WL_CONNECTED && WiFiCheck >= 15*60*1000) {
WiFiConnect = true;
}
if (WiFiConnect) {
Serial.println("\nConnecting to WiFi ...");
WIFI_Utils::startWiFi();
lastWiFiCheck = millis();
WiFiConnect = false;
} }
} }
void validateFreqs() { void validateFreqs() {
if (Config.loramodule.txFreq != Config.loramodule.rxFreq && abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) < 125000) { if (Config.loramodule.txFreq != Config.loramodule.rxFreq && abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) < 125000) {
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID"); Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID");
show_display("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000); displayShow("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000);
Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device
Config.writeFile(); Config.writeFile();
ESP.restart(); ESP.restart();
} }
} }
void typeOfPacket(String packet, String packetType) { void typeOfPacket(const String& packet, const uint8_t packetType) {
String sender; String sender = packet.substring(0,packet.indexOf(">"));
if (packetType == "LoRa-APRS") { switch (packetType) {
fifthLine = "LoRa Rx ----> APRS-IS"; case 0: // LoRa-APRS
sender = packet.substring(0,packet.indexOf(">")); fifthLine = "LoRa Rx ----> APRS-IS";
} else if (packetType == "APRS-LoRa") { break;
fifthLine = "APRS-IS ----> LoRa Tx"; case 1: // APRS-LoRa
sender = packet.substring(0,packet.indexOf(">")); fifthLine = "APRS-IS ----> LoRa Tx";
} else if (packetType == "Digi") { break;
fifthLine = "LoRa Rx ----> LoRa Tx"; case 2: // Digi
sender = packet.substring(0,packet.indexOf(">")); fifthLine = "LoRa Rx ----> LoRa Tx";
break;
} }
for (int i = sender.length(); i < 9; i++) { for (int i = sender.length(); i < 9; i++) {
sender += " "; sender += " ";
} }
if (packet.indexOf("::") >= 10) { sixthLine = sender;
sixthLine = sender + "> MESSAGE"; String seventhLineHelper = "RSSI:";
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm"; seventhLineHelper += String(rssi);
} else if (packet.indexOf(":>") >= 10) { seventhLineHelper += "dBm SNR: ";
sixthLine = sender + "> NEW STATUS"; seventhLineHelper += String(snr);
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm"; seventhLineHelper += "dBm";
} else if (packet.indexOf(":!") >= 10 || packet.indexOf(":=") >= 10) {
sixthLine = sender + "> GPS BEACON"; int firstColonIndex = packet.indexOf(":");
GPS_Utils::getDistance(packet); if (packet[firstColonIndex + 1] == ':') {
seventhLine = "RSSI:" + String(rssi) + "dBm"; sixthLine += "> MESSAGE";
seventhLine = seventhLineHelper;
} else if (packet[firstColonIndex + 1] == '>') {
sixthLine += "> NEW STATUS";
seventhLine = seventhLineHelper;
} else if (packet[firstColonIndex + 1] == '!' || packet[firstColonIndex + 1] == '=' || packet[firstColonIndex + 1] == '@') {
sixthLine += "> GPS BEACON";
if (!Config.syslog.active) {
GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
}
seventhLine = "RSSI:";
seventhLine += String(rssi);
seventhLine += "dBm";
if (rssi <= -100) { if (rssi <= -100) {
seventhLine += " "; seventhLine += " ";
} else { } else {
@@ -219,32 +375,114 @@ namespace Utils {
if (distance.indexOf(".") == 1) { if (distance.indexOf(".") == 1) {
seventhLine += " "; seventhLine += " ";
} }
seventhLine += "D:" + distance + "km"; seventhLine += "D:";
seventhLine += distance;
seventhLine += "km";
} else if (packet[firstColonIndex + 1] == '`' || packet[firstColonIndex + 1] == '\'') {
sixthLine += "> MIC-E";
seventhLine = seventhLineHelper;
} else if (packet[firstColonIndex + 1] == ';') {
sixthLine += "> OBJECT";
seventhLine = seventhLineHelper;
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) { } else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
sixthLine = sender + "> TELEMETRY"; sixthLine += "> TELEMETRY";
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm"; seventhLine = seventhLineHelper;
} else if (packet.indexOf(":`") >= 10) {
sixthLine = sender + "> MIC-E";
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm";
} else if (packet.indexOf(":;") >= 10) {
sixthLine = sender + "> OBJECT";
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm";
} else { } else {
sixthLine = sender + "> ??????????"; sixthLine += "> ??????????";
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm"; seventhLine = seventhLineHelper;
} }
} }
void print(String text) { void print(const String& text) {
if (!Config.tnc.enableSerial) { if (!Config.tnc.enableSerial) {
Serial.print(text); Serial.print(text);
} }
} }
void println(String text) { void println(const String& text) {
if (!Config.tnc.enableSerial) { if (!Config.tnc.enableSerial) {
Serial.println(text); Serial.println(text);
} }
} }
void checkRebootMode() {
if (Config.rebootMode && Config.rebootModeTime > 0) {
Serial.println("(Reboot Time Set to " + String(Config.rebootModeTime) + " hours)");
}
}
void checkRebootTime() {
if (Config.rebootMode && Config.rebootModeTime > 0) {
if (millis() > Config.rebootModeTime * 60 * 60 * 1000) {
Serial.println("\n*** Automatic Reboot Time Restart! ****\n");
ESP.restart();
}
}
}
void checkSleepByLowBatteryVoltage(uint8_t mode) {
if (shouldSleepLowVoltage) {
if (mode == 0) { // at startup
delay(3000);
}
Serial.println("\n\n*** Sleeping Low Battey Voltage ***\n\n");
esp_sleep_enable_timer_wakeup(30 * 60 * 1000000); // sleep 30 min
if (mode == 1) { // low voltage detected after a while
displayToggle(false);
}
#ifdef VEXT_CTRL
#ifndef HELTEC_WSL_V3
digitalWrite(VEXT_CTRL, LOW);
#endif
#endif
LoRa_Utils::sleepRadio();
transmitFlag = true;
delay(100);
esp_deep_sleep_start();
}
}
bool checkValidCallsign(const String& callsign) {
if (callsign == "WLNK-1") return true;
String cleanCallsign;
if (callsign.indexOf("-") > 0) { // SSID Validation
cleanCallsign = callsign.substring(0, callsign.indexOf("-"));
String ssid = callsign.substring(callsign.indexOf("-") + 1);
if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
for (int i = 0; i < ssid.length(); i++) {
if (!isAlphaNumeric(ssid[i])) return false;
}
} else {
cleanCallsign = callsign;
}
if (cleanCallsign.length() < 4 || cleanCallsign.length() > 6) return false;
if (cleanCallsign.length() < 6 && isAlpha(cleanCallsign[0]) && isDigit(cleanCallsign[1]) && isAlpha(cleanCallsign[2]) && isAlpha(cleanCallsign[3]) ) {
cleanCallsign = " " + cleanCallsign; // A0AA --> _A0AA
}
if (!isDigit(cleanCallsign[2]) || !isAlpha(cleanCallsign[3])) { // __0A__ must be validated
if (cleanCallsign[0] != 'R' && !isDigit(cleanCallsign[1]) && !isAlpha(cleanCallsign[2])) return false; // to accepto R0A___
}
bool isValid = false;
if ((isAlphaNumeric(cleanCallsign[0]) || cleanCallsign[0] == ' ') && isAlpha(cleanCallsign[1])) {
isValid = true; // AA0A (+A+A) + _A0AA (+A) + 0A0A (+A+A)
} else if (isAlpha(cleanCallsign[0]) && isDigit(cleanCallsign[1])) {
isValid = true; // A00A (+A+A)
} else if (cleanCallsign[0] == 'R' && cleanCallsign.length() == 6 && isDigit(cleanCallsign[1]) && isAlpha(cleanCallsign[2]) && isAlpha(cleanCallsign[3]) && isAlpha(cleanCallsign[4])) {
isValid = true; // R0AA (+A+A)
}
if (!isValid) return false; // also 00__ avoided
if (cleanCallsign.length() > 4) { // to validate ____AA
for (int i = 5; i <= cleanCallsign.length(); i++) {
if (!isAlpha(cleanCallsign[i - 1])) return false;
}
}
return true;
}
} }
+16 -13
View File
@@ -5,25 +5,28 @@
class ReceivedPacket { class ReceivedPacket {
public: public:
long millis; String rxTime;
String packet; String packet;
int RSSI; int RSSI;
float SNR; float SNR;
}; };
namespace Utils { namespace Utils {
void processStatus(); void processStatus();
String getLocalIP(); String getLocalIP();
void setupDisplay(); void setupDisplay();
void activeStations(); void activeStations();
void checkBeaconInterval(); void checkBeaconInterval();
void checkDisplayInterval(); void checkDisplayInterval();
void checkWiFiInterval(); void validateFreqs();
void validateFreqs(); void typeOfPacket(const String& packet, const uint8_t packetType);
void typeOfPacket(String packet, String packetType); void print(const String& text);
void print(String text); void println(const String& text);
void println(String text); void checkRebootMode();
void checkRebootTime();
void checkSleepByLowBatteryVoltage(uint8_t mode);
bool checkValidCallsign(const String& callsign);
} }
+131 -97
View File
@@ -2,10 +2,10 @@
#include "configuration.h" #include "configuration.h"
#include "ota_utils.h" #include "ota_utils.h"
#include "web_utils.h" #include "web_utils.h"
#include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastBeaconTx; extern uint32_t lastBeaconTx;
extern std::vector<ReceivedPacket> receivedPackets; extern std::vector<ReceivedPacket> receivedPackets;
@@ -29,6 +29,10 @@ extern const char web_bootstrap_js[] asm("_binary_data_embed_bootstrap_js_gz_sta
extern const char web_bootstrap_js_end[] asm("_binary_data_embed_bootstrap_js_gz_end"); extern const char web_bootstrap_js_end[] asm("_binary_data_embed_bootstrap_js_gz_end");
extern const size_t web_bootstrap_js_len = web_bootstrap_js_end - web_bootstrap_js; extern const size_t web_bootstrap_js_len = web_bootstrap_js_end - web_bootstrap_js;
// Declare external symbols for the embedded image data
extern const unsigned char favicon_data[] asm("_binary_data_embed_favicon_png_gz_start");
extern const unsigned char favicon_data_end[] asm("_binary_data_embed_favicon_png_gz_end");
extern const size_t favicon_data_len = favicon_data_end - favicon_data;
namespace WEB_Utils { namespace WEB_Utils {
@@ -45,12 +49,24 @@ namespace WEB_Utils {
} }
void handleHome(AsyncWebServerRequest *request) { void handleHome(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", (const uint8_t*)web_index_html, web_index_html_len); if(Config.webadmin.active && !request->authenticate(Config.webadmin.username.c_str(), Config.webadmin.password.c_str()))
return request->requestAuthentication();
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", (const uint8_t*)web_index_html, web_index_html_len);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
}
void handleFavicon(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse(200, "image/x-icon", (const uint8_t*)favicon_data, favicon_data_len);
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
} }
void handleReadConfiguration(AsyncWebServerRequest *request) { void handleReadConfiguration(AsyncWebServerRequest *request) {
if(Config.webadmin.active && !request->authenticate(Config.webadmin.username.c_str(), Config.webadmin.password.c_str()))
return request->requestAuthentication();
File file = SPIFFS.open("/igate_conf.json"); File file = SPIFFS.open("/igate_conf.json");
String fileContent; String fileContent;
@@ -65,10 +81,10 @@ namespace WEB_Utils {
StaticJsonDocument<1536> data; StaticJsonDocument<1536> data;
for (int i = 0; i < receivedPackets.size(); i++) { for (int i = 0; i < receivedPackets.size(); i++) {
data[i]["millis"] = receivedPackets[i].millis; data[i]["rxTime"] = receivedPackets[i].rxTime;
data[i]["packet"] = receivedPackets[i].packet; data[i]["packet"] = receivedPackets[i].packet;
data[i]["RSSI"] = receivedPackets[i].RSSI; data[i]["RSSI"] = receivedPackets[i].RSSI;
data[i]["SNR"] = receivedPackets[i].SNR; data[i]["SNR"] = receivedPackets[i].SNR;
} }
String buffer; String buffer;
@@ -89,106 +105,120 @@ namespace WEB_Utils {
WiFi_AP wifiap; WiFi_AP wifiap;
wifiap.ssid = request->getParam("wifi.AP." + String(i) + ".ssid", true)->value(); wifiap.ssid = request->getParam("wifi.AP." + String(i) + ".ssid", true)->value();
wifiap.password = request->getParam("wifi.AP." + String(i) + ".password", true)->value(); wifiap.password = request->getParam("wifi.AP." + String(i) + ".password", true)->value();
// wifiap.latitude = request->getParam("wifi.AP." + String(i) + ".latitude", true)->value().toDouble();
// wifiap.longitude = request->getParam("wifi.AP." + String(i) + ".longitude", true)->value().toDouble();
Config.wifiAPs.push_back(wifiap); Config.wifiAPs.push_back(wifiap);
} }
Config.callsign = request->getParam("callsign", true)->value(); Config.callsign = request->getParam("callsign", true)->value();
// Config.iGateComment = request->getParam("iGateComment", true)->value();
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
Config.wifiAutoAP.timeout = request->getParam("wifi.autoAP.timeout", true)->value().toInt();
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
Config.wifiAutoAP.powerOff = request->getParam("wifi.autoAP.powerOff", true)->value().toInt();
Config.digi.mode = request->getParam("digi.mode", true)->value().toInt(); Config.aprs_is.active = request->hasParam("aprs_is.active", true);
// Config.digi.comment = request->getParam("digi.comment", true)->value(); Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
// Config.digi.latitude = request->getParam("digi.latitude", true)->value().toDouble(); Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
// Config.digi.longitude = request->getParam("digi.longitude", true)->value().toDouble(); Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value();
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
Config.aprs_is.active = request->hasParam("aprs_is.active", true); Config.beacon.interval = request->getParam("beacon.interval", true)->value().toInt();
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value(); Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value(); Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true);
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt(); Config.beacon.latitude = request->getParam("beacon.latitude", true)->value().toDouble();
// Config.aprs_is.reportingDistance = request->getParam("aprs_is.reportingDistance", true)->value().toInt(); Config.beacon.longitude = request->getParam("beacon.longitude", true)->value().toDouble();
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value(); Config.beacon.comment = request->getParam("beacon.comment", true)->value();
Config.aprs_is.toRF = request->hasParam("aprs_is.toRF", true); Config.beacon.overlay = request->getParam("beacon.overlay", true)->value();
Config.beacon.symbol = request->getParam("beacon.symbol", true)->value();
Config.beacon.path = request->getParam("beacon.path", true)->value();
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
// Config.loramodule.iGateFreq = request->getParam("lora.iGateFreq", true)->value().toInt();
// if (request->hasParam("lora.digirepeaterTxFreq", true)) {
// Config.loramodule.digirepeaterTxFreq = request->getParam("lora.digirepeaterTxFreq", true)->value().toInt();
// }
// if (request->hasParam("lora.digirepeaterRxFreq", true)) {
// Config.loramodule.digirepeaterRxFreq = request->getParam("lora.digirepeaterRxFreq", true)->value().toInt();
// }
Config.loramodule.txFreq = request->getParam("lora.txFreq", true)->value().toInt(); Config.digi.mode = request->getParam("digi.mode", true)->value().toInt();
Config.loramodule.rxFreq = request->getParam("lora.rxFreq", true)->value().toInt(); Config.digi.ecoMode = request->hasParam("digi.ecoMode", true);
Config.loramodule.spreadingFactor = request->getParam("lora.spreadingFactor", true)->value().toInt();
Config.loramodule.signalBandwidth = request->getParam("lora.signalBandwidth", true)->value().toInt();
Config.loramodule.codingRate4 = request->getParam("lora.codingRate4", true)->value().toInt();
Config.loramodule.power = request->getParam("lora.power", true)->value().toInt();
Config.loramodule.txActive = request->hasParam("lora.txActive", true);
Config.loramodule.rxActive = request->hasParam("lora.rxActive", true);
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
Config.loramodule.txFreq = request->getParam("lora.txFreq", true)->value().toInt();
Config.loramodule.rxFreq = request->getParam("lora.rxFreq", true)->value().toInt();
Config.loramodule.spreadingFactor = request->getParam("lora.spreadingFactor", true)->value().toInt();
Config.loramodule.signalBandwidth = request->getParam("lora.signalBandwidth", true)->value().toInt();
Config.loramodule.codingRate4 = request->getParam("lora.codingRate4", true)->value().toInt();
Config.loramodule.power = request->getParam("lora.power", true)->value().toInt();
Config.loramodule.txActive = request->hasParam("lora.txActive", true);
Config.loramodule.rxActive = request->hasParam("lora.rxActive", true);
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
if (!Config.display.alwaysOn) { if (!Config.display.alwaysOn) {
Config.display.timeout = request->getParam("display.timeout", true)->value().toInt(); Config.display.timeout = request->getParam("display.timeout", true)->value().toInt();
} }
Config.display.turn180 = request->hasParam("display.turn180", true);
Config.display.turn180 = request->hasParam("display.turn180", true);
Config.syslog.active = request->hasParam("syslog.active", true); Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat();
if (Config.syslog.active) { Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true);
Config.syslog.server = request->getParam("syslog.server", true)->value(); if (Config.battery.sendExternalVoltage) {
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt(); Config.battery.externalVoltagePin = request->getParam("battery.externalVoltagePin", true)->value().toInt();
Config.battery.voltageDividerR1 = request->getParam("battery.voltageDividerR1", true)->value().toFloat();
Config.battery.voltageDividerR2 = request->getParam("battery.voltageDividerR2", true)->value().toFloat();
} }
Config.battery.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true);
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
Config.bme.active = request->hasParam("bme.active", true); Config.battery.sendVoltageAsTelemetry = request->hasParam("battery.sendVoltageAsTelemetry", true);
Config.ota.username = request->getParam("ota.username", true)->value(); Config.wxsensor.active = request->hasParam("wxsensor.active", true);
Config.ota.password = request->getParam("ota.password", true)->value(); Config.wxsensor.heightCorrection = request->getParam("wxsensor.heightCorrection", true)->value().toInt();
Config.wxsensor.temperatureCorrection = request->getParam("wxsensor.temperatureCorrection", true)->value().toFloat();
Config.beacon.interval = request->getParam("beacon.interval", true)->value().toInt(); if (Config.wxsensor.active) {
Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true);
Config.beacon.latitude = request->getParam("beacon.latitude", true)->value().toDouble();
Config.beacon.longitude = request->getParam("beacon.longitude", true)->value().toDouble();
Config.beacon.comment = request->getParam("beacon.comment", true)->value();
Config.beacon.overlay = request->getParam("beacon.overlay", true)->value();
Config.beacon.symbol = request->getParam("beacon.symbol", true)->value();
Config.beacon.path = request->getParam("beacon.path", true)->value();
// Config.beaconInterval = request->getParam("other.beaconInterval", true)->value().toInt();
// Config.igateSendsLoRaBeacons = request->hasParam("other.igateSendsLoRaBeacons", true);
// Config.igateRepeatsLoRaPackets = request->hasParam("other.igateRepeatsLoRaPackets", true);
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
Config.sendBatteryVoltage = request->hasParam("other.sendBatteryVoltage", true);
Config.externalVoltageMeasurement = request->hasParam("other.externalVoltageMeasurement", true);
if (Config.externalVoltageMeasurement) {
Config.externalVoltagePin = request->getParam("other.externalVoltagePin", true)->value().toInt();
}
Config.lowPowerMode = request->hasParam("other.lowPowerMode", true);
Config.lowVoltageCutOff = request->getParam("other.lowVoltageCutOff", true)->value().toDouble();
if (Config.bme.active) {
Config.beacon.symbol = "_"; Config.beacon.symbol = "_";
} }
Config.syslog.active = request->hasParam("syslog.active", true);
if (Config.syslog.active) {
Config.syslog.server = request->getParam("syslog.server", true)->value();
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
}
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
Config.rebootMode = request->hasParam("other.rebootMode", true);
Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt();
Config.ota.username = request->getParam("ota.username", true)->value();
Config.ota.password = request->getParam("ota.password", true)->value();
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
Config.lowPowerMode = request->hasParam("other.lowPowerMode", true);
Config.lowVoltageCutOff = request->getParam("other.lowVoltageCutOff", true)->value().toDouble();
Config.personalNote = request->getParam("personalNote", true)->value();
Config.webadmin.active = request->hasParam("webadmin.active", true);
if (Config.webadmin.active) {
Config.webadmin.username = request->getParam("webadmin.username", true)->value();
Config.webadmin.password = request->getParam("webadmin.password", true)->value();
}
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toInt();
Config.writeFile(); Config.writeFile();
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", ""); AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
response->addHeader("Location", "/"); response->addHeader("Location", "/");
request->send(response); request->send(response);
displayToggle(false);
ESP.restart(); ESP.restart();
} }
@@ -200,6 +230,7 @@ namespace WEB_Utils {
request->send(200, "text/plain", "Beacon will be sent in a while"); request->send(200, "text/plain", "Beacon will be sent in a while");
} else if (type == "reboot") { } else if (type == "reboot") {
displayToggle(false);
ESP.restart(); ESP.restart();
} else { } else {
request->send(404, "text/plain", "Not Found"); request->send(404, "text/plain", "Not Found");
@@ -207,48 +238,51 @@ namespace WEB_Utils {
} }
void handleStyle(AsyncWebServerRequest *request) { void handleStyle(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", (const uint8_t*)web_style_css, web_style_css_len); AsyncWebServerResponse *response = request->beginResponse(200, "text/css", (const uint8_t*)web_style_css, web_style_css_len);
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
} }
void handleScript(AsyncWebServerRequest *request) { void handleScript(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/javascript", (const uint8_t*)web_script_js, web_script_js_len); AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", (const uint8_t*)web_script_js, web_script_js_len);
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
} }
void handleBootstrapStyle(AsyncWebServerRequest *request) { void handleBootstrapStyle(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", (const uint8_t*)web_bootstrap_css, web_bootstrap_css_len); AsyncWebServerResponse *response = request->beginResponse(200, "text/css", (const uint8_t*)web_bootstrap_css, web_bootstrap_css_len);
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", "max-age=3600"); response->addHeader("Cache-Control", "max-age=3600");
request->send(response); request->send(response);
} }
void handleBootstrapScript(AsyncWebServerRequest *request) { void handleBootstrapScript(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/javascript", (const uint8_t*)web_bootstrap_js, web_bootstrap_js_len); AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", (const uint8_t*)web_bootstrap_js, web_bootstrap_js_len);
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", "max-age=3600"); response->addHeader("Cache-Control", "max-age=3600");
request->send(response); request->send(response);
} }
void setup() { void setup() {
server.on("/", HTTP_GET, handleHome); if (!Config.digi.ecoMode) {
server.on("/status", HTTP_GET, handleStatus); server.on("/", HTTP_GET, handleHome);
server.on("/received-packets.json", HTTP_GET, handleReceivedPackets); server.on("/status", HTTP_GET, handleStatus);
server.on("/configuration.json", HTTP_GET, handleReadConfiguration); server.on("/received-packets.json", HTTP_GET, handleReceivedPackets);
server.on("/configuration.json", HTTP_POST, handleWriteConfiguration); server.on("/configuration.json", HTTP_GET, handleReadConfiguration);
server.on("/action", HTTP_POST, handleAction); server.on("/configuration.json", HTTP_POST, handleWriteConfiguration);
server.on("/style.css", HTTP_GET, handleStyle); server.on("/action", HTTP_POST, handleAction);
server.on("/script.js", HTTP_GET, handleScript); server.on("/style.css", HTTP_GET, handleStyle);
server.on("/bootstrap.css", HTTP_GET, handleBootstrapStyle); server.on("/script.js", HTTP_GET, handleScript);
server.on("/bootstrap.js", HTTP_GET, handleBootstrapScript); server.on("/bootstrap.css", HTTP_GET, handleBootstrapStyle);
server.on("/bootstrap.js", HTTP_GET, handleBootstrapScript);
server.on("/favicon.png", HTTP_GET, handleFavicon);
OTA_Utils::setup(&server); // Include OTA Updater for WebServer OTA_Utils::setup(&server); // Include OTA Updater for WebServer
server.onNotFound(handleNotFound); server.onNotFound(handleNotFound);
server.begin(); server.begin();
}
} }
} }
+65 -32
View File
@@ -1,29 +1,58 @@
#include <WiFi.h> #include <WiFi.h>
#include "configuration.h" #include "configuration.h"
#include "pins_config.h" #include "boards_pinout.h"
#include "wifi_utils.h" #include "wifi_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern WiFi_AP *currentWiFi;
extern uint8_t myWiFiAPIndex; extern uint8_t myWiFiAPIndex;
extern int myWiFiAPSize; extern int myWiFiAPSize;
extern uint32_t previousWiFiMillis; extern WiFi_AP *currentWiFi;
extern bool WiFiConnected; extern bool backUpDigiMode;
extern long WiFiAutoAPTime;
extern bool WiFiAutoAPStarted; bool WiFiConnected = false;
uint32_t WiFiAutoAPTime = millis();
bool WiFiAutoAPStarted = false;
uint32_t previousWiFiMillis = 0;
uint8_t wifiCounter = 0;
uint32_t lastBackupDigiTime = millis();
namespace WIFI_Utils { namespace WIFI_Utils {
void checkWiFi() { void checkWiFi() {
if ((WiFi.status() != WL_CONNECTED) && ((millis() - previousWiFiMillis) >= 30*1000) && !WiFiAutoAPStarted) { if (!Config.digi.ecoMode) {
Serial.print(millis()); if (backUpDigiMode) {
Serial.println("Reconnecting to WiFi..."); uint32_t WiFiCheck = millis() - lastBackupDigiTime;
WiFi.disconnect(); if (WiFi.status() != WL_CONNECTED && WiFiCheck >= 15 * 60 * 1000) {
WiFi.reconnect(); Serial.println("*** Stoping BackUp Digi Mode ***");
previousWiFiMillis = millis(); backUpDigiMode = false;
wifiCounter = 0;
} else if (WiFi.status() == WL_CONNECTED) {
Serial.println("*** WiFi Reconnect Success (Stoping Backup Digi Mode) ***");
backUpDigiMode = false;
wifiCounter = 0;
}
}
if (!backUpDigiMode && (WiFi.status() != WL_CONNECTED) && ((millis() - previousWiFiMillis) >= 30 * 1000) && !WiFiAutoAPStarted) {
Serial.print(millis());
Serial.println("Reconnecting to WiFi...");
WiFi.disconnect();
WIFI_Utils::startWiFi();//WiFi.reconnect();
previousWiFiMillis = millis();
if (Config.backupDigiMode) {
wifiCounter++;
}
if (wifiCounter >= 2) {
Serial.println("*** Starting BackUp Digi Mode ***");
backUpDigiMode = true;
lastBackupDigiTime = millis();
}
}
} }
} }
@@ -31,7 +60,7 @@ namespace WIFI_Utils {
WiFi.mode(WIFI_MODE_NULL); WiFi.mode(WIFI_MODE_NULL);
WiFi.mode(WIFI_AP); WiFi.mode(WIFI_AP);
WiFi.softAP(Config.callsign + " AP", Config.wifiAutoAP.password); WiFi.softAP(Config.callsign + "-AP", Config.wifiAutoAP.password);
WiFiAutoAPTime = millis(); WiFiAutoAPTime = millis();
WiFiAutoAPStarted = true; WiFiAutoAPStarted = true;
@@ -43,22 +72,24 @@ namespace WIFI_Utils {
startAP = true; startAP = true;
} else { } else {
uint8_t wifiCounter = 0; uint8_t wifiCounter = 0;
String hostName = "iGATE-" + Config.callsign;
WiFi.setHostname(hostName.c_str());
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
WiFi.disconnect(); WiFi.disconnect();
delay(500); delay(500);
unsigned long start = millis(); unsigned long start = millis();
show_display("", "", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0); displayShow("", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0);
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ..."); Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str()); WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
while (WiFi.status() != WL_CONNECTED && wifiCounter<myWiFiAPSize) { while (WiFi.status() != WL_CONNECTED && wifiCounter<myWiFiAPSize) {
delay(500); delay(500);
#ifdef HAS_INTERNAL_LED #ifdef INTERNAL_LED_PIN
digitalWrite(internalLedPin,HIGH); digitalWrite(INTERNAL_LED_PIN,HIGH);
#endif #endif
Serial.print('.'); Serial.print('.');
delay(500); delay(500);
#ifdef HAS_INTERNAL_LED #ifdef INTERNAL_LED_PIN
digitalWrite(internalLedPin,LOW); digitalWrite(INTERNAL_LED_PIN,LOW);
#endif #endif
if ((millis() - start) > 10000){ if ((millis() - start) > 10000){
delay(1000); delay(1000);
@@ -72,42 +103,44 @@ namespace WIFI_Utils {
currentWiFi = &Config.wifiAPs[myWiFiAPIndex]; currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
start = millis(); start = millis();
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ..."); Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
show_display("", "", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0); displayShow("", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0);
WiFi.disconnect(); WiFi.disconnect();
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str()); WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
} }
} }
} }
#ifdef HAS_INTERNAL_LED #ifdef INTERNAL_LED_PIN
digitalWrite(internalLedPin,LOW); digitalWrite(INTERNAL_LED_PIN,LOW);
#endif #endif
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
Serial.print("Connected as "); Serial.print("Connected as ");
Serial.println(WiFi.localIP()); Serial.print(WiFi.localIP());
show_display("", "", " Connected!!", "" , " loading ...", 1000); Serial.print(" / MAC Address: ");
Serial.println(WiFi.macAddress());
displayShow("", " Connected!!", "" , " loading ...", 1000);
} else if (WiFi.status() != WL_CONNECTED) { } else if (WiFi.status() != WL_CONNECTED) {
startAP = true; startAP = true;
Serial.println("\nNot connected to WiFi! Starting Auto AP"); Serial.println("\nNot connected to WiFi! Starting Auto AP");
show_display("", "", " WiFi Not Connected!", "" , " loading ...", 1000); displayShow("", " WiFi Not Connected!", "" , " loading ...", 1000);
} }
WiFiConnected = !startAP; WiFiConnected = !startAP;
if (startAP) { if (startAP) {
Serial.println("\nNot connected to WiFi! Starting Auto AP"); Serial.println("\nNot connected to WiFi! Starting Auto AP");
show_display("", "", " Starting Auto AP", " Please connect to it " , " loading ...", 1000); displayShow("", " Starting Auto AP", " Please connect to it " , " loading ...", 1000);
startAutoAP(); startAutoAP();
} }
} }
void checkIfAutoAPShouldPowerOff() { void checkAutoAPTimeout() {
if (WiFiAutoAPStarted && Config.wifiAutoAP.powerOff > 0) { if (WiFiAutoAPStarted && Config.wifiAutoAP.timeout > 0) {
if (WiFi.softAPgetStationNum() > 0) { if (WiFi.softAPgetStationNum() > 0) {
WiFiAutoAPTime = 0; WiFiAutoAPTime = 0;
} else { } else {
if (WiFiAutoAPTime == 0) { if (WiFiAutoAPTime == 0) {
WiFiAutoAPTime = millis(); WiFiAutoAPTime = millis();
} else if ((millis() - WiFiAutoAPTime) > Config.wifiAutoAP.powerOff * 60 * 1000) { } else if ((millis() - WiFiAutoAPTime) > Config.wifiAutoAP.timeout * 60 * 1000) {
Serial.println("Stopping auto AP"); Serial.println("Stopping auto AP");
WiFiAutoAPStarted = false; WiFiAutoAPStarted = false;
@@ -120,7 +153,7 @@ namespace WIFI_Utils {
} }
void setup() { void setup() {
startWiFi(); if (!Config.digi.ecoMode) startWiFi();
btStop(); btStop();
} }
+1 -1
View File
@@ -9,7 +9,7 @@ namespace WIFI_Utils {
void checkWiFi(); void checkWiFi();
void startAutoAP(); void startAutoAP();
void startWiFi(); void startWiFi();
void checkIfAutoAPShouldPowerOff(); void checkAutoAPTimeout();
void setup(); void setup();
} }
+261
View File
@@ -0,0 +1,261 @@
#include "configuration.h"
#include "wx_utils.h"
#include "display.h"
#define SEALEVELPRESSURE_HPA (1013.25)
#define CORRECTION_FACTOR (8.2296) // for meters
extern Configuration Config;
extern String fifthLine;
int wxModuleType = 0;
uint8_t wxModuleAddress = 0x00;
float newHum, newTemp, newPress, newGas;
Adafruit_BME280 bme280;
#ifdef HELTEC_V3
Adafruit_BMP280 bmp280(&Wire1);
Adafruit_Si7021 sensor = Adafruit_Si7021();
#else
Adafruit_BMP280 bmp280;
Adafruit_BME680 bme680;
Adafruit_Si7021 sensor = Adafruit_Si7021();
#endif
namespace WX_Utils {
void getWxModuleAddres() {
uint8_t err, addr;
for(addr = 1; addr < 0x7F; addr++) {
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
Wire1.beginTransmission(addr);
err = Wire1.endTransmission();
#else
Wire.beginTransmission(addr);
err = Wire.endTransmission();
#endif
if (err == 0) {
//Serial.println(addr); this shows any connected board to I2C
if (addr == 0x76 || addr == 0x77) { // BME/BMP
wxModuleAddress = addr;
return;
} else if (addr == 0x40) { // Si7011
wxModuleAddress = addr;
return;
}
}
}
}
void setup() {
if (Config.wxsensor.active) {
getWxModuleAddres();
if (wxModuleAddress != 0x00) {
bool wxModuleFound = false;
if (wxModuleAddress == 0x76 || wxModuleAddress == 0x77) {
#if defined(HELTEC_V3) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
if (bme280.begin(wxModuleAddress, &Wire1)) {
Serial.println("BME280 sensor found");
wxModuleType = 1;
wxModuleFound = true;
}
#else
if (bme280.begin(wxModuleAddress)) {
Serial.println("BME280 sensor found");
wxModuleType = 1;
wxModuleFound = true;
}
if (!wxModuleFound) {
if (bme680.begin(wxModuleAddress)) {
Serial.println("BME680 sensor found");
wxModuleType = 3;
wxModuleFound = true;
}
}
#endif
if (!wxModuleFound) {
if (bmp280.begin(wxModuleAddress)) {
Serial.println("BMP280 sensor found");
wxModuleType = 2;
wxModuleFound = true;
}
}
} else if (wxModuleAddress == 0x40) {
if(sensor.begin()) {
Serial.println("Si7021 sensor found");
wxModuleType = 4;
wxModuleFound = true;
}
}
if (!wxModuleFound) {
displayShow("ERROR", "", "BME/BMP/Si7021 sensor active", "but no sensor found...", 2000);
Serial.println("BME/BMP/Si7021 sensor Active in config but not found! Check Wiring");
} else {
switch (wxModuleType) {
case 1:
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::FILTER_OFF
);
Serial.println("BME280 Module init done!");
break;
case 2:
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1,
Adafruit_BMP280::SAMPLING_X1,
Adafruit_BMP280::FILTER_OFF
);
Serial.println("BMP280 Module init done!");
break;
case 3:
#ifndef HELTEC_V3
bme680.setTemperatureOversampling(BME680_OS_1X);
bme680.setHumidityOversampling(BME680_OS_1X);
bme680.setPressureOversampling(BME680_OS_1X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_0);
Serial.println("BMP680 Module init done!");
#endif
break;
}
}
}
}
}
String generateTempString(const float sensorTemp) {
String strTemp = String((int)sensorTemp);
switch (strTemp.length()) {
case 1:
return "00" + strTemp;
case 2:
return "0" + strTemp;
case 3:
return strTemp;
default:
return "-999";
}
}
String generateHumString(const float sensorHum) {
String strHum = String((int)sensorHum);
switch (strHum.length()) {
case 1:
return "0" + strHum;
case 2:
return strHum;
case 3:
if ((int)sensorHum == 100) {
return "00";
} else {
return "-99";
}
default:
return "-99";
}
}
String generatePresString(const float sensorPres) {
String strPress = String((int)sensorPres);
String decPress = String(int((sensorPres - int(sensorPres)) * 10));
switch (strPress.length()) {
case 1:
return "000" + strPress + decPress;
case 2:
return "00" + strPress + decPress;
case 3:
return "0" + strPress + decPress;
case 4:
return strPress + decPress;
case 5:
return strPress;
default:
return "-99999";
}
}
String readDataSensor() {
switch (wxModuleType) {
case 1: // BME280
bme280.takeForcedMeasurement();
newTemp = bme280.readTemperature();
newPress = (bme280.readPressure() / 100.0F);
newHum = bme280.readHumidity();
break;
case 2: // BMP280
bmp280.takeForcedMeasurement();
newTemp = bmp280.readTemperature();
newPress = (bmp280.readPressure() / 100.0F);
newHum = 0;
break;
case 3: // BME680
#ifndef HELTEC_V3
bme680.performReading();
delay(50);
if (bme680.endReading()) {
newTemp = bme680.temperature;
newPress = (bme680.pressure / 100.0F);
newHum = bme680.humidity;
newGas = bme680.gas_resistance / 1000.0; // in Kilo ohms
}
#endif
break;
case 4: // Si7021
newTemp = sensor.readTemperature();
newPress = 0;
newHum = sensor.readHumidity();
break;
}
if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
Serial.println("BME/BMP/Si7021 Module data failed");
fifthLine = "";
return ".../...g...t...";
} else {
String tempStr = generateTempString(((newTemp + Config.wxsensor.temperatureCorrection) * 1.8) + 32);
String humStr;
if (wxModuleType == 1 || wxModuleType == 3 || wxModuleType == 4) {
humStr = generateHumString(newHum);
} else if (wxModuleType == 2) {
humStr = "..";
}
String presStr;
if (wxModuleAddress == 4) {
presStr = ".....";
} else {
presStr = generatePresString(newPress + (Config.wxsensor.heightCorrection/CORRECTION_FACTOR));
}
fifthLine = "BME-> ";
fifthLine += String(int(newTemp + Config.wxsensor.temperatureCorrection));
fifthLine += "C ";
fifthLine += humStr;
fifthLine += "% ";
fifthLine += presStr.substring(0,4);
fifthLine += "hPa";
String wxPayload = ".../...g...t";
wxPayload += tempStr;
wxPayload += "h";
wxPayload += humStr;
wxPayload += "b";
wxPayload += presStr;
if (wxModuleType == 3) {
wxPayload += "Gas: ";
wxPayload += String(newGas);
wxPayload += "Kohms";
}
return wxPayload;
}
}
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef WX_UTILS_H_
#define WX_UTILS_H_
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_BME680.h>
#include "Adafruit_Si7021.h"
#include <Arduino.h>
namespace WX_Utils {
void getWxModuleAddres();
void setup();
String generateTempString(const float sensorTemp);
String generateHumString(const float sensorHum);
String generatePresString(const float sensorPres);
String readDataSensor();
}
#endif
+14 -1
View File
@@ -9,8 +9,21 @@ files = [
'data_embed/style.css', 'data_embed/style.css',
'data_embed/bootstrap.js', 'data_embed/bootstrap.js',
'data_embed/bootstrap.css', 'data_embed/bootstrap.css',
'data_embed/favicon.png',
] ]
string_to_find_str = "String"
string_to_find_ver = "versionDate"
with open('src/LoRa_APRS_iGate.cpp', encoding='utf-8') as cpp_file:
for line in cpp_file:
if string_to_find_str in line and string_to_find_ver in line:
start = line.find('"') + 1
end = line.find('"', start)
if start > 0 and end > start:
versionDate = line[start:end]
break
for src in files: for src in files:
out = src + ".gz" out = src + ".gz"
@@ -19,7 +32,7 @@ for src in files:
content = f.read() content = f.read()
if src == 'data_embed/index.html': if src == 'data_embed/index.html':
env_vars = env["BOARD"] + "<br>" + ','.join(env["BUILD_FLAGS"]).replace('-Werror -Wall,', '').replace(',-DELEGANTOTA_USE_ASYNC_WEBSERVER=1', '') env_vars = env["BOARD"] + "<br>" + ','.join(env["BUILD_FLAGS"]).replace('-Werror -Wall,', '').replace(',-DELEGANTOTA_USE_ASYNC_WEBSERVER=1', '') + "<br>" + "Version date: " + versionDate
current_date = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') + " UTC" current_date = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') + " UTC"
build_info = f'{env_vars}<br>Build date: {current_date}'.encode() build_info = f'{env_vars}<br>Build date: {current_date}'.encode()