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

Committer:
JonFreeman
Date:
Sun Aug 16 14:13:19 2020 +0000
Revision:
17:cc9b854295d6
Parent:
16:d1e4b9ad3b8b
August 2020. Checked Radio Control input ops.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 12:d1d21a2941ef 1 /**
JonFreeman 12:d1d21a2941ef 2 * Code in this file : -
JonFreeman 12:d1d21a2941ef 3 *
JonFreeman 12:d1d21a2941ef 4 * STM3_ESC board uses two serial ports.
JonFreeman 12:d1d21a2941ef 5 * One (use pc.printf etc) provides 9600 baud comms to a pc or other terminal. Essential for test and setup, not used in everyday use.
JonFreeman 12:d1d21a2941ef 6 *
JonFreeman 12:d1d21a2941ef 7 * com2 provides 19200 baud comms via opto-isolators to Touch Screen Controller (see "Brute_TS_Controller_2018_11"). Opto isolation allows
JonFreeman 12:d1d21a2941ef 8 * for several boards to parallel up on this port, each STM3_ESC board having a unique single byte ID char in range '0' to '9'.
JonFreeman 12:d1d21a2941ef 9 * This enables Touch Screen controller to address ESC boards individually e.g. for requesting speed, RPM etc
JonFreeman 12:d1d21a2941ef 10 * while also allowing broadcast of commands not requiring responses
JonFreeman 12:d1d21a2941ef 11 *
JonFreeman 12:d1d21a2941ef 12 * Code implements a Command Line Interpreter (see class cli_2019)
JonFreeman 12:d1d21a2941ef 13 * Two instantiations of class cli_2019 are used, 'pcc' for pc comms and 'tsc' for touch screen comms
JonFreeman 12:d1d21a2941ef 14 * These read incoming commands and execute code functions accordingly. These functions are all of type
JonFreeman 12:d1d21a2941ef 15 * void func (struct parameters &) ;
JonFreeman 12:d1d21a2941ef 16 * This allows any command line parameters to pass to 'func'
JonFreeman 12:d1d21a2941ef 17 */
JonFreeman 12:d1d21a2941ef 18 // Brushless_STM3_Ctrl_2018_11
JonFreeman 6:f289a49c1eae 19 #include "mbed.h"
JonFreeman 6:f289a49c1eae 20 #include "BufferedSerial.h"
JonFreeman 13:ef7a06fa11de 21 #include "STM3_ESC.h"
JonFreeman 11:bfb73f083009 22 #include "brushless_motor.h"
JonFreeman 6:f289a49c1eae 23
JonFreeman 6:f289a49c1eae 24 #include <cctype>
JonFreeman 6:f289a49c1eae 25 using namespace std;
JonFreeman 6:f289a49c1eae 26
JonFreeman 16:d1e4b9ad3b8b 27 extern eeprom_settings user_settings ;
JonFreeman 12:d1d21a2941ef 28 extern error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes.
JonFreeman 13:ef7a06fa11de 29 extern int WatchDog; // from main
JonFreeman 13:ef7a06fa11de 30 extern bool WatchDogEnable; // from main
JonFreeman 17:cc9b854295d6 31 //extern bool read_temperature (float & t) ; // from main March 2020
JonFreeman 11:bfb73f083009 32
JonFreeman 12:d1d21a2941ef 33 extern brushless_motor MotorA, MotorB; // Controlling two motors together or individually
JonFreeman 16:d1e4b9ad3b8b 34 extern const char * get_version () ; // Need this as extern const char can not be made to work. This returns & const_version_string
JonFreeman 6:f289a49c1eae 35
JonFreeman 12:d1d21a2941ef 36 extern BufferedSerial com2, pc; // The two com ports used. There is also an unused com port, com3 setup @ 1200 baud
JonFreeman 16:d1e4b9ad3b8b 37 extern void setVI_both (double v, double i) ; // Set motor voltage limit and current limit
JonFreeman 8:93203f473f6e 38 extern double Read_DriverPot ();
JonFreeman 11:bfb73f083009 39 extern double Read_BatteryVolts ();
JonFreeman 16:d1e4b9ad3b8b 40 extern void mode_set_motors_both (int mode) ; // called from cli to set fw, re, rb, hb
JonFreeman 12:d1d21a2941ef 41
JonFreeman 12:d1d21a2941ef 42 // All void func (struct parameters &) ; functions addressed by command line interpreter are together below here
JonFreeman 12:d1d21a2941ef 43
JonFreeman 12:d1d21a2941ef 44 /**
JonFreeman 12:d1d21a2941ef 45 void ver_cmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 46 Responds YES, causes action NO
JonFreeman 12:d1d21a2941ef 47 PC or TS able to read software / firmware / hardware version string
JonFreeman 12:d1d21a2941ef 48 */
JonFreeman 12:d1d21a2941ef 49 void ver_cmd (struct parameters & a)
JonFreeman 8:93203f473f6e 50 {
JonFreeman 16:d1e4b9ad3b8b 51 if (a.source == SOURCE_PC) {
JonFreeman 16:d1e4b9ad3b8b 52 pc.printf ("Version [%s]\r\n", get_version());
JonFreeman 16:d1e4b9ad3b8b 53 }
JonFreeman 12:d1d21a2941ef 54 else {
JonFreeman 12:d1d21a2941ef 55 if (a.source == SOURCE_TS)
JonFreeman 16:d1e4b9ad3b8b 56 if (a.respond) { // Only respond if this board addressed
JonFreeman 16:d1e4b9ad3b8b 57 a.com->printf ("%s\r", get_version());
JonFreeman 16:d1e4b9ad3b8b 58 }
JonFreeman 12:d1d21a2941ef 59 else
JonFreeman 12:d1d21a2941ef 60 pc.printf ("Crap source %d in ver_cmd\r\n", a.source);
JonFreeman 12:d1d21a2941ef 61 }
JonFreeman 8:93203f473f6e 62 }
JonFreeman 6:f289a49c1eae 63
JonFreeman 12:d1d21a2941ef 64 /**
JonFreeman 12:d1d21a2941ef 65 void pot_cmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 66 Responds YES, causes action NO
JonFreeman 12:d1d21a2941ef 67 pc reads DriverPot. No sense in TS reading as STM3_ESC uses either/or TS, DriverPot
JonFreeman 12:d1d21a2941ef 68 */
JonFreeman 12:d1d21a2941ef 69 void pot_cmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 70 { if (a.source == SOURCE_PC)
JonFreeman 12:d1d21a2941ef 71 pc.printf ("Driver's pot %.3f\r\n", Read_DriverPot ());
JonFreeman 12:d1d21a2941ef 72 else
JonFreeman 12:d1d21a2941ef 73 pc.printf ("Wrong use of pot_cmd\r\n");
JonFreeman 12:d1d21a2941ef 74 }
JonFreeman 12:d1d21a2941ef 75
JonFreeman 12:d1d21a2941ef 76 /**
JonFreeman 12:d1d21a2941ef 77 * Do nothing command, but does report board ID code '0' to '9'
JonFreeman 12:d1d21a2941ef 78 */
JonFreeman 6:f289a49c1eae 79 void null_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 80 {
JonFreeman 6:f289a49c1eae 81 if (a.respond)
JonFreeman 16:d1e4b9ad3b8b 82 a.com->printf ("Board ID %c\r\n", user_settings.rd(BOARD_ID));
JonFreeman 8:93203f473f6e 83 }
JonFreeman 8:93203f473f6e 84
JonFreeman 12:d1d21a2941ef 85
JonFreeman 12:d1d21a2941ef 86 /**
JonFreeman 12:d1d21a2941ef 87 * void rdi_cmd (struct parameters & a) // read motor currents (uint32_t) and BatteryVolts (double)
JonFreeman 16:d1e4b9ad3b8b 88
JonFreeman 12:d1d21a2941ef 89 void rdi_cmd (struct parameters & a) // read motor currents (uint32_t) and BatteryVolts (double)
JonFreeman 12:d1d21a2941ef 90 { // Voltage reading true volts, currents only useful as relative values
JonFreeman 12:d1d21a2941ef 91 if (a.respond)
JonFreeman 12:d1d21a2941ef 92 // a.com->printf ("rdi%d %d %.1f\r%s", MotorA.I.ave, MotorB.I.ave, Read_BatteryVolts (), a.source == SOURCE_PC ? "\n" : "");
JonFreeman 12:d1d21a2941ef 93 a.com->printf ("rdi%.1f %.1f %.1f\r%s", MotorA.Idbl, MotorB.Idbl, Read_BatteryVolts (), a.source == SOURCE_PC ? "\n" : "");
JonFreeman 12:d1d21a2941ef 94 // Format good to be unpicked by cli in touch screen controller
JonFreeman 8:93203f473f6e 95 }
JonFreeman 16:d1e4b9ad3b8b 96 */
JonFreeman 12:d1d21a2941ef 97 /**
JonFreeman 12:d1d21a2941ef 98 * void rvi_cmd (struct parameters & a) // read last normalised motor voltage and current values sent to pwms
JonFreeman 12:d1d21a2941ef 99 *
JonFreeman 12:d1d21a2941ef 100 */
JonFreeman 16:d1e4b9ad3b8b 101 //void rvi_cmd (struct parameters & a) // read last normalised values sent to pwms
JonFreeman 16:d1e4b9ad3b8b 102 //{
JonFreeman 16:d1e4b9ad3b8b 103 // if (a.respond)
JonFreeman 16:d1e4b9ad3b8b 104 // 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" : "");
JonFreeman 16:d1e4b9ad3b8b 105 //}
JonFreeman 6:f289a49c1eae 106
JonFreeman 12:d1d21a2941ef 107 /**
JonFreeman 12:d1d21a2941ef 108 * void fw_cmd (struct parameters & a) // Forward command
JonFreeman 12:d1d21a2941ef 109 * Broadcast to all STM3_ESC boards, required to ACT but NOT respond
JonFreeman 12:d1d21a2941ef 110 */
JonFreeman 12:d1d21a2941ef 111 void fw_cmd (struct parameters & a) // Forward command
JonFreeman 6:f289a49c1eae 112 {
JonFreeman 16:d1e4b9ad3b8b 113 // MotorA.set_mode (MOTOR_FORWARD);
JonFreeman 16:d1e4b9ad3b8b 114 // MotorB.set_mode (MOTOR_FORWARD);
JonFreeman 16:d1e4b9ad3b8b 115 mode_set_motors_both (MOTOR_FORWARD);
JonFreeman 12:d1d21a2941ef 116 if (a.source == SOURCE_PC)
JonFreeman 12:d1d21a2941ef 117 pc.printf ("fw\r\n"); // Show response to action if command from pc terminal
JonFreeman 6:f289a49c1eae 118 }
JonFreeman 6:f289a49c1eae 119
JonFreeman 12:d1d21a2941ef 120 /**
JonFreeman 12:d1d21a2941ef 121 * void re_cmd (struct parameters & a) // Reverse command
JonFreeman 12:d1d21a2941ef 122 * Broadcast to all STM3_ESC boards, required to ACT but NOT respond
JonFreeman 12:d1d21a2941ef 123 */
JonFreeman 12:d1d21a2941ef 124 void re_cmd (struct parameters & a) // Reverse command
JonFreeman 6:f289a49c1eae 125 {
JonFreeman 16:d1e4b9ad3b8b 126 mode_set_motors_both (MOTOR_REVERSE);
JonFreeman 12:d1d21a2941ef 127 if (a.source == SOURCE_PC)
JonFreeman 12:d1d21a2941ef 128 pc.printf ("re\r\n");
JonFreeman 8:93203f473f6e 129 }
JonFreeman 6:f289a49c1eae 130
JonFreeman 12:d1d21a2941ef 131 /**
JonFreeman 12:d1d21a2941ef 132 * void rb_cmd (struct parameters & a) // Regen brake command
JonFreeman 12:d1d21a2941ef 133 * Broadcast to all STM3_ESC boards, required to ACT but NOT respond
JonFreeman 12:d1d21a2941ef 134 */
JonFreeman 12:d1d21a2941ef 135 void rb_cmd (struct parameters & a) // Regen brake command
JonFreeman 6:f289a49c1eae 136 {
JonFreeman 16:d1e4b9ad3b8b 137 double tmp = a.dbl[0] / 100.0;
JonFreeman 16:d1e4b9ad3b8b 138 MotorA.brake (tmp);
JonFreeman 16:d1e4b9ad3b8b 139 MotorB.brake (tmp); // Corrected May 2020 - previously MotorA twice
JonFreeman 12:d1d21a2941ef 140 if (a.source == SOURCE_PC)
JonFreeman 16:d1e4b9ad3b8b 141 pc.printf ("rb %.2f\r\n", tmp);
JonFreeman 6:f289a49c1eae 142 }
JonFreeman 6:f289a49c1eae 143
JonFreeman 12:d1d21a2941ef 144 /**
JonFreeman 12:d1d21a2941ef 145 * void hb_cmd (struct parameters & a) // Hand brake command
JonFreeman 12:d1d21a2941ef 146 * Broadcast to all STM3_ESC boards, required to ACT but NOT respond
JonFreeman 12:d1d21a2941ef 147 *
JonFreeman 12:d1d21a2941ef 148 * NOTE Jan 2019 Hand brake not implemented
JonFreeman 16:d1e4b9ad3b8b 149 * May 2020 - Implemented, but not very good
JonFreeman 6:f289a49c1eae 150 */
JonFreeman 12:d1d21a2941ef 151 void hb_cmd (struct parameters & a) // Hand brake command
JonFreeman 6:f289a49c1eae 152 {
JonFreeman 16:d1e4b9ad3b8b 153 double tmp;
JonFreeman 16:d1e4b9ad3b8b 154 if (a.numof_dbls != 0) tmp = a.dbl[0] / 100.0; // a.numof_dbls is int32_t
JonFreeman 16:d1e4b9ad3b8b 155 else tmp = 0.33;
JonFreeman 6:f289a49c1eae 156 if (a.respond) {
JonFreeman 16:d1e4b9ad3b8b 157 // a.com->printf ("numof params = %d\r\n", a.numof_dbls);
JonFreeman 16:d1e4b9ad3b8b 158 a.com->printf ("Hand Brake : Force 0 to 99 %.0f\r\n", tmp * 100.0);
JonFreeman 6:f289a49c1eae 159 }
JonFreeman 16:d1e4b9ad3b8b 160 mode_set_motors_both (MOTOR_HANDBRAKE);
JonFreeman 16:d1e4b9ad3b8b 161 if (tmp < 0.0) tmp = 0.0;
JonFreeman 16:d1e4b9ad3b8b 162 if (tmp > 1.0) tmp = 1.0;
JonFreeman 16:d1e4b9ad3b8b 163 setVI_both (tmp / 5.0, 0.99);
JonFreeman 6:f289a49c1eae 164 }
JonFreeman 6:f289a49c1eae 165
JonFreeman 12:d1d21a2941ef 166
JonFreeman 16:d1e4b9ad3b8b 167
JonFreeman 16:d1e4b9ad3b8b 168
JonFreeman 16:d1e4b9ad3b8b 169 /**void user_settings_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents
JonFreeman 16:d1e4b9ad3b8b 170 * user_settings_cmd called only from pc comms. No sense calling from Touch Screen Controller
JonFreeman 12:d1d21a2941ef 171 *
JonFreeman 12:d1d21a2941ef 172 * Called without parameters - Lists to pc terminal current settings
JonFreeman 12:d1d21a2941ef 173 *
JonFreeman 12:d1d21a2941ef 174 */
JonFreeman 16:d1e4b9ad3b8b 175 void user_settings_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents
JonFreeman 12:d1d21a2941ef 176 {
JonFreeman 16:d1e4b9ad3b8b 177 user_settings.edit (a.dbl, a.numof_dbls);
JonFreeman 16:d1e4b9ad3b8b 178 }
JonFreeman 16:d1e4b9ad3b8b 179
JonFreeman 16:d1e4b9ad3b8b 180 extern struct optpar option_list[] ; //= {
JonFreeman 12:d1d21a2941ef 181
JonFreeman 16:d1e4b9ad3b8b 182 void brake_eff_set_cmd (struct parameters & a) { // set brake effectiveness from TS May 2020
JonFreeman 16:d1e4b9ad3b8b 183 char be = (char) a.dbl[0];
JonFreeman 16:d1e4b9ad3b8b 184 pc.printf ("BRAKE_EFFECTIVENESS min = %d, max = %d\r\n", option_list[BRAKE_EFFECTIVENESS].min, option_list[BRAKE_EFFECTIVENESS].max);
JonFreeman 16:d1e4b9ad3b8b 185 if (be > option_list[BRAKE_EFFECTIVENESS].max) be = option_list[BRAKE_EFFECTIVENESS].max;
JonFreeman 16:d1e4b9ad3b8b 186 if (be < option_list[BRAKE_EFFECTIVENESS].min) be = option_list[BRAKE_EFFECTIVENESS].min;
JonFreeman 16:d1e4b9ad3b8b 187 user_settings.wr(be, BRAKE_EFFECTIVENESS);
JonFreeman 16:d1e4b9ad3b8b 188 user_settings.save ();
JonFreeman 16:d1e4b9ad3b8b 189 pc.printf ("Set brake effectiveness to %d pct\r\n", be);
JonFreeman 12:d1d21a2941ef 190 }
JonFreeman 12:d1d21a2941ef 191
JonFreeman 16:d1e4b9ad3b8b 192 void ssl_cmd (struct parameters & a) { // set speed limit NEW and untested July 2019. Stored as speed * 10 to get 1dec place
JonFreeman 16:d1e4b9ad3b8b 193 char sp = (char) (a.dbl[0] * 10.0);
JonFreeman 16:d1e4b9ad3b8b 194 if (sp > option_list[TOP_SPEED].max) sp = option_list[TOP_SPEED].max;
JonFreeman 16:d1e4b9ad3b8b 195 if (sp < option_list[TOP_SPEED].min) sp = option_list[TOP_SPEED].min;
JonFreeman 16:d1e4b9ad3b8b 196 user_settings.wr(sp, TOP_SPEED);
JonFreeman 16:d1e4b9ad3b8b 197 user_settings.save ();
JonFreeman 16:d1e4b9ad3b8b 198 pc.printf ("Set speed limit to %.1f mph\r\n", a.dbl[0]);
JonFreeman 13:ef7a06fa11de 199 }
JonFreeman 13:ef7a06fa11de 200
JonFreeman 12:d1d21a2941ef 201 /**
JonFreeman 12:d1d21a2941ef 202 * void temperature_cmd (struct parameters & a) {
JonFreeman 16:d1e4b9ad3b8b 203 * Few boards have temperature sensor fitted. Now only supports LM75B i2c sensor
JonFreeman 12:d1d21a2941ef 204 */
JonFreeman 17:cc9b854295d6 205 /*void read_temperature_cmd (struct parameters & a) {
JonFreeman 16:d1e4b9ad3b8b 206 float t = -99.25;
JonFreeman 6:f289a49c1eae 207 if (a.respond) {
JonFreeman 16:d1e4b9ad3b8b 208 a.com->printf ("tem%c ", user_settings.rd(BOARD_ID));
JonFreeman 16:d1e4b9ad3b8b 209 if (read_temperature(t))
JonFreeman 16:d1e4b9ad3b8b 210 a.com->printf ("Temperature = %7.3f\r\n", t);
JonFreeman 16:d1e4b9ad3b8b 211 else
JonFreeman 16:d1e4b9ad3b8b 212 a.com->printf ("Temp sensor not fitted\r\n");
JonFreeman 6:f289a49c1eae 213 }
JonFreeman 17:cc9b854295d6 214 }*/
JonFreeman 6:f289a49c1eae 215
JonFreeman 12:d1d21a2941ef 216 /**
JonFreeman 12:d1d21a2941ef 217 *void rpm_cmd (struct parameters & a) // to report e.g. RPM 1000 1000 ; speed for both motors
JonFreeman 12:d1d21a2941ef 218 */
JonFreeman 6:f289a49c1eae 219 void rpm_cmd (struct parameters & a) // to report e.g. RPM 1000 1000 ; speed for both motors
JonFreeman 6:f289a49c1eae 220 {
JonFreeman 11:bfb73f083009 221 if (a.respond)
JonFreeman 16:d1e4b9ad3b8b 222 // a.com->printf ("rpm%c %d %d\r%s", user_settings.rd(BOARD_ID), MotorA.RPM, MotorB.RPM, a.source == SOURCE_PC ? "\n" : "");
JonFreeman 16:d1e4b9ad3b8b 223 a.com->printf ("rpm%c %.0f %.0f\r%s", user_settings.rd(BOARD_ID), MotorA.dRPM, MotorB.dRPM, a.source == SOURCE_PC ? "\n" : "");
JonFreeman 6:f289a49c1eae 224 }
JonFreeman 6:f289a49c1eae 225
JonFreeman 12:d1d21a2941ef 226 /**
JonFreeman 12:d1d21a2941ef 227 *void mph_cmd (struct parameters & a) // to report miles per hour
JonFreeman 12:d1d21a2941ef 228 */
JonFreeman 16:d1e4b9ad3b8b 229 void mph_cmd (struct parameters & a) // to report miles per hour to 1 decimal place - now 2dp May 2020
JonFreeman 7:6deaeace9a3e 230 {
JonFreeman 16:d1e4b9ad3b8b 231 int j = 0;
JonFreeman 16:d1e4b9ad3b8b 232 double speedmph = 0.0;
JonFreeman 16:d1e4b9ad3b8b 233 if (MotorA.exists ()) {
JonFreeman 16:d1e4b9ad3b8b 234 j |= 1;
JonFreeman 16:d1e4b9ad3b8b 235 speedmph = MotorA.dMPH;
JonFreeman 16:d1e4b9ad3b8b 236 }
JonFreeman 16:d1e4b9ad3b8b 237 if (MotorB.exists ()) {
JonFreeman 16:d1e4b9ad3b8b 238 j |= 2;
JonFreeman 16:d1e4b9ad3b8b 239 speedmph += MotorB.dMPH;
JonFreeman 16:d1e4b9ad3b8b 240 }
JonFreeman 16:d1e4b9ad3b8b 241 if (j == 3)
JonFreeman 16:d1e4b9ad3b8b 242 speedmph /= 2.0;
JonFreeman 11:bfb73f083009 243 if (a.respond)
JonFreeman 16:d1e4b9ad3b8b 244 // May 17th 2020 modified line below - removed superfluous cast, upped to 2 decimal places
JonFreeman 16:d1e4b9ad3b8b 245 // a.com->printf ("mph%c %.2f\r%s", user_settings.rd(BOARD_ID), speedmph, a.source == SOURCE_PC ? "\n" : "");
JonFreeman 16:d1e4b9ad3b8b 246 a.com->printf ("?s%c %.2f\r%s", user_settings.rd(BOARD_ID), speedmph, a.source == SOURCE_PC ? "\n" : "");
JonFreeman 12:d1d21a2941ef 247 }
JonFreeman 12:d1d21a2941ef 248
JonFreeman 12:d1d21a2941ef 249 /**
JonFreeman 12:d1d21a2941ef 250 *void sysV_report (struct parameters & a) // to report system voltage
JonFreeman 12:d1d21a2941ef 251 * Reports system link voltage to one decimal place
JonFreeman 12:d1d21a2941ef 252 */
JonFreeman 12:d1d21a2941ef 253 void sysV_report (struct parameters & a) //
JonFreeman 12:d1d21a2941ef 254 {
JonFreeman 12:d1d21a2941ef 255 if (a.respond)
JonFreeman 16:d1e4b9ad3b8b 256 a.com->printf ("?v%c %.1f\r%s", user_settings.rd(BOARD_ID), Read_BatteryVolts(), a.source == SOURCE_PC ? "\n" : "");
JonFreeman 7:6deaeace9a3e 257 }
JonFreeman 7:6deaeace9a3e 258
JonFreeman 12:d1d21a2941ef 259 /**
JonFreeman 12:d1d21a2941ef 260 *void sysI_report (struct parameters & a) // to report motor currents
JonFreeman 12:d1d21a2941ef 261 * Reports doubles for each motor current amps to 2 decimal places
JonFreeman 12:d1d21a2941ef 262 */
JonFreeman 12:d1d21a2941ef 263 void sysI_report (struct parameters & a) //
JonFreeman 12:d1d21a2941ef 264 {
JonFreeman 16:d1e4b9ad3b8b 265 if (a.respond)
JonFreeman 16:d1e4b9ad3b8b 266 a.com->printf ("?i%c %.2f %.2f\r%s", user_settings.rd(BOARD_ID), MotorA.Idbl, MotorB.Idbl, a.source == SOURCE_PC ? "\n" : "");
JonFreeman 12:d1d21a2941ef 267 }
JonFreeman 6:f289a49c1eae 268
JonFreeman 16:d1e4b9ad3b8b 269 /*
JonFreeman 16:d1e4b9ad3b8b 270
JonFreeman 16:d1e4b9ad3b8b 271 New December 2019 - possible for implementation
JonFreeman 16:d1e4b9ad3b8b 272 Having implemented radio control inputs and driver pot, there is some sense in moving slider handler from touch screen controller
JonFreeman 16:d1e4b9ad3b8b 273 into STM3_ESC code.
JonFreeman 16:d1e4b9ad3b8b 274 New instructions to be accepted from touch screen : -
JonFreeman 16:d1e4b9ad3b8b 275 {"w", "touch screen new slider touch", slider_touch_cmd},
JonFreeman 16:d1e4b9ad3b8b 276 {"x", "updated slider RANGE 0 to 99", slider_touch_position_cmd}, // max two digits
JonFreeman 16:d1e4b9ad3b8b 277 {"y", "touch_screen slider finger lifted clear", slider_untouch_cmd},
JonFreeman 16:d1e4b9ad3b8b 278 */
JonFreeman 16:d1e4b9ad3b8b 279 bool finger_on_slider = false;
JonFreeman 16:d1e4b9ad3b8b 280 /**void slider_touch_cmd (struct parameters & a)
JonFreeman 16:d1e4b9ad3b8b 281 *
JonFreeman 16:d1e4b9ad3b8b 282 * Message from touch screen controller, slider touched
JonFreeman 16:d1e4b9ad3b8b 283 */
JonFreeman 16:d1e4b9ad3b8b 284 void slider_touch_cmd (struct parameters & a) {
JonFreeman 16:d1e4b9ad3b8b 285 finger_on_slider = true;
JonFreeman 16:d1e4b9ad3b8b 286 }
JonFreeman 16:d1e4b9ad3b8b 287
JonFreeman 16:d1e4b9ad3b8b 288 /**void slider_untouch_cmd (struct parameters & a)
JonFreeman 16:d1e4b9ad3b8b 289 *
JonFreeman 16:d1e4b9ad3b8b 290 * Message from touch screen controller, finger taken off slider
JonFreeman 16:d1e4b9ad3b8b 291 */
JonFreeman 16:d1e4b9ad3b8b 292 void slider_untouch_cmd (struct parameters & a) {
JonFreeman 16:d1e4b9ad3b8b 293 finger_on_slider = false;
JonFreeman 16:d1e4b9ad3b8b 294 }
JonFreeman 16:d1e4b9ad3b8b 295
JonFreeman 16:d1e4b9ad3b8b 296 /**void slider_touch_position_cmd (struct parameters & a)
JonFreeman 16:d1e4b9ad3b8b 297 *
JonFreeman 16:d1e4b9ad3b8b 298 * Message from touch screen controller, latest slider touch position
JonFreeman 16:d1e4b9ad3b8b 299 */
JonFreeman 16:d1e4b9ad3b8b 300 void slider_touch_position_cmd (struct parameters & a) {
JonFreeman 16:d1e4b9ad3b8b 301 }
JonFreeman 16:d1e4b9ad3b8b 302
JonFreeman 16:d1e4b9ad3b8b 303 // End of New December 2019
JonFreeman 16:d1e4b9ad3b8b 304
JonFreeman 12:d1d21a2941ef 305
JonFreeman 12:d1d21a2941ef 306 /**void vi_cmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 307 *
JonFreeman 12:d1d21a2941ef 308 * For setting motor voltage and current limits from pc terminal for test
JonFreeman 12:d1d21a2941ef 309 */
JonFreeman 6:f289a49c1eae 310 void vi_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 311 {
JonFreeman 16:d1e4b9ad3b8b 312 setVI_both (a.dbl[0] / 100.0, a.dbl[1] / 100.0);
JonFreeman 16:d1e4b9ad3b8b 313 // pc.printf ("setVI_both from %s\r\n", a.source == SOURCE_PC ? "PC" : "Touch Screen");
JonFreeman 6:f289a49c1eae 314 }
JonFreeman 6:f289a49c1eae 315
JonFreeman 12:d1d21a2941ef 316 /**
JonFreeman 12:d1d21a2941ef 317 *void v_cmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 318 * Set motor voltage limit from either source without checking for addressed board
JonFreeman 12:d1d21a2941ef 319 */
JonFreeman 6:f289a49c1eae 320 void v_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 321 {
JonFreeman 12:d1d21a2941ef 322 MotorA.set_V_limit (a.dbl[0] / 100.0);
JonFreeman 12:d1d21a2941ef 323 MotorB.set_V_limit (a.dbl[0] / 100.0);
JonFreeman 6:f289a49c1eae 324 }
JonFreeman 6:f289a49c1eae 325
JonFreeman 12:d1d21a2941ef 326 /**
JonFreeman 12:d1d21a2941ef 327 *void i_cmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 328 * Set motor current limit from either source without checking for addressed board
JonFreeman 12:d1d21a2941ef 329 */
JonFreeman 6:f289a49c1eae 330 void i_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 331 {
JonFreeman 12:d1d21a2941ef 332 MotorA.set_I_limit (a.dbl[0] / 100.0);
JonFreeman 12:d1d21a2941ef 333 MotorB.set_I_limit (a.dbl[0] / 100.0);
JonFreeman 6:f289a49c1eae 334 }
JonFreeman 6:f289a49c1eae 335
JonFreeman 12:d1d21a2941ef 336 /**
JonFreeman 12:d1d21a2941ef 337 *void kd_cmd (struct parameters & a) // kick and enable the watch dog
JonFreeman 12:d1d21a2941ef 338 *
JonFreeman 13:ef7a06fa11de 339 * Brute_TS_Controller or other external controller to issue regular 'kd\r' to come here.
JonFreeman 13:ef7a06fa11de 340 * WatchDog disabled by default, enabled on first call to here
JonFreeman 13:ef7a06fa11de 341 * This is where WatchDog timer is reset and reloaded.
JonFreeman 13:ef7a06fa11de 342 * Timeout may be detected and handled in 8Hz loop in main programme loop
JonFreeman 12:d1d21a2941ef 343 */
JonFreeman 12:d1d21a2941ef 344 void kd_cmd (struct parameters & a) // kick the watchdog. Reached from TS or pc.
JonFreeman 6:f289a49c1eae 345 {
JonFreeman 16:d1e4b9ad3b8b 346 WatchDog = WATCHDOG_RELOAD + (user_settings.rd(BOARD_ID) & 0x0f); // Reload watchdog timeout. Counted down @ 8Hz
JonFreeman 12:d1d21a2941ef 347 WatchDogEnable = true; // Receipt of this command sufficient to enable watchdog
JonFreeman 6:f289a49c1eae 348 }
JonFreeman 6:f289a49c1eae 349
JonFreeman 13:ef7a06fa11de 350 void wd_report (struct parameters & a) // Reachable always from pc. Only addressed board responds to TS
JonFreeman 13:ef7a06fa11de 351 {
JonFreeman 13:ef7a06fa11de 352 pc.printf ("WatchDog %d\r\n", WatchDog);
JonFreeman 13:ef7a06fa11de 353 }
JonFreeman 12:d1d21a2941ef 354 /**
JonFreeman 12:d1d21a2941ef 355 *void who_cmd (struct parameters & a) // Reachable always from pc. Only addressed board responds to TS
JonFreeman 12:d1d21a2941ef 356 *
JonFreeman 12:d1d21a2941ef 357 * When using STM3_ESC boards together with 'Brute Touch Screen Controller', controller needs to identify number and identity
JonFreeman 12:d1d21a2941ef 358 * of all connected STM3_ESC boards. To do this the Touch Screen issues '0who', '1who' ... '9who' allowing time between each
JonFreeman 12:d1d21a2941ef 359 * for an identified STM3_ESC to respond with 'who7' (if it was number 7) without causing contention of paralleled serial opto isolated bus
JonFreeman 12:d1d21a2941ef 360 */
JonFreeman 12:d1d21a2941ef 361 void who_cmd (struct parameters & a) // Reachable always from pc. Only addressed board responds to TS
JonFreeman 6:f289a49c1eae 362 {
JonFreeman 16:d1e4b9ad3b8b 363 if (a.source == SOURCE_PC || user_settings.rd(BOARD_ID) == a.target_unit)
JonFreeman 16:d1e4b9ad3b8b 364 a.com->printf ("who%c\r%s", user_settings.rd(BOARD_ID), a.source == SOURCE_PC ? "\n" : "");
JonFreeman 6:f289a49c1eae 365 }
JonFreeman 6:f289a49c1eae 366
JonFreeman 17:cc9b854295d6 367 extern void rcins_report () ;
JonFreeman 17:cc9b854295d6 368 void qrc_cmd (struct parameters & a) // report RC1 and RC2 input condition and activity
JonFreeman 17:cc9b854295d6 369 {
JonFreeman 17:cc9b854295d6 370 rcins_report ();
JonFreeman 17:cc9b854295d6 371 }
JonFreeman 17:cc9b854295d6 372
JonFreeman 12:d1d21a2941ef 373 /**
JonFreeman 12:d1d21a2941ef 374 *void rcin_pccmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 375 *
JonFreeman 12:d1d21a2941ef 376 * For test, reports to pc terminal info about radio control input channels
JonFreeman 12:d1d21a2941ef 377 */
JonFreeman 16:d1e4b9ad3b8b 378 //void rcin_pccmd (struct parameters & a)
JonFreeman 16:d1e4b9ad3b8b 379 //{
JonFreeman 16:d1e4b9ad3b8b 380 // rcin_report ();
JonFreeman 16:d1e4b9ad3b8b 381 //}
JonFreeman 16:d1e4b9ad3b8b 382 /*
JonFreeman 12:d1d21a2941ef 383 void scmd (struct parameters & a) // filter coefficient fiddler
JonFreeman 12:d1d21a2941ef 384 {
JonFreeman 12:d1d21a2941ef 385 switch ((int)a.dbl[0]) {
JonFreeman 12:d1d21a2941ef 386 case 1:
JonFreeman 13:ef7a06fa11de 387 MotorA.sdbl[1] = MotorB.sdbl[1] = a.dbl[1];
JonFreeman 12:d1d21a2941ef 388 break;
JonFreeman 12:d1d21a2941ef 389 case 2:
JonFreeman 13:ef7a06fa11de 390 MotorA.sdbl[2] = MotorB.sdbl[2] = a.dbl[1];
JonFreeman 12:d1d21a2941ef 391 break;
JonFreeman 12:d1d21a2941ef 392 case 3:
JonFreeman 13:ef7a06fa11de 393 MotorA.sdbl[3] = MotorB.sdbl[3] = a.dbl[1];
JonFreeman 12:d1d21a2941ef 394 break;
JonFreeman 12:d1d21a2941ef 395 case 4:
JonFreeman 13:ef7a06fa11de 396 MotorA.sdbl[4] = MotorB.sdbl[4] = a.dbl[1];
JonFreeman 12:d1d21a2941ef 397 break;
JonFreeman 12:d1d21a2941ef 398 default:
JonFreeman 12:d1d21a2941ef 399 pc.printf ("Wrong use of scmd %f\r\n", a.dbl[0]);
JonFreeman 12:d1d21a2941ef 400 }
JonFreeman 13:ef7a06fa11de 401 pc.printf ("Filter Coefficient Fiddler - used in brushless_motor::speed_monitor_and_control ()");
JonFreeman 12:d1d21a2941ef 402 pc.printf ("Filter Coeffs 1 to 4\r\n");
JonFreeman 13:ef7a06fa11de 403 pc.printf ("1 %.3f\tPscale 0.01-0.5\r\n", MotorA.sdbl[1]);
JonFreeman 13:ef7a06fa11de 404 pc.printf ("2 %.3f\tP_gain 1.0-1000.0\r\n", MotorA.sdbl[2]);
JonFreeman 13:ef7a06fa11de 405 pc.printf ("3 %.3f\tDscale 0.01-0.5\r\n", MotorA.sdbl[3]);
JonFreeman 13:ef7a06fa11de 406 pc.printf ("4 %.3f\tD_gain 1.0-1000.0\r\n", MotorA.sdbl[4]);
JonFreeman 16:d1e4b9ad3b8b 407 // pc.printf ("5 Set target_speed\r\n");
JonFreeman 12:d1d21a2941ef 408 }
JonFreeman 16:d1e4b9ad3b8b 409 */
JonFreeman 12:d1d21a2941ef 410 struct kb_command { // Commands tabulated as list of these structures as seen below
JonFreeman 12:d1d21a2941ef 411 const char * cmd_word; // points to text e.g. "menu"
JonFreeman 12:d1d21a2941ef 412 const char * explan; // very brief explanation or clue as to purpose of function
JonFreeman 12:d1d21a2941ef 413 void (*f)(struct parameters &); // points to function
JonFreeman 12:d1d21a2941ef 414 } ; // Positioned in code here as knowledge needed by following menucmd
JonFreeman 12:d1d21a2941ef 415
JonFreeman 12:d1d21a2941ef 416 /**
JonFreeman 12:d1d21a2941ef 417 * void menucmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 418 *
JonFreeman 12:d1d21a2941ef 419 * List available terminal commands to pc terminal. No sense in touch screen using this
JonFreeman 12:d1d21a2941ef 420 */
JonFreeman 12:d1d21a2941ef 421 void menucmd (struct parameters & a)
JonFreeman 12:d1d21a2941ef 422 {
JonFreeman 12:d1d21a2941ef 423 if (a.respond) {
JonFreeman 16:d1e4b9ad3b8b 424 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");
JonFreeman 12:d1d21a2941ef 425 for(int i = 0; i < a.numof_menu_items; i++)
JonFreeman 12:d1d21a2941ef 426 a.com->printf("[%s]\t\t%s\r\n", a.command_list[i].cmd_word, a.command_list[i].explan);
JonFreeman 12:d1d21a2941ef 427 a.com->printf("End of List of Commands\r\n");
JonFreeman 12:d1d21a2941ef 428 }
JonFreeman 12:d1d21a2941ef 429 }
JonFreeman 12:d1d21a2941ef 430
JonFreeman 12:d1d21a2941ef 431 /********************** END OF COMMAND LINE INTERPRETER COMMANDS *************************************/
JonFreeman 6:f289a49c1eae 432
JonFreeman 9:ac2412df01be 433
JonFreeman 9:ac2412df01be 434 /**
JonFreeman 12:d1d21a2941ef 435 * struct kb_command const loco_command_list[] = {
JonFreeman 12:d1d21a2941ef 436 * List of commands accepted from external controller through opto isolated com port 19200, 8,n,1
JonFreeman 9:ac2412df01be 437 */
JonFreeman 12:d1d21a2941ef 438 struct kb_command const loco_command_list[] = { // For comms between STM3_ESC and 'Brute Touch Screen Controller'
JonFreeman 12:d1d21a2941ef 439 // ***** Broadcast commands for all STM3_ESC boards to execute. Boards NOT to send serial response *****
JonFreeman 6:f289a49c1eae 440 {"fw", "forward", fw_cmd},
JonFreeman 6:f289a49c1eae 441 {"re", "reverse", re_cmd},
JonFreeman 16:d1e4b9ad3b8b 442 {"rb", "regen brake 0 to 99 %", rb_cmd}, // max two digits
JonFreeman 6:f289a49c1eae 443 {"hb", "hand brake", hb_cmd},
JonFreeman 16:d1e4b9ad3b8b 444 {"v", "set motors V percent RANGE 0 to 99", v_cmd},
JonFreeman 16:d1e4b9ad3b8b 445 {"i", "set motors I percent RANGE 0 to 99", i_cmd},
JonFreeman 16:d1e4b9ad3b8b 446 {"vi", "set motors V and I percent RANGE 0 to 99", vi_cmd},
JonFreeman 16:d1e4b9ad3b8b 447 {"w", "touch screen new slider touch", slider_touch_cmd},
JonFreeman 16:d1e4b9ad3b8b 448 {"x", "updated slider RANGE 0 to 99", slider_touch_position_cmd},
JonFreeman 16:d1e4b9ad3b8b 449 {"y", "touch_screen slider finger lifted clear", slider_untouch_cmd},
JonFreeman 12:d1d21a2941ef 450 {"kd", "kick the dog, reloads WatchDog", kd_cmd},
JonFreeman 16:d1e4b9ad3b8b 451 {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019
JonFreeman 16:d1e4b9ad3b8b 452 {"sbe", "set brake effectiveness 5 to 90 percent", brake_eff_set_cmd}, // NEW May 2020
JonFreeman 12:d1d21a2941ef 453 // ***** Endof Broadcast commands for all STM3_ESC boards to execute. Boards NOT to send serial response *****
JonFreeman 12:d1d21a2941ef 454
JonFreeman 12:d1d21a2941ef 455 // ***** Following are rx'd requests for serial response from addressed STM3_ESC only
JonFreeman 12:d1d21a2941ef 456 {"?v", "Report system bus voltage", sysV_report},
JonFreeman 12:d1d21a2941ef 457 {"?i", "Report motor both currents", sysI_report},
JonFreeman 8:93203f473f6e 458 {"who", "search for connected units, e.g. 3who returs 'who3' if found", who_cmd},
JonFreeman 17:cc9b854295d6 459 // {"tem", "report temperature", read_temperature_cmd},
JonFreeman 8:93203f473f6e 460 {"mph", "read loco speed miles per hour", mph_cmd},
JonFreeman 16:d1e4b9ad3b8b 461 {"?s", "read loco speed miles per hour", mph_cmd}, // Shorter-hand added 17th May 2020
JonFreeman 16:d1e4b9ad3b8b 462 // {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019
JonFreeman 16:d1e4b9ad3b8b 463 // {"sbe", "set brake effectiveness 5 to 90 percent", brake_eff_set_cmd}, // NEW May 2020
JonFreeman 12:d1d21a2941ef 464 // {"rvi", "read most recent values sent to pwms", rvi_cmd},
JonFreeman 12:d1d21a2941ef 465 // {"rdi", "read motor currents and power voltage", rdi_cmd},
JonFreeman 12:d1d21a2941ef 466 // ***** Endof
JonFreeman 12:d1d21a2941ef 467 } ;
JonFreeman 7:6deaeace9a3e 468
JonFreeman 7:6deaeace9a3e 469
JonFreeman 9:ac2412df01be 470 /**
JonFreeman 9:ac2412df01be 471 struct kb_command const loco_command_list[] = {
JonFreeman 9:ac2412df01be 472 List of commands accepted from external pc through non-opto isolated com port 9600, 8,n,1
JonFreeman 9:ac2412df01be 473 */
JonFreeman 7:6deaeace9a3e 474 struct kb_command const pc_command_list[] = {
JonFreeman 7:6deaeace9a3e 475 {"ls", "Lists available commands", menucmd},
JonFreeman 7:6deaeace9a3e 476 {"?", "Lists available commands, same as ls", menucmd},
JonFreeman 8:93203f473f6e 477 {"pot", "read drivers control pot", pot_cmd},
JonFreeman 7:6deaeace9a3e 478 {"fw", "forward", fw_cmd},
JonFreeman 7:6deaeace9a3e 479 {"re", "reverse", re_cmd},
JonFreeman 7:6deaeace9a3e 480 {"rb", "regen brake 0 to 99 %", rb_cmd},
JonFreeman 7:6deaeace9a3e 481 {"hb", "hand brake", hb_cmd},
JonFreeman 7:6deaeace9a3e 482 {"v", "set motors V percent RANGE 0 to 100", v_cmd},
JonFreeman 7:6deaeace9a3e 483 {"i", "set motors I percent RANGE 0 to 100", i_cmd},
JonFreeman 7:6deaeace9a3e 484 {"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd},
JonFreeman 12:d1d21a2941ef 485 {"?v", "Report system bus voltage", sysV_report},
JonFreeman 12:d1d21a2941ef 486 {"?i", "Report motor both currents", sysI_report},
JonFreeman 13:ef7a06fa11de 487 {"?w", "show WatchDog timer contents", wd_report},
JonFreeman 17:cc9b854295d6 488 {"kd", "kick the dog, reloads WatchDog", kd_cmd},
JonFreeman 8:93203f473f6e 489 {"who", "search for connected units, e.g. 3who returs 'who3' if found", who_cmd},
JonFreeman 16:d1e4b9ad3b8b 490 {"us", "read or set user settings in eeprom", user_settings_cmd}, // Big change Jan 2019
JonFreeman 13:ef7a06fa11de 491 {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019 ONLY HERE FOR TEST, normal use is from Touch Screen only.
JonFreeman 16:d1e4b9ad3b8b 492 {"sbe", "set brake effectiveness 5 to 90 percent", brake_eff_set_cmd}, // NEW May 2020
JonFreeman 12:d1d21a2941ef 493 // {"erase", "set eeprom contents to all 0xff", erase_cmd},
JonFreeman 17:cc9b854295d6 494 // {"tem", "report temperature", read_temperature_cmd}, // Reports -50 when sensor not fitted
JonFreeman 12:d1d21a2941ef 495 {"ver", "Version", ver_cmd},
JonFreeman 7:6deaeace9a3e 496 {"rpm", "read motor pair speeds", rpm_cmd},
JonFreeman 17:cc9b854295d6 497 // {"mph", "read loco speed miles per hour", mph_cmd},
JonFreeman 16:d1e4b9ad3b8b 498 {"?s", "read loco speed miles per hour", mph_cmd},
JonFreeman 17:cc9b854295d6 499 {"?rc", "report RC1 and RC2 input condition and activity", qrc_cmd},
JonFreeman 16:d1e4b9ad3b8b 500 // {"rvi", "read most recent values sent to pwms", rvi_cmd},
JonFreeman 16:d1e4b9ad3b8b 501 // {"rdi", "read motor currents and power voltage", rdi_cmd},
JonFreeman 12:d1d21a2941ef 502 // {"bc", "bogie constants - wheel dia, motor pinion, wheel gear", bogie_constants_report_cmd},
JonFreeman 12:d1d21a2941ef 503 // {"gbb", "get bogie bytes from eeprom and report", gbb_cmd}, // OBSOLETE, replaced by 'gbb'
JonFreeman 7:6deaeace9a3e 504 {"nu", "do nothing", null_cmd},
JonFreeman 12:d1d21a2941ef 505 } ;
JonFreeman 7:6deaeace9a3e 506
JonFreeman 12:d1d21a2941ef 507 // cli_2019 (BufferedSerial * comport, kb_command const * list, int list_len, int source) {
JonFreeman 12:d1d21a2941ef 508 /**
JonFreeman 12:d1d21a2941ef 509 * cli_2019 pcc (&pc, pc_command_list, sizeof(pc_command_list) / sizeof(kb_command), SOURCE_PC) ;
JonFreeman 12:d1d21a2941ef 510 * cli_2019 tsc (&com2, loco_command_list, sizeof(loco_command_list) / sizeof(kb_command), SOURCE_TS) ;
JonFreeman 12:d1d21a2941ef 511 *
JonFreeman 12:d1d21a2941ef 512 * Instantiate two Command Line Interpreters, one for pc terminal and one for touch screen controller
JonFreeman 12:d1d21a2941ef 513 */
JonFreeman 12:d1d21a2941ef 514 cli_2019 pcc (&pc, pc_command_list, sizeof(pc_command_list) / sizeof(kb_command), SOURCE_PC) ;
JonFreeman 12:d1d21a2941ef 515 cli_2019 tsc (&com2, loco_command_list, sizeof(loco_command_list) / sizeof(kb_command), SOURCE_TS) ;
JonFreeman 6:f289a49c1eae 516
JonFreeman 6:f289a49c1eae 517 /*
JonFreeman 6:f289a49c1eae 518 New - March 2018
JonFreeman 12:d1d21a2941ef 519 Using opto isolated serial port, paralleled up using same pair to multiple STM3_ESC boards running this code.
JonFreeman 6:f289a49c1eae 520 New feature - commands have optional prefix digit 0-9 indicating which unit message is addressed to.
JonFreeman 6:f289a49c1eae 521 Commands without prefix digit - broadcast to all units, all to obey but none to respond.
JonFreeman 6:f289a49c1eae 522 Only units recognising its address from prefix digit may respond. This avoids bus contention.
JonFreeman 6:f289a49c1eae 523 But for BROADCAST commands, '0' may respond on behalf of the group
JonFreeman 6:f289a49c1eae 524 */
JonFreeman 12:d1d21a2941ef 525
JonFreeman 12:d1d21a2941ef 526 /**
JonFreeman 12:d1d21a2941ef 527 * void cli_2019::test () {
JonFreeman 12:d1d21a2941ef 528 *
JonFreeman 12:d1d21a2941ef 529 * Daft check that class instantiation worked
JonFreeman 12:d1d21a2941ef 530 */
JonFreeman 16:d1e4b9ad3b8b 531 void cli_2019::flush () {
JonFreeman 16:d1e4b9ad3b8b 532 // char ch;
JonFreeman 16:d1e4b9ad3b8b 533 while (a.com->readable())
JonFreeman 16:d1e4b9ad3b8b 534 a.com->getc();
JonFreeman 16:d1e4b9ad3b8b 535 //pc.printf ("At cli2019::test, source %d len %d,\r\n", a.source, a.numof_menu_items);
JonFreeman 12:d1d21a2941ef 536 }
JonFreeman 12:d1d21a2941ef 537
JonFreeman 12:d1d21a2941ef 538 /**
JonFreeman 12:d1d21a2941ef 539 * void cli_2019::core () {
JonFreeman 12:d1d21a2941ef 540 *
JonFreeman 12:d1d21a2941ef 541 * Command Line Interpreter.
JonFreeman 12:d1d21a2941ef 542 * This to be called every few milli secs from main programme loop.
JonFreeman 12:d1d21a2941ef 543 * Reads any rx'd chars into command line buffer, returns when serial buffer empty.
JonFreeman 12:d1d21a2941ef 544 * If last char rx'd war '\r' end of text delimiter, apt command_list is searched for a matched command in command line
JonFreeman 12:d1d21a2941ef 545 * If matched command found, apt function is executed.
JonFreeman 12:d1d21a2941ef 546 * Parameters available to functions from 'parameters' struct.
JonFreeman 12:d1d21a2941ef 547 */
JonFreeman 12:d1d21a2941ef 548 void cli_2019::core () {
JonFreeman 16:d1e4b9ad3b8b 549 int ch, IAm = user_settings.rd(BOARD_ID);
JonFreeman 7:6deaeace9a3e 550 char * pEnd;//, * cmd_line_ptr;
JonFreeman 7:6deaeace9a3e 551 while (a.com->readable()) {
JonFreeman 7:6deaeace9a3e 552 ch = a.com->getc();
JonFreeman 12:d1d21a2941ef 553 if (clindex > MAX_CMD_LEN) { // trap out stupidly long command lines
JonFreeman 12:d1d21a2941ef 554 ESC_Error.set (FAULT_COM_LINE_LEN, 1); // Set FAULT_EEPROM bit 0 if 24LC64 problem
JonFreeman 7:6deaeace9a3e 555 a.com->printf ("Error!! Stupidly long cmd line\r\n");
JonFreeman 12:d1d21a2941ef 556 clindex = 0;
JonFreeman 7:6deaeace9a3e 557 }
JonFreeman 11:bfb73f083009 558 if(ch != '\r') { // was this the 'Enter' key?
JonFreeman 11:bfb73f083009 559 if (ch != '\n') // Ignore line feeds
JonFreeman 12:d1d21a2941ef 560 cmdline[clindex++] = ch; // added char to command being assembled
JonFreeman 11:bfb73f083009 561 }
JonFreeman 7:6deaeace9a3e 562 else { // key was CR, may or may not be command to lookup
JonFreeman 7:6deaeace9a3e 563 a.target_unit = BROADCAST; // Set to BROADCAST default once found command line '\r'
JonFreeman 12:d1d21a2941ef 564 cmdline_ptr = cmdline;
JonFreeman 12:d1d21a2941ef 565 cmdline[clindex] = 0; // null terminate command string
JonFreeman 12:d1d21a2941ef 566 if(clindex) { // If have got some chars to lookup
JonFreeman 7:6deaeace9a3e 567 int i, wrdlen;
JonFreeman 12:d1d21a2941ef 568 if (isdigit(cmdline[0])) { // Look for command with prefix digit
JonFreeman 12:d1d21a2941ef 569 cmdline_ptr++; // point past identified digit prefix
JonFreeman 12:d1d21a2941ef 570 a.target_unit = cmdline[0]; // '0' to '9'
JonFreeman 7:6deaeace9a3e 571 //com->printf ("Got prefix %c\r\n", cmd_line[0]);
JonFreeman 7:6deaeace9a3e 572 }
JonFreeman 7:6deaeace9a3e 573 for (i = 0; i < a.numof_menu_items; i++) { // Look for input match in command list
JonFreeman 12:d1d21a2941ef 574 wrdlen = strlen(commandlist[i].cmd_word);
JonFreeman 12:d1d21a2941ef 575 if(strncmp(commandlist[i].cmd_word, cmdline_ptr, wrdlen) == 0 && !isalpha(cmdline_ptr[wrdlen])) { // If match found
JonFreeman 16:d1e4b9ad3b8b 576 for (int k = 0; k < MAX_CLI_PARAMS; k++) {
JonFreeman 7:6deaeace9a3e 577 a.dbl[k] = 0.0;
JonFreeman 7:6deaeace9a3e 578 }
JonFreeman 7:6deaeace9a3e 579 a.position_in_list = i;
JonFreeman 7:6deaeace9a3e 580 a.numof_dbls = 0;
JonFreeman 16:d1e4b9ad3b8b 581 // pEnd = cmdline + clindex; // does indeed point to null terminator
JonFreeman 12:d1d21a2941ef 582 pEnd = cmdline_ptr + wrdlen;
JonFreeman 16:d1e4b9ad3b8b 583 // while (*pEnd) { // Assemble all numerics as doubles
JonFreeman 16:d1e4b9ad3b8b 584 while (*pEnd && a.numof_dbls < MAX_CLI_PARAMS) { // Assemble all numerics as doubles
JonFreeman 7:6deaeace9a3e 585 a.dbl[a.numof_dbls++] = strtod (pEnd, &pEnd);
JonFreeman 16:d1e4b9ad3b8b 586 while (*pEnd && (pEnd < cmdline + clindex) && *pEnd && !isdigit(*pEnd) && ('.' != *pEnd) && ('-' != *pEnd) && ('+' != *pEnd)) { // Can crash cli here with e.g. 'ls -l'
JonFreeman 7:6deaeace9a3e 587 pEnd++;
JonFreeman 16:d1e4b9ad3b8b 588 } // problem occurs with input such as "- ", or "-a", seemingly anything dodgy following a '-' or a '+'
JonFreeman 16:d1e4b9ad3b8b 589 if (((*pEnd == '-') || (*pEnd == '+')) &&(!isdigit(*(pEnd+1))) && ('.' !=*(pEnd+1)))
JonFreeman 16:d1e4b9ad3b8b 590 pEnd = cmdline + clindex; // fixed by aborting remainder of line
JonFreeman 7:6deaeace9a3e 591 }
JonFreeman 7:6deaeace9a3e 592 a.respond = a.resp_always;
JonFreeman 7:6deaeace9a3e 593 if (((a.target_unit == BROADCAST) && (IAm == '0')) || (IAm == a.target_unit))
JonFreeman 7:6deaeace9a3e 594 a.respond = true; // sorted 26/4/18
JonFreeman 7:6deaeace9a3e 595 // All boards to obey BROADCAST command, only specific board to obey number prefixed command
JonFreeman 7:6deaeace9a3e 596 if ((a.target_unit == BROADCAST) || (IAm == a.target_unit))
JonFreeman 12:d1d21a2941ef 597 commandlist[i].f(a); // execute command if addressed to this unit
JonFreeman 7:6deaeace9a3e 598 i = a.numof_menu_items + 1; // to exit for loop
JonFreeman 7:6deaeace9a3e 599 } // end of match found
JonFreeman 7:6deaeace9a3e 600 } // End of for numof_menu_items
JonFreeman 12:d1d21a2941ef 601 if(i == a.numof_menu_items) {
JonFreeman 12:d1d21a2941ef 602 // a.com->printf("No Match Found for CMD [%s]\r\n", cmdline);
JonFreeman 12:d1d21a2941ef 603 pc.printf("No Match Found for CMD [%s]\r\n", cmdline);
JonFreeman 12:d1d21a2941ef 604 ESC_Error.set (FAULT_COM_LINE_NOMATCH, 1); // Set FAULT_EEPROM bit 0 if 24LC64 problem
JonFreeman 12:d1d21a2941ef 605 }
JonFreeman 7:6deaeace9a3e 606 } // End of If have got some chars to lookup
JonFreeman 12:d1d21a2941ef 607 clindex = 0;
JonFreeman 12:d1d21a2941ef 608 } // End of else key was CR, may or may not be command to lookup
JonFreeman 12:d1d21a2941ef 609 } // End of while (com->readable())
JonFreeman 12:d1d21a2941ef 610 } // end of command line interpreter core function
JonFreeman 6:f289a49c1eae 611
JonFreeman 6:f289a49c1eae 612