Code for 'Smart Regulator' featured in 'Model Engineer', November 2020 on. Contains all work to August 2020 including all code described. Top level algorithm development is quite spares, leaving some work for you! Any questions - jon@jons-workshop.com
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
cli.cpp@5:6ca3e7ffc553, 2020-12-05 (annotated)
- Committer:
- JonFreeman
- Date:
- Sat Dec 05 12:40:17 2020 +0000
- Revision:
- 5:6ca3e7ffc553
- Parent:
- 3:43cb067ecd00
Code for 'Smart Regulator' to August 2020, published as is. Basic low-level functions all thoroughly tested and debugged, top level algorithms have scope for further development - over to you! For help contact jon @ jons-workshop[.com
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JonFreeman | 0:77803b3ee157 | 1 | /* |
JonFreeman | 0:77803b3ee157 | 2 | Command Line Interpreter code module. |
JonFreeman | 0:77803b3ee157 | 3 | Purpose - |
JonFreeman | 0:77803b3ee157 | 4 | Provides easy interface to pc terminal programme for use during programme development, debug etc. |
JonFreeman | 0:77803b3ee157 | 5 | Also usable as comms subsystem in finished code for accepting commands, reporting data etc. |
JonFreeman | 0:77803b3ee157 | 6 | */ |
JonFreeman | 0:77803b3ee157 | 7 | #include "mbed.h" |
JonFreeman | 3:43cb067ecd00 | 8 | #include "field.h" |
JonFreeman | 0:77803b3ee157 | 9 | #include "Alternator.h" |
JonFreeman | 3:43cb067ecd00 | 10 | #include "BufferedSerial.h" |
JonFreeman | 0:77803b3ee157 | 11 | #include <cctype> |
JonFreeman | 0:77803b3ee157 | 12 | using namespace std; |
JonFreeman | 0:77803b3ee157 | 13 | |
JonFreeman | 3:43cb067ecd00 | 14 | ee_settings_2020 user_settings ; |
JonFreeman | 0:77803b3ee157 | 15 | |
JonFreeman | 3:43cb067ecd00 | 16 | extern BufferedSerial pc; |
JonFreeman | 3:43cb067ecd00 | 17 | extern void maketable () ; |
JonFreeman | 1:450090bdb6f4 | 18 | extern void query_system (struct parameters & a) ; |
JonFreeman | 0:77803b3ee157 | 19 | extern uint32_t ReadEngineRPM () ; |
JonFreeman | 3:43cb067ecd00 | 20 | extern double Read_Link_Volts () ; |
JonFreeman | 3:43cb067ecd00 | 21 | extern double Read_Field_Volts () ; |
JonFreeman | 3:43cb067ecd00 | 22 | extern double Read_Ammeter () ; |
JonFreeman | 5:6ca3e7ffc553 | 23 | extern void charge_pump_override (parameters & a) ; // 0 disables, !0 enables charge pump |
JonFreeman | 5:6ca3e7ffc553 | 24 | extern void set_v_out_opamp (parameters & a) ; // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting |
JonFreeman | 1:450090bdb6f4 | 25 | |
JonFreeman | 3:43cb067ecd00 | 26 | //bool ee_settings_2020::wr (char c, uint32_t i) { // Write one setup char value to private buffer 'settings' |
JonFreeman | 3:43cb067ecd00 | 27 | /* |
JonFreeman | 3:43cb067ecd00 | 28 | void slope_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 29 | Provides a quick way of filling lookup table. |
JonFreeman | 3:43cb067ecd00 | 30 | Sets percent at 3000 RPM with first parameter 0 to 100 |
JonFreeman | 3:43cb067ecd00 | 31 | */ |
JonFreeman | 3:43cb067ecd00 | 32 | void slope_cmd (struct parameters & a) { // Requires two params. First %@ 3000 rpm, second slope MAX +/-20 % per krpm above |
JonFreeman | 3:43cb067ecd00 | 33 | const int startat = 1800; // rpm to start at |
JonFreeman | 3:43cb067ecd00 | 34 | const int rpm_per = 200; // rpm per lookup table step |
JonFreeman | 3:43cb067ecd00 | 35 | const int threshold = startat / rpm_per; |
JonFreeman | 3:43cb067ecd00 | 36 | signed char at_power_beyond, slope; |
JonFreeman | 3:43cb067ecd00 | 37 | pc.printf ("Slope - set pct = %d @ 3krpm, slope %d pct above\r\n", (int32_t)a.dbl[0], (int32_t)a.dbl[1]); |
JonFreeman | 3:43cb067ecd00 | 38 | if (a.numof_dbls != 2) |
JonFreeman | 3:43cb067ecd00 | 39 | pc.printf ("Need 2 params in slope, got %d, ", a.numof_dbls); |
JonFreeman | 3:43cb067ecd00 | 40 | else { |
JonFreeman | 3:43cb067ecd00 | 41 | pc.printf ("Got slope params %.1f, %.1f\r\n", a.dbl[0], a.dbl[1]); |
JonFreeman | 3:43cb067ecd00 | 42 | if (a.dbl[0] > 100.0) a.dbl[0] = 100.0; |
JonFreeman | 3:43cb067ecd00 | 43 | if (a.dbl[0] < 0.0) a.dbl[0] = 0.0; |
JonFreeman | 3:43cb067ecd00 | 44 | if (a.dbl[1] > +20.0) a.dbl[1] = +20.0; |
JonFreeman | 3:43cb067ecd00 | 45 | if (a.dbl[1] < -20.0) a.dbl[1] = -20.0; |
JonFreeman | 3:43cb067ecd00 | 46 | at_power_beyond = (signed char)a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 47 | slope = (signed char)a.dbl[1]; |
JonFreeman | 3:43cb067ecd00 | 48 | pc.printf ("Setting slope "); |
JonFreeman | 3:43cb067ecd00 | 49 | for (int i = 0; i < threshold; i++) { // Zero all very low speed settings |
JonFreeman | 3:43cb067ecd00 | 50 | user_settings.wr (0, i); |
JonFreeman | 3:43cb067ecd00 | 51 | } |
JonFreeman | 3:43cb067ecd00 | 52 | for (int i = threshold; i < 21; i++) { |
JonFreeman | 3:43cb067ecd00 | 53 | user_settings.wr (at_power_beyond, i); |
JonFreeman | 3:43cb067ecd00 | 54 | pc.printf ("%d, ", at_power_beyond); |
JonFreeman | 3:43cb067ecd00 | 55 | at_power_beyond += slope; |
JonFreeman | 3:43cb067ecd00 | 56 | if (at_power_beyond < 0) at_power_beyond = 0; |
JonFreeman | 3:43cb067ecd00 | 57 | if (at_power_beyond > 100) at_power_beyond = 100; |
JonFreeman | 3:43cb067ecd00 | 58 | } |
JonFreeman | 3:43cb067ecd00 | 59 | pc.printf ("\r\nDone\r\n"); |
JonFreeman | 3:43cb067ecd00 | 60 | user_settings.save (); |
JonFreeman | 3:43cb067ecd00 | 61 | maketable (); |
JonFreeman | 3:43cb067ecd00 | 62 | } |
JonFreeman | 3:43cb067ecd00 | 63 | } |
JonFreeman | 2:8e7b51353f32 | 64 | |
JonFreeman | 3:43cb067ecd00 | 65 | void table_tweak_cmd (struct parameters & a) { // Requires two params. First '20', '22' etc representing hundreds RPM. Second 0 to 99 percent |
JonFreeman | 2:8e7b51353f32 | 66 | char txt[100]; |
JonFreeman | 2:8e7b51353f32 | 67 | uint32_t d[3]; |
JonFreeman | 2:8e7b51353f32 | 68 | txt[0] = 0; |
JonFreeman | 2:8e7b51353f32 | 69 | if (a.numof_dbls != 2) |
JonFreeman | 2:8e7b51353f32 | 70 | sprintf (txt, "Need 2 params, got %d, ", a.numof_dbls); |
JonFreeman | 2:8e7b51353f32 | 71 | else { |
JonFreeman | 2:8e7b51353f32 | 72 | d[2] = (uint32_t)a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 73 | d[0] = d[2] / 2; |
JonFreeman | 2:8e7b51353f32 | 74 | d[1] = (uint32_t)a.dbl[1]; |
JonFreeman | 3:43cb067ecd00 | 75 | if (d[0] > 20 || d[1] > 100 || d[2] != d[0] * 2) |
JonFreeman | 2:8e7b51353f32 | 76 | sprintf (txt + strlen(txt), "Param out of range %d, %d, ", d[2], d[1]); |
JonFreeman | 2:8e7b51353f32 | 77 | else { |
JonFreeman | 2:8e7b51353f32 | 78 | pc.printf ("Off to reset table %d RPM, %d percent\r\n", d[2] * 100, d[1]); |
JonFreeman | 2:8e7b51353f32 | 79 | user_settings.wr ((char)d[1], d[0]); |
JonFreeman | 2:8e7b51353f32 | 80 | user_settings.save (); |
JonFreeman | 2:8e7b51353f32 | 81 | maketable (); |
JonFreeman | 2:8e7b51353f32 | 82 | } |
JonFreeman | 2:8e7b51353f32 | 83 | } |
JonFreeman | 2:8e7b51353f32 | 84 | if (txt[0]) |
JonFreeman | 2:8e7b51353f32 | 85 | pc.printf ("Errors in table_tweak_cmd - %s\r\n", txt); |
JonFreeman | 2:8e7b51353f32 | 86 | else |
JonFreeman | 2:8e7b51353f32 | 87 | pc.printf ("Good in table_tweak_cmd, RPM=%d, percentage=%d\r\n", d[0] * 500, d[1]); |
JonFreeman | 2:8e7b51353f32 | 88 | } |
JonFreeman | 0:77803b3ee157 | 89 | |
JonFreeman | 3:43cb067ecd00 | 90 | |
JonFreeman | 3:43cb067ecd00 | 91 | //extern VEXT_Data Field; |
JonFreeman | 3:43cb067ecd00 | 92 | extern FieldControl Field; |
JonFreeman | 3:43cb067ecd00 | 93 | |
JonFreeman | 3:43cb067ecd00 | 94 | extern int32_t set_engine_RPM_lit (uint32_t RPMrequest) ; // Returns speed error pos or neg |
JonFreeman | 3:43cb067ecd00 | 95 | extern int32_t set_engine_RPM_pct (uint32_t RPMrequest) ; // Returns speed error pos or neg |
JonFreeman | 3:43cb067ecd00 | 96 | void ss_cmd (struct parameters & a) { // Set engine Speed 0 - 8000 RPM |
JonFreeman | 3:43cb067ecd00 | 97 | uint32_t v = (uint32_t) a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 98 | pc.printf ("Setting engine RPM to %d, measured RPM returned = %d\r\n", v, set_engine_RPM_lit (v)); |
JonFreeman | 3:43cb067ecd00 | 99 | } |
JonFreeman | 0:77803b3ee157 | 100 | |
JonFreeman | 3:43cb067ecd00 | 101 | void sp_cmd (struct parameters & a) { // Set engine Speed 0 - 8000 RPM |
JonFreeman | 3:43cb067ecd00 | 102 | uint32_t v = (uint32_t) a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 103 | pc.printf ("Setting engine RPM percent to %d, measured RPM returned = %d\r\n", v, set_engine_RPM_pct (v)); |
JonFreeman | 3:43cb067ecd00 | 104 | } |
JonFreeman | 3:43cb067ecd00 | 105 | |
JonFreeman | 3:43cb067ecd00 | 106 | void rfcmd (struct parameters & a) { // |
JonFreeman | 3:43cb067ecd00 | 107 | // pc.printf ("Field.measured_period = %u", (uint32_t)Field.get_measured_period()); |
JonFreeman | 3:43cb067ecd00 | 108 | // pc.printf (", Field.measured_pw_us = %u, duty_cycle = %.3f\r\n", (uint32_t)Field.measured_pw_us, Field.duty_cycle()); |
JonFreeman | 3:43cb067ecd00 | 109 | pc.printf ("Field duty cycle measured = %.3f\r\n", Field.get_duty_ratio()); |
JonFreeman | 3:43cb067ecd00 | 110 | } |
JonFreeman | 3:43cb067ecd00 | 111 | |
JonFreeman | 3:43cb067ecd00 | 112 | void vcmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 113 | pc.printf ("link volts %.2f, field volts %.2f\r\n", Read_Link_Volts(), Read_Field_Volts()); |
JonFreeman | 3:43cb067ecd00 | 114 | } |
JonFreeman | 3:43cb067ecd00 | 115 | |
JonFreeman | 3:43cb067ecd00 | 116 | void acmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 117 | pc.printf ("amps %.2f\r\n", Read_Ammeter()); |
JonFreeman | 3:43cb067ecd00 | 118 | } |
JonFreeman | 3:43cb067ecd00 | 119 | |
JonFreeman | 1:450090bdb6f4 | 120 | |
JonFreeman | 3:43cb067ecd00 | 121 | extern void set_pwm (double) ; // Range 0.0 to 1.0 |
JonFreeman | 3:43cb067ecd00 | 122 | void fls_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 123 | pc.printf ("Setting field.limiter to %d percent\r\n", (int)a.dbl[0]); |
JonFreeman | 3:43cb067ecd00 | 124 | set_pwm (a.dbl[0] / 100.0); |
JonFreeman | 3:43cb067ecd00 | 125 | } |
JonFreeman | 3:43cb067ecd00 | 126 | |
JonFreeman | 3:43cb067ecd00 | 127 | void set_defaults_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 128 | struct sldandt * p = NULL; |
JonFreeman | 3:43cb067ecd00 | 129 | bool flag = true; |
JonFreeman | 3:43cb067ecd00 | 130 | int i = 0; |
JonFreeman | 3:43cb067ecd00 | 131 | while (flag) { |
JonFreeman | 3:43cb067ecd00 | 132 | p = user_settings.inform(i); // Returns NULL when i goes out of range |
JonFreeman | 3:43cb067ecd00 | 133 | if (p == NULL) |
JonFreeman | 3:43cb067ecd00 | 134 | flag = false; |
JonFreeman | 3:43cb067ecd00 | 135 | else { |
JonFreeman | 3:43cb067ecd00 | 136 | pc.printf ("min %d, max %d, default %d, text %s\r\n", p->min, p->max, p->de_fault, p->txt); |
JonFreeman | 3:43cb067ecd00 | 137 | user_settings.wr (p->de_fault, i); |
JonFreeman | 3:43cb067ecd00 | 138 | i++; |
JonFreeman | 3:43cb067ecd00 | 139 | } |
JonFreeman | 0:77803b3ee157 | 140 | } |
JonFreeman | 3:43cb067ecd00 | 141 | user_settings.save (); |
JonFreeman | 3:43cb067ecd00 | 142 | } |
JonFreeman | 0:77803b3ee157 | 143 | |
JonFreeman | 3:43cb067ecd00 | 144 | void servodir_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 145 | char ch = (char)a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 146 | if (a.numof_dbls != 1 || ch > 1) { |
JonFreeman | 3:43cb067ecd00 | 147 | pc.printf ("Wrong servodir set\r\n"); |
JonFreeman | 3:43cb067ecd00 | 148 | return ; |
JonFreeman | 3:43cb067ecd00 | 149 | } |
JonFreeman | 3:43cb067ecd00 | 150 | if (user_settings.rd(SERVO_DIR) != ch) { |
JonFreeman | 3:43cb067ecd00 | 151 | pc.printf ("Setting servo dir %.1f \r\n", a.dbl[0]); |
JonFreeman | 3:43cb067ecd00 | 152 | user_settings.wr(ch, SERVO_DIR); |
JonFreeman | 3:43cb067ecd00 | 153 | user_settings.save(); |
JonFreeman | 3:43cb067ecd00 | 154 | } |
JonFreeman | 0:77803b3ee157 | 155 | } |
JonFreeman | 0:77803b3ee157 | 156 | |
JonFreeman | 3:43cb067ecd00 | 157 | char * modes_txt[] = { |
JonFreeman | 3:43cb067ecd00 | 158 | "0\tSafe nothing mode for cli cmd testing", |
JonFreeman | 3:43cb067ecd00 | 159 | "1\tPot to Servo direct, field OFF", |
JonFreeman | 3:43cb067ecd00 | 160 | "2\tVariable voltage", |
JonFreeman | 3:43cb067ecd00 | 161 | "3\tFixed voltage", |
JonFreeman | 3:43cb067ecd00 | 162 | "4\tEngine Revs Control", |
JonFreeman | 3:43cb067ecd00 | 163 | "5\tSet Engine to Driver's Pot", |
JonFreeman | 3:43cb067ecd00 | 164 | "6\tControl Engine by Current Load", |
JonFreeman | 3:43cb067ecd00 | 165 | "7\tAuto Test", |
JonFreeman | 3:43cb067ecd00 | 166 | } ; |
JonFreeman | 3:43cb067ecd00 | 167 | |
JonFreeman | 3:43cb067ecd00 | 168 | int numof_op_modes = sizeof(modes_txt) / sizeof(char *); |
JonFreeman | 0:77803b3ee157 | 169 | |
JonFreeman | 3:43cb067ecd00 | 170 | char * get_mode_text (uint32_t mode) { |
JonFreeman | 3:43cb067ecd00 | 171 | if (mode > numof_op_modes) { |
JonFreeman | 3:43cb067ecd00 | 172 | pc.printf ("mode OOR in get_mode_text, %d\r\n", mode); |
JonFreeman | 3:43cb067ecd00 | 173 | mode = numof_op_modes - 1; |
JonFreeman | 3:43cb067ecd00 | 174 | } |
JonFreeman | 3:43cb067ecd00 | 175 | return modes_txt[mode]; |
JonFreeman | 3:43cb067ecd00 | 176 | } |
JonFreeman | 1:450090bdb6f4 | 177 | |
JonFreeman | 3:43cb067ecd00 | 178 | void mode20_cmd (struct parameters & a) ; |
JonFreeman | 3:43cb067ecd00 | 179 | void mode_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 180 | if (a.numof_dbls == 1 && (uint32_t) a.dbl[0] <= numof_op_modes) { |
JonFreeman | 3:43cb067ecd00 | 181 | a.dbl[1] = a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 182 | a.dbl[0] = OP_MODE; //23.0; |
JonFreeman | 3:43cb067ecd00 | 183 | a.numof_dbls = 2; |
JonFreeman | 3:43cb067ecd00 | 184 | mode20_cmd (a); |
JonFreeman | 3:43cb067ecd00 | 185 | return; |
JonFreeman | 3:43cb067ecd00 | 186 | } |
JonFreeman | 3:43cb067ecd00 | 187 | pc.printf ("Current mode is %d \r\nTo set operating mode, use mode n :- where \r\n", user_settings.rd(OP_MODE)); |
JonFreeman | 3:43cb067ecd00 | 188 | for (int i = 0; i < numof_op_modes; i++) |
JonFreeman | 3:43cb067ecd00 | 189 | pc.printf ("%s\r\n", get_mode_text(i)); |
JonFreeman | 0:77803b3ee157 | 190 | } |
JonFreeman | 0:77803b3ee157 | 191 | |
JonFreeman | 3:43cb067ecd00 | 192 | void mode20_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 193 | struct sldandt * p = NULL; // Pointer to struct containing max, min and default values, and brief text descriptor for a command |
JonFreeman | 3:43cb067ecd00 | 194 | int i = 0; |
JonFreeman | 3:43cb067ecd00 | 195 | bool flag = true; |
JonFreeman | 3:43cb067ecd00 | 196 | bool save_settings = false; |
JonFreeman | 3:43cb067ecd00 | 197 | int32_t cmd_num = (int32_t) a.dbl[0], first_p = (int32_t) a.dbl[1]; |
JonFreeman | 3:43cb067ecd00 | 198 | pc.printf ("At user setting, numofparams = %d, dbl[0]=%.2f, dbl[1]=%.2f\r\n", a.numof_dbls, a.dbl[0], a.dbl[1]); |
JonFreeman | 3:43cb067ecd00 | 199 | if (a.numof_dbls < 2) { // Need at least command number followed by at least one parameter |
JonFreeman | 3:43cb067ecd00 | 200 | pc.printf ("Listing Setup\r\nTo alter, enter us param number, new value\r\n"); |
JonFreeman | 3:43cb067ecd00 | 201 | while (flag) { |
JonFreeman | 3:43cb067ecd00 | 202 | p = user_settings.inform(i); // Returns false when i goes out of range |
JonFreeman | 3:43cb067ecd00 | 203 | if (p == NULL) |
JonFreeman | 3:43cb067ecd00 | 204 | flag = false; |
JonFreeman | 3:43cb067ecd00 | 205 | else { |
JonFreeman | 3:43cb067ecd00 | 206 | pc.printf ("%d\tval %d, min %d, max %d, default %d, text %s\r\n", i, user_settings.rd(i), p->min, p->max, p->de_fault, p->txt); |
JonFreeman | 3:43cb067ecd00 | 207 | i++; |
JonFreeman | 3:43cb067ecd00 | 208 | } |
JonFreeman | 3:43cb067ecd00 | 209 | } |
JonFreeman | 3:43cb067ecd00 | 210 | return ; |
JonFreeman | 3:43cb067ecd00 | 211 | } // When too few parameters, output list. Done. |
JonFreeman | 3:43cb067ecd00 | 212 | p = user_settings.inform(cmd_num); // Set pointer to min, max, default and text info |
JonFreeman | 3:43cb067ecd00 | 213 | if (p == NULL) { |
JonFreeman | 3:43cb067ecd00 | 214 | pc.printf ("Invalid command number %d in user setting entry\r\n", cmd_num); |
JonFreeman | 3:43cb067ecd00 | 215 | return ; |
JonFreeman | 3:43cb067ecd00 | 216 | } |
JonFreeman | 3:43cb067ecd00 | 217 | if (first_p < p->min || first_p > p->max) { |
JonFreeman | 3:43cb067ecd00 | 218 | pc.printf ("%s\r\nParameter min %d, max %d, you entered %d. Not setting\r\n", p->txt, p->min, p->max, first_p); |
JonFreeman | 3:43cb067ecd00 | 219 | return ; |
JonFreeman | 3:43cb067ecd00 | 220 | } |
JonFreeman | 3:43cb067ecd00 | 221 | pc.printf ("Hoping to set [%s] to %d\r\n", p->txt, first_p); |
JonFreeman | 3:43cb067ecd00 | 222 | switch (cmd_num) { |
JonFreeman | 3:43cb067ecd00 | 223 | case OP_MODE: // |
JonFreeman | 3:43cb067ecd00 | 224 | case WARM_UP_DELAY: |
JonFreeman | 3:43cb067ecd00 | 225 | case WARMUP_SERVO_POS: |
JonFreeman | 3:43cb067ecd00 | 226 | case SPEED_CTRL_P: |
JonFreeman | 3:43cb067ecd00 | 227 | case SERVO_DIR: |
JonFreeman | 3:43cb067ecd00 | 228 | i = user_settings.rd(cmd_num); |
JonFreeman | 3:43cb067ecd00 | 229 | if (i == first_p) |
JonFreeman | 3:43cb067ecd00 | 230 | pc.printf ("No need, [%s] already set to %d\r\n", p->txt, i); |
JonFreeman | 3:43cb067ecd00 | 231 | else { |
JonFreeman | 3:43cb067ecd00 | 232 | user_settings.wr((char)first_p, cmd_num); |
JonFreeman | 3:43cb067ecd00 | 233 | save_settings = true; |
JonFreeman | 3:43cb067ecd00 | 234 | pc.printf ("Setting [%s] to %d\r\n", p->txt, first_p); |
JonFreeman | 3:43cb067ecd00 | 235 | } |
JonFreeman | 3:43cb067ecd00 | 236 | break; |
JonFreeman | 3:43cb067ecd00 | 237 | default: |
JonFreeman | 3:43cb067ecd00 | 238 | pc.printf ("No code for [%s]\r\n", p->txt); |
JonFreeman | 3:43cb067ecd00 | 239 | break; |
JonFreeman | 3:43cb067ecd00 | 240 | } |
JonFreeman | 3:43cb067ecd00 | 241 | if (save_settings) |
JonFreeman | 3:43cb067ecd00 | 242 | user_settings.save(); |
JonFreeman | 0:77803b3ee157 | 243 | } |
JonFreeman | 0:77803b3ee157 | 244 | |
JonFreeman | 3:43cb067ecd00 | 245 | extern void auto_test_initiate (int bulb_count) ; |
JonFreeman | 3:43cb067ecd00 | 246 | void auto_test_kickoff_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 247 | auto_test_initiate ((int)a.dbl[0]); |
JonFreeman | 0:77803b3ee157 | 248 | } |
JonFreeman | 0:77803b3ee157 | 249 | |
JonFreeman | 3:43cb067ecd00 | 250 | void test_Fsfs_cmd (struct parameters & a) { |
JonFreeman | 3:43cb067ecd00 | 251 | uint32_t rpm = (uint32_t)a.dbl[0]; |
JonFreeman | 3:43cb067ecd00 | 252 | pc.printf ("Field.set_for_speed %d returned %d\r\n", rpm, Field.set_for_speed(rpm)); |
JonFreeman | 1:450090bdb6f4 | 253 | } |
JonFreeman | 1:450090bdb6f4 | 254 | |
JonFreeman | 0:77803b3ee157 | 255 | void null_cmd (struct parameters & a) { |
JonFreeman | 0:77803b3ee157 | 256 | pc.printf ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]); |
JonFreeman | 0:77803b3ee157 | 257 | } |
JonFreeman | 0:77803b3ee157 | 258 | |
JonFreeman | 0:77803b3ee157 | 259 | void menucmd (struct parameters & a); |
JonFreeman | 0:77803b3ee157 | 260 | |
JonFreeman | 0:77803b3ee157 | 261 | struct kb_command { |
JonFreeman | 0:77803b3ee157 | 262 | const char * cmd_word; // points to text e.g. "menu" |
JonFreeman | 0:77803b3ee157 | 263 | const char * explan; |
JonFreeman | 0:77803b3ee157 | 264 | void (*f)(struct parameters &); // points to function |
JonFreeman | 0:77803b3ee157 | 265 | } ; |
JonFreeman | 0:77803b3ee157 | 266 | |
JonFreeman | 0:77803b3ee157 | 267 | struct kb_command const command_list[] = { |
JonFreeman | 0:77803b3ee157 | 268 | {"?", "Lists available commands, same as ls", menucmd}, |
JonFreeman | 5:6ca3e7ffc553 | 269 | {"cp", "Charge pump disable (0), enable (!0)", charge_pump_override}, |
JonFreeman | 5:6ca3e7ffc553 | 270 | {"vo", "Set out volts to ESC 0 - 100 pct", set_v_out_opamp}, |
JonFreeman | 3:43cb067ecd00 | 271 | {"ft", "Test Field.set_for_speed fn", test_Fsfs_cmd}, |
JonFreeman | 3:43cb067ecd00 | 272 | {"at", "Initiate Auto Test sequence", auto_test_kickoff_cmd}, |
JonFreeman | 3:43cb067ecd00 | 273 | {"svod", "Set servo sense 0 or 1", servodir_cmd}, |
JonFreeman | 3:43cb067ecd00 | 274 | {"sd", "Set User Settings Defaults", set_defaults_cmd}, |
JonFreeman | 3:43cb067ecd00 | 275 | {"us", "Set User Settings", mode20_cmd}, |
JonFreeman | 3:43cb067ecd00 | 276 | {"tt", "Table Tweak 0 - 100", table_tweak_cmd}, |
JonFreeman | 3:43cb067ecd00 | 277 | {"ss", "Set Speed 0 - 8000 RPM", ss_cmd}, |
JonFreeman | 3:43cb067ecd00 | 278 | {"sp", "Set Speed 0 - 100 percent", sp_cmd}, |
JonFreeman | 3:43cb067ecd00 | 279 | // {"tl", "Throttle logger tester, enter param 0.0 - 1.0", throt_log_cmd}, |
JonFreeman | 0:77803b3ee157 | 280 | {"rf", "Check rise and fall on VEXT", rfcmd}, |
JonFreeman | 0:77803b3ee157 | 281 | {"v", "Read Battery volts", vcmd}, |
JonFreeman | 3:43cb067ecd00 | 282 | {"i", "Read Ammeter", acmd}, |
JonFreeman | 3:43cb067ecd00 | 283 | {"fl", "Field limiter set 0 to 99 percent", fls_cmd}, |
JonFreeman | 3:43cb067ecd00 | 284 | {"mode", "Set operating mode - as us23", mode_cmd}, |
JonFreeman | 3:43cb067ecd00 | 285 | {"slope", "Field limiter set pct 0 to 99 @3k, slope pct per k above", slope_cmd}, |
JonFreeman | 1:450090bdb6f4 | 286 | {"q", "Query system - toggle message stream on/off", query_system}, |
JonFreeman | 0:77803b3ee157 | 287 | {"nu", "do nothing", null_cmd}, |
JonFreeman | 0:77803b3ee157 | 288 | }; |
JonFreeman | 0:77803b3ee157 | 289 | |
JonFreeman | 0:77803b3ee157 | 290 | const int numof_menu_items = sizeof(command_list) / sizeof(kb_command); |
JonFreeman | 0:77803b3ee157 | 291 | void menucmd (struct parameters & a) |
JonFreeman | 0:77803b3ee157 | 292 | { |
JonFreeman | 1:450090bdb6f4 | 293 | pc.printf("\r\nIntelligent Alternator Controller - Jon Freeman 2020\r\nAt menucmd function - listing commands:-\r\n"); |
JonFreeman | 0:77803b3ee157 | 294 | for(int i = 0; i < numof_menu_items; i++) |
JonFreeman | 0:77803b3ee157 | 295 | pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan); |
JonFreeman | 0:77803b3ee157 | 296 | pc.printf("End of List of Commands\r\n"); |
JonFreeman | 0:77803b3ee157 | 297 | } |
JonFreeman | 0:77803b3ee157 | 298 | |
JonFreeman | 0:77803b3ee157 | 299 | void command_line_interpreter () |
JonFreeman | 0:77803b3ee157 | 300 | { |
JonFreeman | 1:450090bdb6f4 | 301 | |
JonFreeman | 0:77803b3ee157 | 302 | const int MAX_CMD_LEN = 120; |
JonFreeman | 0:77803b3ee157 | 303 | static char cmd_line[MAX_CMD_LEN + 4]; |
JonFreeman | 0:77803b3ee157 | 304 | static int cl_index = 0; |
JonFreeman | 0:77803b3ee157 | 305 | int ch; |
JonFreeman | 0:77803b3ee157 | 306 | char * pEnd; |
JonFreeman | 0:77803b3ee157 | 307 | static struct parameters param_block ; |
JonFreeman | 0:77803b3ee157 | 308 | while (pc.readable()) { |
JonFreeman | 0:77803b3ee157 | 309 | ch = tolower(pc.getc()); |
JonFreeman | 0:77803b3ee157 | 310 | // pc.printf("%c", ch); |
JonFreeman | 0:77803b3ee157 | 311 | if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines |
JonFreeman | 0:77803b3ee157 | 312 | pc.printf ("Error!! Stupidly long cmd line\r\n"); |
JonFreeman | 0:77803b3ee157 | 313 | cl_index = 0; |
JonFreeman | 0:77803b3ee157 | 314 | } |
JonFreeman | 0:77803b3ee157 | 315 | if (ch == '\r' || ch >= ' ' && ch <= 'z') |
JonFreeman | 0:77803b3ee157 | 316 | pc.printf("%c", ch); |
JonFreeman | 0:77803b3ee157 | 317 | else { // Using <Ctrl>+ 'F', 'B' for Y, 'L', 'R' for X, 'U', 'D' for Z |
JonFreeman | 0:77803b3ee157 | 318 | cl_index = 0; // 6 2 12 18 21 4 |
JonFreeman | 0:77803b3ee157 | 319 | pc.printf("[%d]", ch); |
JonFreeman | 0:77803b3ee157 | 320 | //nudger (ch); // was used on cnc to nudge axes a tad |
JonFreeman | 0:77803b3ee157 | 321 | } |
JonFreeman | 0:77803b3ee157 | 322 | if(ch != '\r') // was this the 'Enter' key? |
JonFreeman | 0:77803b3ee157 | 323 | cmd_line[cl_index++] = ch; // added char to command being assembled |
JonFreeman | 0:77803b3ee157 | 324 | else { // key was CR, may or may not be command to lookup |
JonFreeman | 0:77803b3ee157 | 325 | cmd_line[cl_index] = 0; // null terminate command string |
JonFreeman | 0:77803b3ee157 | 326 | if(cl_index) { // If have got some chars to lookup |
JonFreeman | 0:77803b3ee157 | 327 | int i, wrdlen; |
JonFreeman | 0:77803b3ee157 | 328 | for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list |
JonFreeman | 0:77803b3ee157 | 329 | wrdlen = strlen(command_list[i].cmd_word); |
JonFreeman | 0:77803b3ee157 | 330 | if(strncmp(command_list[i].cmd_word, cmd_line, wrdlen) == 0 && !isalpha(cmd_line[wrdlen])) { // If match found |
JonFreeman | 0:77803b3ee157 | 331 | for (int k = 0; k < MAX_PARAMS; k++) { |
JonFreeman | 0:77803b3ee157 | 332 | param_block.dbl[k] = 0.0; |
JonFreeman | 0:77803b3ee157 | 333 | } |
JonFreeman | 0:77803b3ee157 | 334 | param_block.position_in_list = i; |
JonFreeman | 3:43cb067ecd00 | 335 | //param_block.last_time = clock (); |
JonFreeman | 0:77803b3ee157 | 336 | param_block.numof_dbls = 0; |
JonFreeman | 0:77803b3ee157 | 337 | pEnd = cmd_line + wrdlen; |
JonFreeman | 0:77803b3ee157 | 338 | while (*pEnd) { // Assemble all numerics as doubles |
JonFreeman | 0:77803b3ee157 | 339 | param_block.dbl[param_block.numof_dbls++] = strtod (pEnd, &pEnd); |
JonFreeman | 0:77803b3ee157 | 340 | while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) { |
JonFreeman | 0:77803b3ee157 | 341 | pEnd++; |
JonFreeman | 0:77803b3ee157 | 342 | } |
JonFreeman | 0:77803b3ee157 | 343 | } |
JonFreeman | 0:77803b3ee157 | 344 | pc.printf ("\r\n"); |
JonFreeman | 0:77803b3ee157 | 345 | // for (int k = 0; k < param_block.numof_dbls; k++) |
JonFreeman | 0:77803b3ee157 | 346 | // pc.printf ("Read %.3f\r\n", param_block.dbl[k]); |
JonFreeman | 3:43cb067ecd00 | 347 | // param_block.times[i] = clock(); |
JonFreeman | 0:77803b3ee157 | 348 | command_list[i].f(param_block); // execute command |
JonFreeman | 0:77803b3ee157 | 349 | i = numof_menu_items + 1; // to exit for loop |
JonFreeman | 0:77803b3ee157 | 350 | } // end of match found |
JonFreeman | 0:77803b3ee157 | 351 | } // End of for numof_menu_items |
JonFreeman | 0:77803b3ee157 | 352 | if(i == numof_menu_items) |
JonFreeman | 0:77803b3ee157 | 353 | pc.printf("No Match Found for CMD [%s]\r\n", cmd_line); |
JonFreeman | 0:77803b3ee157 | 354 | } // End of If have got some chars to lookup |
JonFreeman | 0:77803b3ee157 | 355 | pc.printf("\r\n>"); |
JonFreeman | 0:77803b3ee157 | 356 | cl_index = 0; |
JonFreeman | 0:77803b3ee157 | 357 | } // End of else key was CR, may or may not be command to lookup |
JonFreeman | 0:77803b3ee157 | 358 | } // End of while (pc.readable()) |
JonFreeman | 1:450090bdb6f4 | 359 | |
JonFreeman | 0:77803b3ee157 | 360 | } |
JonFreeman | 0:77803b3ee157 | 361 | |
JonFreeman | 0:77803b3ee157 | 362 |