Dual Brushless Motor ESC, 10-62V, up to 50A per motor. Motors ganged or independent, multiple control input methods, cycle-by-cycle current limit, speed mode and torque mode control. Motors tiny to kW. Speed limit and other parameters easily set in firmware. As used in 'The Brushless Brutalist' locomotive - www.jons-workshop.com. See also Model Engineer magazine June-October 2019.
Dependencies: mbed BufferedSerial Servo PCT2075 FastPWM
Update 17th August 2020 Radio control inputs completed
Diff: cli_BLS_nortos.cpp
- Revision:
- 16:d1e4b9ad3b8b
- Parent:
- 14:acaa1add097b
- Child:
- 17:cc9b854295d6
--- a/cli_BLS_nortos.cpp Sat Nov 30 18:40:30 2019 +0000 +++ b/cli_BLS_nortos.cpp Tue Jun 09 09:20:19 2020 +0000 @@ -24,21 +24,20 @@ #include <cctype> using namespace std; -extern eeprom_settings mode ; +extern eeprom_settings user_settings ; extern error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes. extern int WatchDog; // from main extern bool WatchDogEnable; // from main -extern double rpm2mph ; +extern bool read_temperature (float & t) ; // from main March 2020 extern brushless_motor MotorA, MotorB; // Controlling two motors together or individually -extern char const_version_string[] ; +extern const char * get_version () ; // Need this as extern const char can not be made to work. This returns & const_version_string extern BufferedSerial com2, pc; // The two com ports used. There is also an unused com port, com3 setup @ 1200 baud -extern void setVI (double v, double i) ; // Set motor voltage limit and current limit +extern void setVI_both (double v, double i) ; // Set motor voltage limit and current limit extern double Read_DriverPot (); extern double Read_BatteryVolts (); -extern void mode_set_both_motors (int mode, double val) ; // called from cli to set fw, re, rb, hb -extern void rcin_report () ; +extern void mode_set_motors_both (int mode) ; // called from cli to set fw, re, rb, hb // All void func (struct parameters &) ; functions addressed by command line interpreter are together below here @@ -49,12 +48,14 @@ */ void ver_cmd (struct parameters & a) { - if (a.source == SOURCE_PC) - pc.printf ("Version %s\r\n", const_version_string); + if (a.source == SOURCE_PC) { + pc.printf ("Version [%s]\r\n", get_version()); + } else { if (a.source == SOURCE_TS) - if (a.respond) // Only respond if this board addressed - a.com->printf ("%s\r", const_version_string); + if (a.respond) { // Only respond if this board addressed + a.com->printf ("%s\r", get_version()); + } else pc.printf ("Crap source %d in ver_cmd\r\n", a.source); } @@ -78,28 +79,13 @@ void null_cmd (struct parameters & a) { if (a.respond) - a.com->printf ("At null_cmd, board ID %c\r\n", mode.rd(BOARD_ID)); + a.com->printf ("Board ID %c\r\n", user_settings.rd(BOARD_ID)); } -#ifdef USING_DC_MOTORS -/** -void mt_cmd (struct parameters & a) - PC Only - Responds YES, causes action NO - report_motor_types () // Reports 'Brushless' if Hall inputs read 1 to 6, 'DC' if no Hall sensors connected, therefore DC motor assumed -*/ -void mt_cmd (struct parameters & a) -{ - if (a.source == SOURCE_PC) - pc.printf ("Mot A is %s, Mot B is %s\r\n", MotorA.dc_motor ? "DC":"Brushless", MotorB.dc_motor ? "DC":"Brushless"); - else - pc.printf ("Wrong use of mt_cmd\r\n"); -} -#endif /** * void rdi_cmd (struct parameters & a) // read motor currents (uint32_t) and BatteryVolts (double) -*/ + void rdi_cmd (struct parameters & a) // read motor currents (uint32_t) and BatteryVolts (double) { // Voltage reading true volts, currents only useful as relative values if (a.respond) @@ -107,16 +93,16 @@ a.com->printf ("rdi%.1f %.1f %.1f\r%s", MotorA.Idbl, MotorB.Idbl, Read_BatteryVolts (), a.source == SOURCE_PC ? "\n" : ""); // Format good to be unpicked by cli in touch screen controller } - +*/ /** * void rvi_cmd (struct parameters & a) // read last normalised motor voltage and current values sent to pwms * */ -void rvi_cmd (struct parameters & a) // read last normalised values sent to pwms -{ - if (a.respond) - a.com->printf ("rvi%.2f %.2f %.2f %.2f\r%s", MotorA.last_V, MotorA.last_I, MotorB.last_V, MotorB.last_I, a.source == SOURCE_PC ? "\n" : ""); -} +//void rvi_cmd (struct parameters & a) // read last normalised values sent to pwms +//{ +// if (a.respond) +// a.com->printf ("rvi%.2f %.2f %.2f %.2f\r%s", MotorA.last_V, MotorA.last_I, MotorB.last_V, MotorB.last_I, a.source == SOURCE_PC ? "\n" : ""); +//} /** * void fw_cmd (struct parameters & a) // Forward command @@ -124,7 +110,9 @@ */ void fw_cmd (struct parameters & a) // Forward command { - mode_set_both_motors (MOTOR_FORWARD, 0.0); +// MotorA.set_mode (MOTOR_FORWARD); +// MotorB.set_mode (MOTOR_FORWARD); + mode_set_motors_both (MOTOR_FORWARD); if (a.source == SOURCE_PC) pc.printf ("fw\r\n"); // Show response to action if command from pc terminal } @@ -135,7 +123,7 @@ */ void re_cmd (struct parameters & a) // Reverse command { - mode_set_both_motors (MOTOR_REVERSE, 0.0); + mode_set_motors_both (MOTOR_REVERSE); if (a.source == SOURCE_PC) pc.printf ("re\r\n"); } @@ -146,9 +134,11 @@ */ void rb_cmd (struct parameters & a) // Regen brake command { - mode_set_both_motors (MOTOR_REGENBRAKE, a.dbl[0] / 100.0); + double tmp = a.dbl[0] / 100.0; + MotorA.brake (tmp); + MotorB.brake (tmp); // Corrected May 2020 - previously MotorA twice if (a.source == SOURCE_PC) - pc.printf ("rb %.2f\r\n", a.dbl[0] / 100.0); + pc.printf ("rb %.2f\r\n", tmp); } /** @@ -156,136 +146,72 @@ * Broadcast to all STM3_ESC boards, required to ACT but NOT respond * * NOTE Jan 2019 Hand brake not implemented -* +* May 2020 - Implemented, but not very good */ void hb_cmd (struct parameters & a) // Hand brake command { + double tmp; + if (a.numof_dbls != 0) tmp = a.dbl[0] / 100.0; // a.numof_dbls is int32_t + else tmp = 0.33; if (a.respond) { - a.com->printf ("numof params = %d\r\n", a.numof_dbls); - a.com->printf ("Hand Brake : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]); +// a.com->printf ("numof params = %d\r\n", a.numof_dbls); + a.com->printf ("Hand Brake : Force 0 to 99 %.0f\r\n", tmp * 100.0); } - mode_set_both_motors (MOTOR_HANDBRAKE, 0.0); + mode_set_motors_both (MOTOR_HANDBRAKE); + if (tmp < 0.0) tmp = 0.0; + if (tmp > 1.0) tmp = 1.0; + setVI_both (tmp / 5.0, 0.99); } -extern int numof_eeprom_options2 ; -extern struct optpar const option_list2[] ; -/**void mode_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents -* mode_cmd called only from pc comms. No sense calling from Touch Screen Controller + + +/**void user_settings_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents +* user_settings_cmd called only from pc comms. No sense calling from Touch Screen Controller * * Called without parameters - Lists to pc terminal current settings * */ -void mode19_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents +void user_settings_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents { - char temps[36]; - int i; - double topspeed; // New Jan 2019 - set max loco speed - pc.printf ("\r\nmode - Set system data in EEPROM - Jan 2019\r\nSyntax 'mode' with no parameters lists current state.\r\n"); - if (a.numof_dbls) { // If more than 0 parameters supplied - for (i = 0; i < a.numof_dbls; i++) - temps[i] = (char)a.dbl[i]; // recast doubles to char - while (i < 33) - temps[i++] = 0; - switch ((int)a.dbl[0]) { - case 0: // MotorA_dir [0 or 1], MotorB_dir [0 or 1] - if (temps[1] == 0 || temps[1] == 1) - mode.wr(temps[1], MOTADIR); - if (temps[2] == 0 || temps[2] == 1) - mode.wr(temps[2], MOTBDIR); - break; - case 1: // MotorA_poles [4,6,8], MotorB_poles [4,6,8] - if (temps[1] == 4 || temps[1] == 6 || temps[1] == 8) - mode.wr(temps[1], MOTAPOLES); - if (temps[2] == 4 || temps[2] == 6 || temps[2] == 8) - mode.wr(temps[2], MOTBPOLES); - break; - case 2: // MotorA_ current sense resistors [1 to 4], MotorB_ current sense resistors [1 to 4] - if (temps[1] > 0 && temps[1] < 5) - mode.wr(temps[1], ISHUNTA); // Corrected since published - if (temps[2] > 0 && temps[2] < 5) - mode.wr(temps[2], ISHUNTB); - break; - case 3: // 2 Servo1 [0 or 1], Servo2 [0 or 1] - if (temps[1] == 0 || temps[1] == 1) - mode.wr(temps[1], SVO1); - if (temps[2] == 0 || temps[2] == 1) - mode.wr(temps[2], SVO2); - break; - case 4: // 3 RCIn1 [0 or 1], RCIn2 [0 or 1] - if (temps[1] == 0 || temps[1] == 1) - mode.wr(temps[1], RCIN1); - if (temps[2] == 0 || temps[2] == 1) - mode.wr(temps[2], RCIN2); - break; - case 5: // 4 Board ID '0' to '9' - if (temps[1] <= 9) // pointless to compare unsigned integer with zero - mode.wr('0' | temps[1], BOARD_ID); - break; - case 6: // TOP_SPEED - topspeed = a.dbl[1]; - if (topspeed > 25.0) topspeed = 25.0; - if (topspeed < 1.0) topspeed = 1.0; - mode.wr((char)(topspeed * 10.0), TOP_SPEED); - break; - case 7: // 5 Wheel dia mm, Motor pinion teeth, Wheel gear teeth - mode.wr(temps[1], WHEELDIA); - mode.wr(temps[2], MOTPIN); - mode.wr(temps[3], WHEELGEAR); - break; - case 8: // {2, 5, 2, "Command source 2= COM2 (Touch Screen), 3= Pot, 4= RC Input1, 5= RC Input2"}, - if (temps[1] > 1 && temps[1] < 6) - mode.wr(temps[1], COMM_SRC); - break; - case 83: // set to defaults - mode.set_defaults (); - break; - case 9: // 9 Save settings - mode.save (); - pc.printf ("Saving settings to EEPROM\r\n"); - break; - default: - break; - } // endof switch - } // endof // If more than 0 parameters supplied - else { - pc.printf ("No Changes\r\n"); - } - pc.printf ("mode 0\tMotorA_dir [0 or 1]=%d, MotorB_dir [0 or 1]=%d\r\n", mode.rd(MOTADIR), mode.rd(MOTBDIR)); - pc.printf ("mode 1\tMotorA_poles [4,6,8]=%d, MotorB_poles [4,6,8]=%d\r\n", mode.rd(MOTAPOLES), mode.rd(MOTBPOLES)); - pc.printf ("mode 2\tMotorA I 0R05 sense Rs [1to4]=%d, MotorB I 0R05 sense Rs [1to4]=%d\r\n", mode.rd(ISHUNTA), mode.rd(ISHUNTB)); - pc.printf ("mode 3\tServo1 [0 or 1]=%d, Servo2 [0 or 1]=%d\r\n", mode.rd(SVO1), mode.rd(SVO2)); - pc.printf ("mode 4\tRCIn1 [0 or 1]=%d, RCIn2 [0 or 1]=%d\r\n", mode.rd(RCIN1), mode.rd(RCIN2)); - pc.printf ("mode 5\tBoard ID ['0' to '9']='%c'\r\n", mode.rd(BOARD_ID)); - pc.printf ("mode 6\tTop Speed MPH [1.0 to 25.0]=%.1f\r\n", double(mode.rd(TOP_SPEED)) / 10.0); - pc.printf ("mode 7\tWheel dia mm=%d, Motor pinion teeth=%d, Wheel gear teeth=%d\r\n", mode.rd(WHEELDIA), mode.rd(MOTPIN), mode.rd(WHEELGEAR)); - pc.printf ("mode 8\tCommand Src [%d] - 2=COM2 (Touch Screen), 3=Pot, 4=RC In1, 5=RC In2\r\n", mode.rd(COMM_SRC)); - pc.printf ("mode 83\tSet to defaults\r\n"); - pc.printf ("mode 9\tSave settings\r\r\n"); + user_settings.edit (a.dbl, a.numof_dbls); +} + +extern struct optpar option_list[] ; //= { +void brake_eff_set_cmd (struct parameters & a) { // set brake effectiveness from TS May 2020 + char be = (char) a.dbl[0]; + pc.printf ("BRAKE_EFFECTIVENESS min = %d, max = %d\r\n", option_list[BRAKE_EFFECTIVENESS].min, option_list[BRAKE_EFFECTIVENESS].max); + if (be > option_list[BRAKE_EFFECTIVENESS].max) be = option_list[BRAKE_EFFECTIVENESS].max; + if (be < option_list[BRAKE_EFFECTIVENESS].min) be = option_list[BRAKE_EFFECTIVENESS].min; + user_settings.wr(be, BRAKE_EFFECTIVENESS); + user_settings.save (); + pc.printf ("Set brake effectiveness to %d pct\r\n", be); } - -void ssl_cmd (struct parameters & a) { // set speed limit NEW and untested July 2019 - if (a.dbl[0] > 25.0) a.dbl[0] = 25.0; - if (a.dbl[0] < 1.0) a.dbl[0] = 1.0; - mode.wr((char)(a.dbl[0] * 10.0), TOP_SPEED); - mode.save (); +void ssl_cmd (struct parameters & a) { // set speed limit NEW and untested July 2019. Stored as speed * 10 to get 1dec place + char sp = (char) (a.dbl[0] * 10.0); + if (sp > option_list[TOP_SPEED].max) sp = option_list[TOP_SPEED].max; + if (sp < option_list[TOP_SPEED].min) sp = option_list[TOP_SPEED].min; + user_settings.wr(sp, TOP_SPEED); + user_settings.save (); + pc.printf ("Set speed limit to %.1f mph\r\n", a.dbl[0]); } -#ifdef TEMP_SENSOR_ENABLE - -extern uint32_t last_temperature_count; /** * void temperature_cmd (struct parameters & a) { -* Few boards have temperature sensor fitted. Non-preferred feature +* Few boards have temperature sensor fitted. Now only supports LM75B i2c sensor */ -void temperature_cmd (struct parameters & a) { +void read_temperature_cmd (struct parameters & a) { + float t = -99.25; if (a.respond) { - a.com->printf ("tem%c %d\r\n", mode.rd(BOARD_ID), (last_temperature_count / 16) - 50); + a.com->printf ("tem%c ", user_settings.rd(BOARD_ID)); + if (read_temperature(t)) + a.com->printf ("Temperature = %7.3f\r\n", t); + else + a.com->printf ("Temp sensor not fitted\r\n"); } } -#endif /** *void rpm_cmd (struct parameters & a) // to report e.g. RPM 1000 1000 ; speed for both motors @@ -293,18 +219,31 @@ void rpm_cmd (struct parameters & a) // to report e.g. RPM 1000 1000 ; speed for both motors { if (a.respond) -// a.com->printf ("rpm%c %d %d\r%s", mode.rd(BOARD_ID), MotorA.RPM, MotorB.RPM, a.source == SOURCE_PC ? "\n" : ""); - a.com->printf ("rpm%c %.0f %.0f\r%s", mode.rd(BOARD_ID), MotorA.dRPM, MotorB.dRPM, a.source == SOURCE_PC ? "\n" : ""); +// a.com->printf ("rpm%c %d %d\r%s", user_settings.rd(BOARD_ID), MotorA.RPM, MotorB.RPM, a.source == SOURCE_PC ? "\n" : ""); + a.com->printf ("rpm%c %.0f %.0f\r%s", user_settings.rd(BOARD_ID), MotorA.dRPM, MotorB.dRPM, a.source == SOURCE_PC ? "\n" : ""); } /** *void mph_cmd (struct parameters & a) // to report miles per hour */ -void mph_cmd (struct parameters & a) // to report miles per hour to 1 decimal place +void mph_cmd (struct parameters & a) // to report miles per hour to 1 decimal place - now 2dp May 2020 { + int j = 0; + double speedmph = 0.0; + if (MotorA.exists ()) { + j |= 1; + speedmph = MotorA.dMPH; + } + if (MotorB.exists ()) { + j |= 2; + speedmph += MotorB.dMPH; + } + if (j == 3) + speedmph /= 2.0; if (a.respond) -// a.com->printf ("mph%c %.1f\r%s", mode.rd(BOARD_ID), (double)(MotorA.RPM + MotorB.RPM) * rpm2mph / 2.0, a.source == SOURCE_PC ? "\n" : ""); - a.com->printf ("mph%c %.1f\r%s", mode.rd(BOARD_ID), (double)(MotorA.dMPH + MotorB.dMPH) / 2.0, a.source == SOURCE_PC ? "\n" : ""); +// May 17th 2020 modified line below - removed superfluous cast, upped to 2 decimal places +// a.com->printf ("mph%c %.2f\r%s", user_settings.rd(BOARD_ID), speedmph, a.source == SOURCE_PC ? "\n" : ""); + a.com->printf ("?s%c %.2f\r%s", user_settings.rd(BOARD_ID), speedmph, a.source == SOURCE_PC ? "\n" : ""); } /** @@ -314,7 +253,7 @@ void sysV_report (struct parameters & a) // { if (a.respond) - a.com->printf ("?v%c %.1f\r%s", mode.rd(BOARD_ID), Read_BatteryVolts(), a.source == SOURCE_PC ? "\n" : ""); + a.com->printf ("?v%c %.1f\r%s", user_settings.rd(BOARD_ID), Read_BatteryVolts(), a.source == SOURCE_PC ? "\n" : ""); } /** @@ -323,12 +262,46 @@ */ void sysI_report (struct parameters & a) // { - if (a.respond) // Calibration, refinement of 6000.0 (not miles out) first guess possible. -// a.com->printf ("?i%c %.2f %.2f\r%s", mode_bytes[BOARD_ID], (double)MotorA.I.ave / 6000.0, (double)MotorB.I.ave / 6000.0, a.source == SOURCE_PC ? "\n" : ""); -// a.com->printf ("?i%c %.2f %.2f\r%s", mode.rd(BOARD_ID), (double)MotorA.I.ave / 6000.0, MotorA.I.dblave2 / 6000.0, a.source == SOURCE_PC ? "\n" : ""); - a.com->printf ("?i%c %.2f %.2f\r%s", mode.rd(BOARD_ID), MotorA.Idbl, MotorB.Idbl, a.source == SOURCE_PC ? "\n" : ""); + if (a.respond) + a.com->printf ("?i%c %.2f %.2f\r%s", user_settings.rd(BOARD_ID), MotorA.Idbl, MotorB.Idbl, a.source == SOURCE_PC ? "\n" : ""); } +/* + +New December 2019 - possible for implementation + Having implemented radio control inputs and driver pot, there is some sense in moving slider handler from touch screen controller + into STM3_ESC code. + New instructions to be accepted from touch screen : - + {"w", "touch screen new slider touch", slider_touch_cmd}, + {"x", "updated slider RANGE 0 to 99", slider_touch_position_cmd}, // max two digits + {"y", "touch_screen slider finger lifted clear", slider_untouch_cmd}, +*/ +bool finger_on_slider = false; +/**void slider_touch_cmd (struct parameters & a) +* +* Message from touch screen controller, slider touched +*/ +void slider_touch_cmd (struct parameters & a) { + finger_on_slider = true; +} + +/**void slider_untouch_cmd (struct parameters & a) +* +* Message from touch screen controller, finger taken off slider +*/ +void slider_untouch_cmd (struct parameters & a) { + finger_on_slider = false; +} + +/**void slider_touch_position_cmd (struct parameters & a) +* +* Message from touch screen controller, latest slider touch position +*/ +void slider_touch_position_cmd (struct parameters & a) { +} + +// End of New December 2019 + /**void vi_cmd (struct parameters & a) * @@ -336,8 +309,8 @@ */ void vi_cmd (struct parameters & a) { - setVI (a.dbl[0] / 100.0, a.dbl[1] / 100.0); - pc.printf ("setVI from %s\r\n", a.source == SOURCE_PC ? "PC" : "Touch Screen"); + setVI_both (a.dbl[0] / 100.0, a.dbl[1] / 100.0); +// pc.printf ("setVI_both from %s\r\n", a.source == SOURCE_PC ? "PC" : "Touch Screen"); } /** @@ -370,7 +343,7 @@ */ void kd_cmd (struct parameters & a) // kick the watchdog. Reached from TS or pc. { - WatchDog = WATCHDOG_RELOAD + (mode.rd(BOARD_ID) & 0x0f); // Reload watchdog timeout. Counted down @ 8Hz + WatchDog = WATCHDOG_RELOAD + (user_settings.rd(BOARD_ID) & 0x0f); // Reload watchdog timeout. Counted down @ 8Hz WatchDogEnable = true; // Receipt of this command sufficient to enable watchdog } @@ -387,8 +360,8 @@ */ void who_cmd (struct parameters & a) // Reachable always from pc. Only addressed board responds to TS { - if (a.source == SOURCE_PC || mode.rd(BOARD_ID) == a.target_unit) - a.com->printf ("who%c\r%s", mode.rd(BOARD_ID), a.source == SOURCE_PC ? "\n" : ""); + if (a.source == SOURCE_PC || user_settings.rd(BOARD_ID) == a.target_unit) + a.com->printf ("who%c\r%s", user_settings.rd(BOARD_ID), a.source == SOURCE_PC ? "\n" : ""); } /** @@ -396,11 +369,11 @@ * * For test, reports to pc terminal info about radio control input channels */ -void rcin_pccmd (struct parameters & a) -{ - rcin_report (); -} - +//void rcin_pccmd (struct parameters & a) +//{ +// rcin_report (); +//} +/* void scmd (struct parameters & a) // filter coefficient fiddler { switch ((int)a.dbl[0]) { @@ -416,10 +389,6 @@ case 4: MotorA.sdbl[4] = MotorB.sdbl[4] = a.dbl[1]; break; - case 5: - MotorA.set_speed (a.dbl[1]); - MotorB.set_speed (a.dbl[1]); - break; default: pc.printf ("Wrong use of scmd %f\r\n", a.dbl[0]); } @@ -429,9 +398,9 @@ pc.printf ("2 %.3f\tP_gain 1.0-1000.0\r\n", MotorA.sdbl[2]); pc.printf ("3 %.3f\tDscale 0.01-0.5\r\n", MotorA.sdbl[3]); pc.printf ("4 %.3f\tD_gain 1.0-1000.0\r\n", MotorA.sdbl[4]); - pc.printf ("5 Set target_speed\r\n"); +// pc.printf ("5 Set target_speed\r\n"); } - +*/ struct kb_command { // Commands tabulated as list of these structures as seen below const char * cmd_word; // points to text e.g. "menu" const char * explan; // very brief explanation or clue as to purpose of function @@ -446,7 +415,7 @@ void menucmd (struct parameters & a) { if (a.respond) { - a.com->printf("\r\n\nDual BLDC ESC type STM3 2018-20, Ver %s\r\nAt menucmd function - listing commands, source %s:-\r\n", const_version_string, a.source == SOURCE_PC ? "PC" : "TS"); + a.com->printf("\r\n\nDual BLDC ESC type STM3 2018-20, Ver %s\r\nAt menucmd function - listing commands, source %s:-\r\n", get_version(), a.source == SOURCE_PC ? "PC" : "TS"); for(int i = 0; i < a.numof_menu_items; i++) a.com->printf("[%s]\t\t%s\r\n", a.command_list[i].cmd_word, a.command_list[i].explan); a.com->printf("End of List of Commands\r\n"); @@ -464,23 +433,28 @@ // ***** Broadcast commands for all STM3_ESC boards to execute. Boards NOT to send serial response ***** {"fw", "forward", fw_cmd}, {"re", "reverse", re_cmd}, - {"rb", "regen brake 0 to 99 %", rb_cmd}, + {"rb", "regen brake 0 to 99 %", rb_cmd}, // max two digits {"hb", "hand brake", hb_cmd}, - {"v", "set motors V percent RANGE 0 to 100", v_cmd}, - {"i", "set motors I percent RANGE 0 to 100", i_cmd}, - {"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd}, + {"v", "set motors V percent RANGE 0 to 99", v_cmd}, + {"i", "set motors I percent RANGE 0 to 99", i_cmd}, + {"vi", "set motors V and I percent RANGE 0 to 99", vi_cmd}, + {"w", "touch screen new slider touch", slider_touch_cmd}, + {"x", "updated slider RANGE 0 to 99", slider_touch_position_cmd}, + {"y", "touch_screen slider finger lifted clear", slider_untouch_cmd}, {"kd", "kick the dog, reloads WatchDog", kd_cmd}, + {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019 + {"sbe", "set brake effectiveness 5 to 90 percent", brake_eff_set_cmd}, // NEW May 2020 // ***** Endof Broadcast commands for all STM3_ESC boards to execute. Boards NOT to send serial response ***** // ***** Following are rx'd requests for serial response from addressed STM3_ESC only {"?v", "Report system bus voltage", sysV_report}, {"?i", "Report motor both currents", sysI_report}, {"who", "search for connected units, e.g. 3who returs 'who3' if found", who_cmd}, -#ifdef TEMP_SENSOR_ENABLE - {"tem", "report temperature", temperature_cmd}, -#endif + {"tem", "report temperature", read_temperature_cmd}, {"mph", "read loco speed miles per hour", mph_cmd}, - {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019 + {"?s", "read loco speed miles per hour", mph_cmd}, // Shorter-hand added 17th May 2020 +// {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019 +// {"sbe", "set brake effectiveness 5 to 90 percent", brake_eff_set_cmd}, // NEW May 2020 // {"rvi", "read most recent values sent to pwms", rvi_cmd}, // {"rdi", "read motor currents and power voltage", rdi_cmd}, // ***** Endof @@ -494,10 +468,6 @@ struct kb_command const pc_command_list[] = { {"ls", "Lists available commands", menucmd}, {"?", "Lists available commands, same as ls", menucmd}, -#ifdef USING_DC_MOTORS - {"mtypes", "report types of motors found", mt_cmd}, -#endif - {"s","1-4, RPM and speed filter param", scmd}, {"pot", "read drivers control pot", pot_cmd}, {"fw", "forward", fw_cmd}, {"re", "reverse", re_cmd}, @@ -510,19 +480,18 @@ {"?i", "Report motor both currents", sysI_report}, {"?w", "show WatchDog timer contents", wd_report}, {"who", "search for connected units, e.g. 3who returs 'who3' if found", who_cmd}, - {"mode", "read or set params in eeprom", mode19_cmd}, // Big change Jan 2019 + {"us", "read or set user settings in eeprom", user_settings_cmd}, // Big change Jan 2019 {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019 ONLY HERE FOR TEST, normal use is from Touch Screen only. + {"sbe", "set brake effectiveness 5 to 90 percent", brake_eff_set_cmd}, // NEW May 2020 // {"erase", "set eeprom contents to all 0xff", erase_cmd}, -#ifdef TEMP_SENSOR_ENABLE - {"tem", "report temperature", temperature_cmd}, // Reports -50 when sensor not fitted -#endif + {"tem", "report temperature", read_temperature_cmd}, // Reports -50 when sensor not fitted {"kd", "kick the dog, reloads WatchDog", kd_cmd}, {"ver", "Version", ver_cmd}, - {"rcin", "Report Radio Control Input stuff", rcin_pccmd}, {"rpm", "read motor pair speeds", rpm_cmd}, {"mph", "read loco speed miles per hour", mph_cmd}, - {"rvi", "read most recent values sent to pwms", rvi_cmd}, - {"rdi", "read motor currents and power voltage", rdi_cmd}, + {"?s", "read loco speed miles per hour", mph_cmd}, +// {"rvi", "read most recent values sent to pwms", rvi_cmd}, +// {"rdi", "read motor currents and power voltage", rdi_cmd}, // {"bc", "bogie constants - wheel dia, motor pinion, wheel gear", bogie_constants_report_cmd}, // {"gbb", "get bogie bytes from eeprom and report", gbb_cmd}, // OBSOLETE, replaced by 'gbb' {"nu", "do nothing", null_cmd}, @@ -552,8 +521,11 @@ * * Daft check that class instantiation worked */ -void cli_2019::test () { - pc.printf ("At cli2019::test, source %d len %d,\r\n", a.source, a.numof_menu_items); +void cli_2019::flush () { +// char ch; + while (a.com->readable()) + a.com->getc(); + //pc.printf ("At cli2019::test, source %d len %d,\r\n", a.source, a.numof_menu_items); } /** @@ -567,7 +539,7 @@ * Parameters available to functions from 'parameters' struct. */ void cli_2019::core () { - int ch, IAm = mode.rd(BOARD_ID); + int ch, IAm = user_settings.rd(BOARD_ID); char * pEnd;//, * cmd_line_ptr; while (a.com->readable()) { ch = a.com->getc(); @@ -594,17 +566,21 @@ for (i = 0; i < a.numof_menu_items; i++) { // Look for input match in command list wrdlen = strlen(commandlist[i].cmd_word); if(strncmp(commandlist[i].cmd_word, cmdline_ptr, wrdlen) == 0 && !isalpha(cmdline_ptr[wrdlen])) { // If match found - for (int k = 0; k < MAX_PARAMS; k++) { + for (int k = 0; k < MAX_CLI_PARAMS; k++) { a.dbl[k] = 0.0; } a.position_in_list = i; a.numof_dbls = 0; +// pEnd = cmdline + clindex; // does indeed point to null terminator pEnd = cmdline_ptr + wrdlen; - while (*pEnd) { // Assemble all numerics as doubles +// while (*pEnd) { // Assemble all numerics as doubles + while (*pEnd && a.numof_dbls < MAX_CLI_PARAMS) { // Assemble all numerics as doubles a.dbl[a.numof_dbls++] = strtod (pEnd, &pEnd); - while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) { + while (*pEnd && (pEnd < cmdline + clindex) && *pEnd && !isdigit(*pEnd) && ('.' != *pEnd) && ('-' != *pEnd) && ('+' != *pEnd)) { // Can crash cli here with e.g. 'ls -l' pEnd++; - } + } // problem occurs with input such as "- ", or "-a", seemingly anything dodgy following a '-' or a '+' + if (((*pEnd == '-') || (*pEnd == '+')) &&(!isdigit(*(pEnd+1))) && ('.' !=*(pEnd+1))) + pEnd = cmdline + clindex; // fixed by aborting remainder of line } a.respond = a.resp_always; if (((a.target_unit == BROADCAST) && (IAm == '0')) || (IAm == a.target_unit))