1515 * - Status display, p.e. positions, firmware (ESP and PIC), WiFi,...
1616 * - Access point (until local WiFi has been configured)
1717 * - OTA Firmware-Update ESP
18- * - Firmware-Update (PIC) via Web UI (planned)
18+ * - Write to PIC EEPROM via Web UI
19+ * - Firmware-Update (PIC) via Web UI
1920 *
2021 * \b IDE: <c> Arduino IDE 2.2.1 → <c> esptool.py v3.0 \n
2122 * \b Device: \n
3839 * Doxygen: https://www.doxygen.nl/manual/docblocks.html \n
3940 *
4041 * Change Log:
42+ * 2024-09-24 v0.9
43+ * - Added new command: EEwrite EEwrite:<uint16 addr,uint16 data>
44+ * This command allows to change PIC EEPROM, p.e. VBSUM_1pct @EEPROM addr = 2.
45+ * - Error codes PICerrno and ESPerrno are exported with status report and are shown in Web-UI v0.9 and above.
46+ * Corresponding text messages may be edited in customize.js.
47+ * - Read access to all files except index.html was restricted to private IP addresses Class C (192.168.x.x).
4148 * 2024-03-11 v0.8
4249 * - Added data logger: <IP>/logdata? reads curr_log[] and bemf_log[] from PIC.
4350 * - Added VBsum to "info?" for testing BEMF sum-up for position control.
7481 *
7582 * @todo - poor handling of refset[] (maybe by PIC?).
7683 * - home drive sometimes doesn't reset position.
77- * - Download of ovc.ini should be password protected or PSK should be encrypted in ovc.ini.
78- * - Firmware update via httpUpdater should be password protected.
79- * - Define enum ERRNOs globally (ESP + PIC)
8084 */
8185
8286// *** includes
@@ -98,6 +102,7 @@ extern float DS18B20_TempC (uint8_t index);
98102extern int fw_download (char *rec);
99103
100104extern void webUI_bootload (void );
105+ extern void webUI_eewrite (void );
101106extern void webUI_home (void );
102107extern void webUI_info (void );
103108extern void webUI_move (void );
@@ -144,7 +149,8 @@ struct FLAGS //!< flags to start tasks within loop()
144149 uint8_t bootload :1 ; // !< 4 update PIC firmware
145150 uint8_t version :1 ; // !< 5 update PIC version
146151 uint8_t logdata :1 ; // !< 6 reads log data from PIC
147- uint8_t :1 ; // !< 7
152+ uint8_t eewrite :1 ; // !< 7 write to PIC EEPROM
153+ uint8_t :1 ; // !< 8
148154};
149155
150156/* uint16_t status word (read from PIC)
@@ -163,6 +169,36 @@ struct FLAGS //!< flags to start tasks within loop()
163169#define MOVE (x ) ((x & 0x0100 ) /* 'move' is executing */
164170#define HOME (x ) ((x & 0x0200 ) /* 'home' is executing */
165171
172+
173+ enum Errs { /* ALL PIC errnos are negative, ESP errors are positive */
174+ E_ADC_TIMEOUT = -127 , // AD converter timeout
175+
176+ E_EEWR_ARGC = -9 , // EEPROM write: argument count != 2
177+ E_EEWR_ADDR = -8 , // EEPROM write: address out of range
178+ E_HOMEING_ACTIVE = -7 , // Move command, whereas Home is active
179+ E_MOVE_ARGC = -6 , // Move command: argument count != 3
180+ E_NO_REFERENCE = -5 , // Reference not set
181+ E_UNDEF_CMD = -4 , // Undefined command
182+ E_MA_MAX = -3 , // Out of range: mA_max
183+ E_SET_POS_RANGE = -2 , // Out of range: set_pos
184+ E_VZ_RANGE = -1 , // Out of range: vz
185+
186+ E_NO_ERR = 0 , // No error
187+
188+ E_INIFILE_NOT_FOUND = 1 , // INI file not found
189+ E_IDENTIFIER_NOT_FOUND = 2 , // Identifier not found
190+ E_PIC_TIMEOUT = 3 , // PIC timeout
191+ E_NACK_Move = 4 , // Move not acknowledged by PIC
192+ E_NACK_Home = 5 , // Home not acknowledged by PIC
193+ E_NACK_Status = 6 , // Status not acknowledged by PIC
194+ E_NACK_EEwrite = 7 , // EEPROM write not acknowledged by PIC
195+ E_ADDR_RANGE = 8 , // (EEPROM write) address out of range
196+ E_EEWRITE_ARGC = 9 , // (EEPROM write) argument count != 2
197+ E_DATA_RANGE = 10 , // (EEPROM write) data out of range
198+ };
199+
200+
201+
166202/* * LIBRARY INSTANCES */
167203
168204/* * Webserver
@@ -179,21 +215,24 @@ PubSubClient MQTTclient(espClient);
179215
180216/* * Global variables
181217 * =============== */
182- char ESPversion[32 ] = " v0.8 " ; // Version of ESP-Firmware
183- char PICversion[32 ] = " NN" ; // Version of PIC-Firmware
218+ char ESPversion[32 ] = " v0.9 " ; // Version of ESP-Firmware
219+ char PICversion[32 ] = " NN" ; // Version of PIC-Firmware
184220
185221// WiFi credentials: Initial values are used for access point!
186222// The credential aof your routers WiFi can be customized in "ovc.ini" (uploaded into LittleFS)
187223char ssid[64 ] = " OVC-access-point" ; // SSID (access point)
188224char psk[64 ] = " OVC-password" ; // Password (access point)
189225long rssi; // signal strength in dBm
190226
227+ IPAddress remoteIP; // the client's (remote) IP
228+ int16_t ESPerrno = 0 ; // ESP errno
229+
191230// MQTT
192231char mqtt_host[64 ] = " " ; // IP address of mqtt host (broker)
193232char mqtt_prefix[64 ] = " " ; // prefix (p.e. "OVC-1")
194233char mqtt_token[64 ] = " " ; // token for publish (p.e. "OVC-1/tempC" etc.)
195234
196- char jStatus[512 ]; // set big enough to hold the "beautifed " JSON status!
235+ char jStatus[512 ]; // set big enough to hold the "beautyfied " JSON status!
197236unsigned long mqttLastConnect = millis();
198237unsigned long mqttLastPub = millis();
199238unsigned long mqttCurrentTime;
@@ -206,6 +245,7 @@ char alias4[8];
206245
207246// Vars sourced by PIC µC
208247uint16_t status; // status word from PIC
248+ int16_t PICerrno = 0 ; // errno returned from PIC (cmd2pic)
209249float mAmps = 0.0 ; // actual current [mA]
210250float tempC = 0.0 ; // temperature in Celsius (DS18B20)
211251float dTemp = 0.0 ; // temperature adjust (ovc.ini)
@@ -218,6 +258,8 @@ struct FLAGS flags; // processing flags (Web UI -> loop)
218258int vz = 0 ; // selected valve zone (motor), [1 .. 4], 0 = none!
219259int set_pos[numVZ + 1 ] = { -1 , 0 , 65 , 36 , 100 }; // valve set positions
220260float max_mA[numVZ + 1 ] = { 0.0 , 30.0 , 30.0 , 30.0 , 30.0 }; // motor current limits [mA]
261+ int EEaddr; // address for EEPROM write
262+ int EEdata; // data for EEPROM write
221263
222264char txbuf[64 ];
223265char rxbuf[64 ];
@@ -345,6 +387,7 @@ void setup ()
345387 */
346388// server.on("/", handleRoot); // handled by LittleFS -> invokes /index.html (our Web UI)
347389 server.on (" /bootload" , HTTP_GET , webUI_bootload);
390+ server.on (" /eewrite" , HTTP_GET , webUI_eewrite);
348391 server.on (" /move" , HTTP_GET , webUI_move);
349392 server.on (" /home" , HTTP_GET , webUI_home);
350393 server.on (" /logdata" , HTTP_GET , webUI_logdata);
@@ -392,11 +435,12 @@ void loop ()
392435 */
393436 sprintf (txbuf, " Move:%d,%d,%d" , vz, set_pos[vz], (uint16_t )(10 * max_mA[vz])); // Move:vz:set_pos[vz]:10 x max_mA[vz]
394437 OLED_show (1 , txbuf); // optional show on OLED.row 1 (0..5)
438+ delay (500 );
395439 error = cmd2pic ();
396440 // check if response contains command token ("Move"), else it is an error reponse
397441 if (strncmp (rxbuf, " Move:" , 5 ) != 0 ) // compare first N chars of response with command
398442 { /* * @todo optional error handler, response might contain error number */
399- error = - 2 ;
443+ error = E_NACK_Move ;
400444 }
401445 flags.move = 0 ;
402446 } // if flags.move
@@ -408,10 +452,11 @@ void loop ()
408452 */
409453 sprintf (txbuf, " Home:%d,%d" , vz, (uint16_t )(10 * max_mA[vz])); // Home:vz:10 x max_mA[vz]
410454 OLED_show (1 , txbuf); // optional show on OLED.row 1 (0..5)
455+ delay (500 );
411456 error = cmd2pic ();
412457 if (strncmp (rxbuf, " Home:" , 5 ) != 0 ) // compare first N chars of response with command
413458 { /* * @todo optional error handler, response might contain error number */
414- error = - 3 ;
459+ error = E_NACK_Home ;
415460 }
416461 flags.home = 0 ;
417462 }
@@ -440,6 +485,20 @@ void loop ()
440485 flags.bootload = 0 ;
441486 }
442487
488+ else if (flags.eewrite ) // EEPROM write?
489+ {
490+ sprintf (txbuf, " EEwrite:%u,%u" , EEaddr, EEdata); // EEwrite:EEaddr,EEdata
491+ OLED_show (1 , txbuf); // optional show on OLED.row 1 (0..5)
492+ delay (500 );
493+ error = cmd2pic ();
494+ // check if response contains command token ("Move"), else it is an error reponse
495+ if (strncmp (rxbuf, " EEwrite:" , 8 ) != 0 ) // compare first N chars of response with command
496+ { /* * @todo optional error handler, response might contain error number */
497+ error = E_NACK_EEwrite;
498+ }
499+ flags.eewrite = 0 ;
500+ } // if flags.eewrite
501+
443502 else if (flags.logdata ) // read logdata (curr_log[], bemf_log[]) from PIC
444503 {
445504 getPIClogdata ();
@@ -465,7 +524,7 @@ void loop ()
465524 // check if response contains command token ("Status:"), else it is an error reponse
466525 if (strncmp (rxbuf, " Status:" , 7 ) != 0 ) // compare first N chars of response with command
467526 { // / @todo optional error handler, response might contain error number
468- error = - 4 ;
527+ error = E_NACK_Status ;
469528 }
470529
471530 /* Process status or error message */
@@ -609,18 +668,15 @@ void create_jStatus (char *dest, int len, bool pretty)
609668
610669 doc[" mAmps" ] = round (mAmps * 10 ) / 10.0 ;
611670 doc[" tempC" ] = round (tempC * 10 ) / 10.0 ;
671+ doc[" PICerrno" ] = PICerrno;
672+ doc[" ESPerrno" ] = ESPerrno;
612673
613674 JsonObject VZ1 = doc.createNestedObject (" VZ1" );
614675 VZ1 [" Position" ] = position[1 ];
615676 VZ1 [" Set_Pos" ] = set_pos[1 ];
616677 VZ1 [" Ref_Set" ] = refset[1 ] ? 1 : 0 ;
617678 VZ1 [" max_mA" ] = max_mA[1 ];
618679
619- VZ1 [" Position" ] = position[1 ];
620- VZ1 [" Set_Pos" ] = set_pos[1 ];
621- VZ1 [" Ref_Set" ] = refset[1 ] ? 1 : 0 ;
622- VZ1 [" max_mA" ] = max_mA[1 ];
623-
624680 JsonObject VZ2 = doc.createNestedObject (" VZ2" );
625681 VZ2 [" Position" ] = position[2 ];
626682 VZ2 [" Set_Pos" ] = set_pos[2 ];
@@ -690,7 +746,7 @@ int cmd2pic (void)
690746
691747 if ((millis () - tstart) > MAX_ACK_TIME )
692748 {
693- error = - 1 ; // timeout?
749+ error = E_PIC_TIMEOUT ;
694750/*
695751 Serial.flush(); // Waits for the transmission of outgoing serial data to complete
696752 Serial.swap(); // output to serial monitor
@@ -708,7 +764,10 @@ int cmd2pic (void)
708764 if (str.startsWith (" ERROR" ))
709765 {
710766 error = str.substring (5 ).toInt ();
767+ PICerrno = error;
711768 }
769+ else if (!str.startsWith (" Status:" )) PICerrno = 0 ;
770+
712771 /* * @todo response could contain an error mesg - how to handle this?)
713772 TEST: * /
714773 Serial.flush(); // Waits for the transmission of outgoing serial data to complete
@@ -725,7 +784,7 @@ int cmd2pic (void)
725784 } // if
726785 else // no response (timeout)
727786 {
728- error = - 2 ; // timeout
787+ error = E_PIC_TIMEOUT ;
729788/*
730789 Serial.flush(); // Waits for the transmission of outgoing serial data to complete
731790 Serial.swap(); // output to serial monitor
@@ -807,7 +866,7 @@ void getPIClogdata (void)
807866
808867 if ((millis () - tstart) > MAX_ACK_TIME )
809868 {
810- error = - 1 ; // timeout?
869+ error = E_PIC_TIMEOUT ;
811870 }
812871 server.handleClient (); // process WebUI during reception
813872 } // for
0 commit comments