STM3 ESC dual brushless motor controller. 10-60v, motor power rating tiny to kW. Ganged or independent motor control As used in 'The Brute' locomotive - www.jons-workshop.com

Dependencies:   mbed BufferedSerial Servo FastPWM

Committer:
JonFreeman
Date:
Tue Jun 05 07:19:39 2018 +0000
Revision:
6:f289a49c1eae
Child:
7:6deaeace9a3e
Migrating towards code for both STM32F401RET (64 pin) and STM32F446ZET7 (144 pin). Should resolve IO conflicts for larger device - getting servo ins and outs working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 6:f289a49c1eae 1 // DualBLS2018_03
JonFreeman 6:f289a49c1eae 2 #include "mbed.h"
JonFreeman 6:f289a49c1eae 3 #include "BufferedSerial.h"
JonFreeman 6:f289a49c1eae 4
JonFreeman 6:f289a49c1eae 5 #include <cctype>
JonFreeman 6:f289a49c1eae 6 #include "DualBLS.h"
JonFreeman 6:f289a49c1eae 7 using namespace std;
JonFreeman 6:f289a49c1eae 8
JonFreeman 6:f289a49c1eae 9 extern int I_Am () ; // Returns boards id number as ASCII char '0', '1' etc. Code for Broadcast = '\r'
JonFreeman 6:f289a49c1eae 10 extern int WatchDog;
JonFreeman 6:f289a49c1eae 11
JonFreeman 6:f289a49c1eae 12 const int BROADCAST = '\r';
JonFreeman 6:f289a49c1eae 13 const int MAX_PARAMS = 20;
JonFreeman 6:f289a49c1eae 14 struct parameters {
JonFreeman 6:f289a49c1eae 15 int32_t position_in_list, // set but not used Apr 2018, contains i for i'th menu item
JonFreeman 6:f289a49c1eae 16 // last_time, // gets reading from clock() ; not known to be useful or reliable
JonFreeman 6:f289a49c1eae 17 numof_dbls,
JonFreeman 6:f289a49c1eae 18 target_unit;
JonFreeman 6:f289a49c1eae 19 double dbl[MAX_PARAMS];
JonFreeman 6:f289a49c1eae 20 bool respond;
JonFreeman 6:f289a49c1eae 21 } ;
JonFreeman 6:f289a49c1eae 22
JonFreeman 6:f289a49c1eae 23 // WithOUT RTOS
JonFreeman 6:f289a49c1eae 24 extern BufferedSerial com2, pc;
JonFreeman 6:f289a49c1eae 25 extern void send_test () ;
JonFreeman 6:f289a49c1eae 26 extern void setVI (double v, double i) ;
JonFreeman 6:f289a49c1eae 27 extern void setV (double v) ;
JonFreeman 6:f289a49c1eae 28 extern void setI (double i) ;
JonFreeman 6:f289a49c1eae 29 extern void read_last_VI (double * val) ; // only for test from cli
JonFreeman 6:f289a49c1eae 30
JonFreeman 6:f289a49c1eae 31 BufferedSerial * com;
JonFreeman 6:f289a49c1eae 32
JonFreeman 6:f289a49c1eae 33 void null_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 34 {
JonFreeman 6:f289a49c1eae 35 if (a.respond)
JonFreeman 6:f289a49c1eae 36 com->printf ("At null_cmd, board ID %c, parameters : First %.3f, second %.3f\r\n", I_Am(), a.dbl[0], a.dbl[1]);
JonFreeman 6:f289a49c1eae 37 }
JonFreeman 6:f289a49c1eae 38
JonFreeman 6:f289a49c1eae 39 extern void mode_set (int mode, double val) ; // called from cli to set fw, re, rb, hb
JonFreeman 6:f289a49c1eae 40 extern void read_supply_vi (double * val) ;
JonFreeman 6:f289a49c1eae 41
JonFreeman 6:f289a49c1eae 42 void rdi_cmd (struct parameters & a) // read motor currents
JonFreeman 6:f289a49c1eae 43 {
JonFreeman 6:f289a49c1eae 44 if (a.respond) {
JonFreeman 6:f289a49c1eae 45 double r[4];
JonFreeman 6:f289a49c1eae 46 read_supply_vi (r); // get MotorA.I.ave, MotorB.I.ave, Battery volts
JonFreeman 6:f289a49c1eae 47 com->printf ("rdi%.0f %.0f %.1f\r", r[0], r[1], r[2]); // Format good to be unpicked by cli in touch screen controller
JonFreeman 6:f289a49c1eae 48 }
JonFreeman 6:f289a49c1eae 49 }
JonFreeman 6:f289a49c1eae 50
JonFreeman 6:f289a49c1eae 51 void rvi_cmd (struct parameters & a) // read last normalised values sent to pwms
JonFreeman 6:f289a49c1eae 52 {
JonFreeman 6:f289a49c1eae 53 if (a.respond) {
JonFreeman 6:f289a49c1eae 54 double r[6];
JonFreeman 6:f289a49c1eae 55 read_last_VI (r);
JonFreeman 6:f289a49c1eae 56 com->printf ("rvi%.2f %.2f %.2f %.2f\r", r[0], r[1], r[2], r[3]);
JonFreeman 6:f289a49c1eae 57 }
JonFreeman 6:f289a49c1eae 58 }
JonFreeman 6:f289a49c1eae 59
JonFreeman 6:f289a49c1eae 60 void fw_cmd (struct parameters & a) // Forward command
JonFreeman 6:f289a49c1eae 61 {
JonFreeman 6:f289a49c1eae 62 mode_set (FORWARD, 0.0);
JonFreeman 6:f289a49c1eae 63 }
JonFreeman 6:f289a49c1eae 64
JonFreeman 6:f289a49c1eae 65 void re_cmd (struct parameters & a) // Reverse command
JonFreeman 6:f289a49c1eae 66 {
JonFreeman 6:f289a49c1eae 67 mode_set (REVERSE, 0.0);
JonFreeman 6:f289a49c1eae 68 }
JonFreeman 6:f289a49c1eae 69
JonFreeman 6:f289a49c1eae 70 void rb_cmd (struct parameters & a) // Regen brake command
JonFreeman 6:f289a49c1eae 71 {
JonFreeman 6:f289a49c1eae 72 double b = a.dbl[0] / 100.0;
JonFreeman 6:f289a49c1eae 73 // com->printf ("Applying brake %.3f\r\n", b);
JonFreeman 6:f289a49c1eae 74 mode_set (REGENBRAKE, b);
JonFreeman 6:f289a49c1eae 75 // apply_brake (b);
JonFreeman 6:f289a49c1eae 76 }
JonFreeman 6:f289a49c1eae 77
JonFreeman 6:f289a49c1eae 78 extern bool wr_24LC64 (int mem_start_addr, char * source, int length) ;
JonFreeman 6:f289a49c1eae 79 extern bool rd_24LC64 (int mem_start_addr, char * dest, int length) ;
JonFreeman 6:f289a49c1eae 80
JonFreeman 6:f289a49c1eae 81 void erase_cmd (struct parameters & a) // Sets eeprom contents to all 0xff. 256 pages of 32 bytes to do
JonFreeman 6:f289a49c1eae 82 {
JonFreeman 6:f289a49c1eae 83 char t[36];
JonFreeman 6:f289a49c1eae 84 for (int i = 0; i < 32; i++)
JonFreeman 6:f289a49c1eae 85 t[i] = 0xff;
JonFreeman 6:f289a49c1eae 86 for (int i = 0; i < 8191; i += 32) {
JonFreeman 6:f289a49c1eae 87 com->printf (".");
JonFreeman 6:f289a49c1eae 88 if (!wr_24LC64 (i, t, 32))
JonFreeman 6:f289a49c1eae 89 com->printf ("eeprom write prob\r\n");
JonFreeman 6:f289a49c1eae 90 }
JonFreeman 6:f289a49c1eae 91 }
JonFreeman 6:f289a49c1eae 92 /*struct motorpairoptions { // This to be user settable in eeprom, 32 bytes
JonFreeman 6:f289a49c1eae 93 uint8_t MotA_dir, // 0 or 1
JonFreeman 6:f289a49c1eae 94 MotB_dir, // 0 or 1
JonFreeman 6:f289a49c1eae 95 gang, // 0 for separate control (robot mode), 1 for ganged loco bogie mode
JonFreeman 6:f289a49c1eae 96 serv1, // 0, 1, 2 = Not used, Input, Output
JonFreeman 6:f289a49c1eae 97 serv2, // 0, 1, 2 = Not used, Input, Output
JonFreeman 6:f289a49c1eae 98 cmd_source, // 0 Invalid, 1 COM1, 2 COM2, 3 Pot, 4 Servo1, 5 Servo2
JonFreeman 6:f289a49c1eae 99 {'1', '9', '0', "Alternative ID ascii '1' to '9'"}, // defaults to '0' before eerom setup for first time
JonFreeman 6:f289a49c1eae 100 {50, 250, 98, "Wheel diameter mm"}, // New 01/06/2018
JonFreeman 6:f289a49c1eae 101 {10, 250, 27, "Motor pinion"}, // New 01/06/2018
JonFreeman 6:f289a49c1eae 102 {50, 250, 85, "Wheel gear"}, // New 01/06/2018
JonFreeman 6:f289a49c1eae 103 // last;
JonFreeman 6:f289a49c1eae 104 } ;
JonFreeman 6:f289a49c1eae 105 */
JonFreeman 6:f289a49c1eae 106 extern char mode_bytes[];
JonFreeman 6:f289a49c1eae 107
JonFreeman 6:f289a49c1eae 108 void mode_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents
JonFreeman 6:f289a49c1eae 109 {
JonFreeman 6:f289a49c1eae 110 if (a.target_unit == BROADCAST) {
JonFreeman 6:f289a49c1eae 111 // com->printf ("At mode_cmd, can not use BROADCAST with mode_cmd\r\n");
JonFreeman 6:f289a49c1eae 112 } else {
JonFreeman 6:f289a49c1eae 113 char t[36];
JonFreeman 6:f289a49c1eae 114 com->printf ("At mode_cmd with node %d\r\n", a.target_unit);
JonFreeman 6:f289a49c1eae 115 rd_24LC64 (0, t, 32);
JonFreeman 6:f289a49c1eae 116 com->printf ("Numof params=%d\r\n", a.numof_dbls);
JonFreeman 6:f289a49c1eae 117 for (int i = 0; i < numof_eeprom_options; i++)
JonFreeman 6:f289a49c1eae 118 com->printf ("%2x\t%s\r\n", t[i], option_list[i].t);
JonFreeman 6:f289a49c1eae 119 if (a.numof_dbls == 0) { // Read present contents, do not write
JonFreeman 6:f289a49c1eae 120 com->printf ("That's it\r\n");
JonFreeman 6:f289a49c1eae 121 } else { // Write new shit to eeprom
JonFreeman 6:f289a49c1eae 122 com->printf ("\r\n");
JonFreeman 6:f289a49c1eae 123 if (a.numof_dbls != numof_eeprom_options) {
JonFreeman 6:f289a49c1eae 124 com->printf ("params required = %d, you offered %d\r\n", numof_eeprom_options, a.numof_dbls);
JonFreeman 6:f289a49c1eae 125 } else { // Have been passed correct number of parameters
JonFreeman 6:f289a49c1eae 126 int b;
JonFreeman 6:f289a49c1eae 127 com->printf("Ready to write params to eeprom\r\n");
JonFreeman 6:f289a49c1eae 128 for (int i = 0; i < numof_eeprom_options; i++) {
JonFreeman 6:f289a49c1eae 129 b = (int)a.dbl[i]; // parameter value to check against limits
JonFreeman 6:f289a49c1eae 130 if (i == 6) // Alternative ID must be turned to ascii
JonFreeman 6:f289a49c1eae 131 b |= '0';
JonFreeman 6:f289a49c1eae 132 if ((b < option_list[i].min) || (b > option_list[i].max)) { // if parameter out of range
JonFreeman 6:f289a49c1eae 133 com->printf("Warning - Parameter = %d, out of range, setting to default %d\r\n", b, option_list[i].def);
JonFreeman 6:f289a49c1eae 134 b = option_list[i].def;
JonFreeman 6:f289a49c1eae 135 }
JonFreeman 6:f289a49c1eae 136 com->printf ("0x%2x\t%s\r\n", (t[i] = b), option_list[i].t);
JonFreeman 6:f289a49c1eae 137 }
JonFreeman 6:f289a49c1eae 138 wr_24LC64 (0, t, numof_eeprom_options);
JonFreeman 6:f289a49c1eae 139 memcpy (mode_bytes,t,32);
JonFreeman 6:f289a49c1eae 140 com->printf("Parameters set in eeprom\r\n");
JonFreeman 6:f289a49c1eae 141 }
JonFreeman 6:f289a49c1eae 142 }
JonFreeman 6:f289a49c1eae 143 }
JonFreeman 6:f289a49c1eae 144 }
JonFreeman 6:f289a49c1eae 145 /*void coast_cmd (struct parameters & a) { // Coast
JonFreeman 6:f289a49c1eae 146
JonFreeman 6:f289a49c1eae 147 }
JonFreeman 6:f289a49c1eae 148 */
JonFreeman 6:f289a49c1eae 149 void hb_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 150 {
JonFreeman 6:f289a49c1eae 151 if (a.respond) {
JonFreeman 6:f289a49c1eae 152 com->printf ("numof params = %d\r\n", a.numof_dbls);
JonFreeman 6:f289a49c1eae 153 com->printf ("Hand Brake : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
JonFreeman 6:f289a49c1eae 154 }
JonFreeman 6:f289a49c1eae 155 mode_set (HANDBRAKE, 0.0);
JonFreeman 6:f289a49c1eae 156 }
JonFreeman 6:f289a49c1eae 157
JonFreeman 6:f289a49c1eae 158 extern uint32_t last_temp_count;
JonFreeman 6:f289a49c1eae 159 void temperature_cmd (struct parameters & a) {
JonFreeman 6:f289a49c1eae 160 if (a.respond) {
JonFreeman 6:f289a49c1eae 161 com->printf ("tem%c %d\r\n", mode_bytes[ID], (last_temp_count / 16) - 50);
JonFreeman 6:f289a49c1eae 162 }
JonFreeman 6:f289a49c1eae 163 }
JonFreeman 6:f289a49c1eae 164
JonFreeman 6:f289a49c1eae 165 void bogie_constants_report_cmd (struct parameters & a) {
JonFreeman 6:f289a49c1eae 166 if (a.respond) {
JonFreeman 6:f289a49c1eae 167 com->printf ("bc%c %d %d %d\r\n", mode_bytes[ID], mode_bytes[WHEELDIA], mode_bytes[MOTPIN], mode_bytes[WHEELGEAR]);
JonFreeman 6:f289a49c1eae 168 }
JonFreeman 6:f289a49c1eae 169 }
JonFreeman 6:f289a49c1eae 170
JonFreeman 6:f289a49c1eae 171 extern void read_RPM (uint32_t * dest) ;
JonFreeman 6:f289a49c1eae 172 void rpm_cmd (struct parameters & a) // to report e.g. RPM 1000 1000 ; speed for both motors
JonFreeman 6:f289a49c1eae 173 {
JonFreeman 6:f289a49c1eae 174 if (a.respond) {
JonFreeman 6:f289a49c1eae 175 uint32_t dest[3];
JonFreeman 6:f289a49c1eae 176 read_RPM (dest);
JonFreeman 6:f289a49c1eae 177 com->printf ("rpm%d %d\r", dest[0], dest[1]);
JonFreeman 6:f289a49c1eae 178 }
JonFreeman 6:f289a49c1eae 179 }
JonFreeman 6:f289a49c1eae 180
JonFreeman 6:f289a49c1eae 181 void menucmd (struct parameters & a);
JonFreeman 6:f289a49c1eae 182
JonFreeman 6:f289a49c1eae 183 void vi_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 184 {
JonFreeman 6:f289a49c1eae 185 // if (a.respond)
JonFreeman 6:f289a49c1eae 186 // com->printf ("In setVI, setting V to %.2f, I %.2f\r\n", a.dbl[0], a.dbl[1]);
JonFreeman 6:f289a49c1eae 187 setVI (a.dbl[0] / 100.0, a.dbl[1] / 100.0);
JonFreeman 6:f289a49c1eae 188 }
JonFreeman 6:f289a49c1eae 189
JonFreeman 6:f289a49c1eae 190 void v_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 191 {
JonFreeman 6:f289a49c1eae 192 // if (a.respond)
JonFreeman 6:f289a49c1eae 193 // com->printf ("In setV, setting V to %.2f\r\n", a.dbl[0]);
JonFreeman 6:f289a49c1eae 194 setV (a.dbl[0] / 100.0);
JonFreeman 6:f289a49c1eae 195 }
JonFreeman 6:f289a49c1eae 196
JonFreeman 6:f289a49c1eae 197 void i_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 198 {
JonFreeman 6:f289a49c1eae 199 // if (a.respond)
JonFreeman 6:f289a49c1eae 200 // com->printf ("In setI, setting I to %.2f\r\n", a.dbl[0]);
JonFreeman 6:f289a49c1eae 201 setI (a.dbl[0] / 100.0);
JonFreeman 6:f289a49c1eae 202 }
JonFreeman 6:f289a49c1eae 203
JonFreeman 6:f289a49c1eae 204 void kd_cmd (struct parameters & a) // kick the watchdog
JonFreeman 6:f289a49c1eae 205 {
JonFreeman 6:f289a49c1eae 206 WatchDog = WATCHDOG_RELOAD + (I_Am() & 0x0f);
JonFreeman 6:f289a49c1eae 207 // com->printf ("Poked %d up Dog\r\n", WatchDog);
JonFreeman 6:f289a49c1eae 208 }
JonFreeman 6:f289a49c1eae 209
JonFreeman 6:f289a49c1eae 210 void who_cmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 211 {
JonFreeman 6:f289a49c1eae 212 int i = I_Am ();
JonFreeman 6:f289a49c1eae 213 if (I_Am() == a.target_unit)
JonFreeman 6:f289a49c1eae 214 com->printf ("who%c\r\n", a.target_unit);
JonFreeman 6:f289a49c1eae 215 }
JonFreeman 6:f289a49c1eae 216
JonFreeman 6:f289a49c1eae 217 struct kb_command {
JonFreeman 6:f289a49c1eae 218 const char * cmd_word; // points to text e.g. "menu"
JonFreeman 6:f289a49c1eae 219 const char * explan;
JonFreeman 6:f289a49c1eae 220 void (*f)(struct parameters &); // points to function
JonFreeman 6:f289a49c1eae 221 } ;
JonFreeman 6:f289a49c1eae 222
JonFreeman 6:f289a49c1eae 223 struct kb_command const command_list[] = {
JonFreeman 6:f289a49c1eae 224 {"ls", "Lists available commands", menucmd},
JonFreeman 6:f289a49c1eae 225 {"?", "Lists available commands, same as ls", menucmd},
JonFreeman 6:f289a49c1eae 226 {"fw", "forward", fw_cmd},
JonFreeman 6:f289a49c1eae 227 {"re", "reverse", re_cmd},
JonFreeman 6:f289a49c1eae 228 {"rb", "regen brake 0 to 99 %", rb_cmd},
JonFreeman 6:f289a49c1eae 229 {"hb", "hand brake", hb_cmd},
JonFreeman 6:f289a49c1eae 230 {"v", "set motors V percent RANGE 0 to 100", v_cmd},
JonFreeman 6:f289a49c1eae 231 {"i", "set motors I percent RANGE 0 to 100", i_cmd},
JonFreeman 6:f289a49c1eae 232 {"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd},
JonFreeman 6:f289a49c1eae 233 {"who", "search for connected units, e.g. 3who returs 'Hi there' if found", who_cmd},
JonFreeman 6:f289a49c1eae 234 {"mode", "read or set params in eeprom", mode_cmd},
JonFreeman 6:f289a49c1eae 235 {"erase", "set eeprom contents to all 0xff", erase_cmd},
JonFreeman 6:f289a49c1eae 236 {"tem", "report temperature", temperature_cmd},
JonFreeman 6:f289a49c1eae 237 {"kd", "kick the dog, reloads WatchDog", kd_cmd},
JonFreeman 6:f289a49c1eae 238 {"rpm", "read motor pair speeds", rpm_cmd},
JonFreeman 6:f289a49c1eae 239 {"rvi", "read most recent values sent to pwms", rvi_cmd},
JonFreeman 6:f289a49c1eae 240 {"rdi", "read motor currents and power voltage", rdi_cmd},
JonFreeman 6:f289a49c1eae 241 {"bc", "bogie constants - wheel dia, motor pinion, wheel gear", bogie_constants_report_cmd},
JonFreeman 6:f289a49c1eae 242 {"nu", "do nothing", null_cmd},
JonFreeman 6:f289a49c1eae 243 };
JonFreeman 6:f289a49c1eae 244
JonFreeman 6:f289a49c1eae 245 const int numof_menu_items = sizeof(command_list) / sizeof(kb_command);
JonFreeman 6:f289a49c1eae 246 void menucmd (struct parameters & a)
JonFreeman 6:f289a49c1eae 247 {
JonFreeman 6:f289a49c1eae 248 if (a.respond) {
JonFreeman 6:f289a49c1eae 249 com->printf("\r\n\nDouble Brushless Motor Driver 2018\r\nAt menucmd function - listing commands:-\r\n");
JonFreeman 6:f289a49c1eae 250 for(int i = 0; i < numof_menu_items; i++)
JonFreeman 6:f289a49c1eae 251 com->printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan);
JonFreeman 6:f289a49c1eae 252 com->printf("End of List of Commands\r\n");
JonFreeman 6:f289a49c1eae 253 }
JonFreeman 6:f289a49c1eae 254 }
JonFreeman 6:f289a49c1eae 255
JonFreeman 6:f289a49c1eae 256 /*
JonFreeman 6:f289a49c1eae 257 New - March 2018
JonFreeman 6:f289a49c1eae 258 Using opto isolated serial port, paralleled up using same pair to multiple boards running this code.
JonFreeman 6:f289a49c1eae 259 New feature - commands have optional prefix digit 0-9 indicating which unit message is addressed to.
JonFreeman 6:f289a49c1eae 260 Commands without prefix digit - broadcast to all units, all to obey but none to respond.
JonFreeman 6:f289a49c1eae 261 Only units recognising its address from prefix digit may respond. This avoids bus contention.
JonFreeman 6:f289a49c1eae 262 But for BROADCAST commands, '0' may respond on behalf of the group
JonFreeman 6:f289a49c1eae 263 */
JonFreeman 6:f289a49c1eae 264 //void command_line_interpreter (void const *argument)
JonFreeman 6:f289a49c1eae 265 void command_line_interpreter ()
JonFreeman 6:f289a49c1eae 266 {
JonFreeman 6:f289a49c1eae 267 const int MAX_CMD_LEN = 120;
JonFreeman 6:f289a49c1eae 268 static char cmd_line[MAX_CMD_LEN + 4];
JonFreeman 6:f289a49c1eae 269 static int cl_index = 0;
JonFreeman 6:f289a49c1eae 270 int ch, IAm = I_Am();
JonFreeman 6:f289a49c1eae 271 char * pEnd, * cmd_line_ptr;
JonFreeman 6:f289a49c1eae 272 static struct parameters param_block ;
JonFreeman 6:f289a49c1eae 273 com = &com2;
JonFreeman 6:f289a49c1eae 274 while (com->readable()) {
JonFreeman 6:f289a49c1eae 275 // ch = tolower(com->getc());
JonFreeman 6:f289a49c1eae 276 ch = com->getc();
JonFreeman 6:f289a49c1eae 277 if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines
JonFreeman 6:f289a49c1eae 278 com->printf ("Error!! Stupidly long cmd line\r\n");
JonFreeman 6:f289a49c1eae 279 cl_index = 0;
JonFreeman 6:f289a49c1eae 280 }
JonFreeman 6:f289a49c1eae 281 if(ch != '\r') // was this the 'Enter' key?
JonFreeman 6:f289a49c1eae 282 cmd_line[cl_index++] = ch; // added char to command being assembled
JonFreeman 6:f289a49c1eae 283 else { // key was CR, may or may not be command to lookup
JonFreeman 6:f289a49c1eae 284 param_block.target_unit = BROADCAST; // Set to BROADCAST default once found command line '\r'
JonFreeman 6:f289a49c1eae 285 cmd_line_ptr = cmd_line;
JonFreeman 6:f289a49c1eae 286 cmd_line[cl_index] = 0; // null terminate command string
JonFreeman 6:f289a49c1eae 287 if(cl_index) { // If have got some chars to lookup
JonFreeman 6:f289a49c1eae 288 int i, wrdlen;
JonFreeman 6:f289a49c1eae 289 if (isdigit(cmd_line[0])) { // Look for command with prefix digit
JonFreeman 6:f289a49c1eae 290 cmd_line_ptr++; // point past identified digit prefix
JonFreeman 6:f289a49c1eae 291 param_block.target_unit = cmd_line[0]; // '0' to '9'
JonFreeman 6:f289a49c1eae 292 //com->printf ("Got prefix %c\r\n", cmd_line[0]);
JonFreeman 6:f289a49c1eae 293 }
JonFreeman 6:f289a49c1eae 294 for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list
JonFreeman 6:f289a49c1eae 295 wrdlen = strlen(command_list[i].cmd_word);
JonFreeman 6:f289a49c1eae 296 if(strncmp(command_list[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen])) { // If match found
JonFreeman 6:f289a49c1eae 297 for (int k = 0; k < MAX_PARAMS; k++) {
JonFreeman 6:f289a49c1eae 298 param_block.dbl[k] = 0.0;
JonFreeman 6:f289a49c1eae 299 }
JonFreeman 6:f289a49c1eae 300 param_block.position_in_list = i;
JonFreeman 6:f289a49c1eae 301 // param_block.last_time = clock ();
JonFreeman 6:f289a49c1eae 302 param_block.numof_dbls = 0;
JonFreeman 6:f289a49c1eae 303 pEnd = cmd_line_ptr + wrdlen;
JonFreeman 6:f289a49c1eae 304 while (*pEnd) { // Assemble all numerics as doubles
JonFreeman 6:f289a49c1eae 305 param_block.dbl[param_block.numof_dbls++] = strtod (pEnd, &pEnd);
JonFreeman 6:f289a49c1eae 306 while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) {
JonFreeman 6:f289a49c1eae 307 pEnd++;
JonFreeman 6:f289a49c1eae 308 }
JonFreeman 6:f289a49c1eae 309 }
JonFreeman 6:f289a49c1eae 310 //com->printf ("\r\n"); // Not allowed as many may output this.
JonFreeman 6:f289a49c1eae 311 //for (int k = 0; k < param_block.numof_dbls; k++)
JonFreeman 6:f289a49c1eae 312 // com->printf ("Read %.3f\r\n", param_block.dbl[k]);
JonFreeman 6:f289a49c1eae 313 // param_block.times[i] = clock();
JonFreeman 6:f289a49c1eae 314 param_block.respond = false;
JonFreeman 6:f289a49c1eae 315 if (((param_block.target_unit == BROADCAST) && (IAm == '0')) || (IAm == param_block.target_unit))
JonFreeman 6:f289a49c1eae 316 param_block.respond = true; // sorted 26/4/18
JonFreeman 6:f289a49c1eae 317 // All boards to obey BROADCAST command, only specific board to obey number prefixed command
JonFreeman 6:f289a49c1eae 318 if ((param_block.target_unit == BROADCAST) || (IAm == param_block.target_unit))
JonFreeman 6:f289a49c1eae 319 command_list[i].f(param_block); // execute command if addressed to this unit
JonFreeman 6:f289a49c1eae 320 i = numof_menu_items + 1; // to exit for loop
JonFreeman 6:f289a49c1eae 321 } // end of match found
JonFreeman 6:f289a49c1eae 322 } // End of for numof_menu_items
JonFreeman 6:f289a49c1eae 323 if(i == numof_menu_items)
JonFreeman 6:f289a49c1eae 324 com->printf("No Match Found for CMD [%s]\r\n", cmd_line);
JonFreeman 6:f289a49c1eae 325 } // End of If have got some chars to lookup
JonFreeman 6:f289a49c1eae 326 //com->printf("\r\n>");
JonFreeman 6:f289a49c1eae 327 cl_index = 0;
JonFreeman 6:f289a49c1eae 328 } // End of else key was CR, may or may not be command to lookup
JonFreeman 6:f289a49c1eae 329 } // End of while (com->readable())
JonFreeman 6:f289a49c1eae 330 // Thread::wait(20); // Using RTOS on this project
JonFreeman 6:f289a49c1eae 331 // }
JonFreeman 6:f289a49c1eae 332 }
JonFreeman 6:f289a49c1eae 333
JonFreeman 6:f289a49c1eae 334