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

Committer:
JonFreeman
Date:
Sat Apr 25 15:35:58 2020 +0000
Revision:
1:450090bdb6f4
Parent:
0:77803b3ee157
Child:
2:8e7b51353f32
About to pick this up again late Apr 2020.;

Who changed what in which revision?

UserRevisionLine numberNew 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 0:77803b3ee157 8 #include "Alternator.h"
JonFreeman 0:77803b3ee157 9 //#include "BufferedSerial.h"
JonFreeman 0:77803b3ee157 10 #include <cctype>
JonFreeman 0:77803b3ee157 11 using namespace std;
JonFreeman 0:77803b3ee157 12
JonFreeman 1:450090bdb6f4 13 extern eeprom_settings user_settings ;
JonFreeman 0:77803b3ee157 14 //eeprom_settings mode ;
JonFreeman 0:77803b3ee157 15
JonFreeman 1:450090bdb6f4 16 //extern int ver, vef, measured_pw_us;
JonFreeman 1:450090bdb6f4 17 extern void set_throttle_limit (struct parameters & a) ;
JonFreeman 1:450090bdb6f4 18 extern void speed_control_factor_set (struct parameters & a) ;
JonFreeman 1:450090bdb6f4 19 extern void query_system (struct parameters & a) ;
JonFreeman 0:77803b3ee157 20 extern uint32_t ReadEngineRPM () ;
JonFreeman 0:77803b3ee157 21 extern double Read_BatteryVolts () ;
JonFreeman 1:450090bdb6f4 22 extern void Read_Ammeter (double *) ;
JonFreeman 0:77803b3ee157 23
JonFreeman 0:77803b3ee157 24
JonFreeman 0:77803b3ee157 25
JonFreeman 0:77803b3ee157 26
JonFreeman 0:77803b3ee157 27
JonFreeman 0:77803b3ee157 28 // WithOUT RTOS
JonFreeman 0:77803b3ee157 29 //extern BufferedSerial pc;
JonFreeman 1:450090bdb6f4 30
JonFreeman 1:450090bdb6f4 31 #ifdef TARGET_NUCLEO_L432KC //
JonFreeman 0:77803b3ee157 32 extern Serial pc;
JonFreeman 1:450090bdb6f4 33 #else
JonFreeman 1:450090bdb6f4 34 extern BufferedSerial pc;
JonFreeman 1:450090bdb6f4 35 #endif
JonFreeman 1:450090bdb6f4 36 //extern double test_pot; // These used in knifeandfork code testing only
JonFreeman 0:77803b3ee157 37
JonFreeman 0:77803b3ee157 38 //extern int numof_eeprom_options2 ;
JonFreeman 0:77803b3ee157 39 //extern struct optpar const option_list2[] ;
JonFreeman 0:77803b3ee157 40 extern struct optpar option_list2[] ;
JonFreeman 0:77803b3ee157 41
JonFreeman 0:77803b3ee157 42 /**void mode_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents
JonFreeman 0:77803b3ee157 43 * mode_cmd called only from pc comms. No sense calling from Touch Screen Controller
JonFreeman 0:77803b3ee157 44 *
JonFreeman 0:77803b3ee157 45 * Called without parameters - Lists to pc terminal current settings
JonFreeman 0:77803b3ee157 46 *
JonFreeman 0:77803b3ee157 47 */
JonFreeman 0:77803b3ee157 48 void mode19_cmd (struct parameters & a) // With no params, reads eeprom contents. With params sets eeprom contents
JonFreeman 0:77803b3ee157 49 {
JonFreeman 1:450090bdb6f4 50
JonFreeman 0:77803b3ee157 51 char temps[36];
JonFreeman 0:77803b3ee157 52 int i;
JonFreeman 0:77803b3ee157 53 pc.printf ("\r\nmode - Set system data in EEPROM - Jan 2019\r\nSyntax 'mode' with no parameters lists current state.\r\n");
JonFreeman 0:77803b3ee157 54 if (a.numof_dbls) { // If more than 0 parameters supplied
JonFreeman 0:77803b3ee157 55 for (i = 0; i < a.numof_dbls; i++)
JonFreeman 0:77803b3ee157 56 temps[i] = (char)a.dbl[i]; // recast doubles to char
JonFreeman 0:77803b3ee157 57 while (i < 33)
JonFreeman 0:77803b3ee157 58 temps[i++] = 0;
JonFreeman 0:77803b3ee157 59 i = (int)a.dbl[0];
JonFreeman 0:77803b3ee157 60 switch (i) {
JonFreeman 0:77803b3ee157 61 case 0: case 1: case 2: case 3: case 4:
JonFreeman 0:77803b3ee157 62 case 5: case 6: case 7: case 8:
JonFreeman 0:77803b3ee157 63 if (temps[1] >= option_list2[i].min && temps[1] <= option_list2[i].max)
JonFreeman 1:450090bdb6f4 64 user_settings.wr(temps[1], RPM0 + i);
JonFreeman 0:77803b3ee157 65 break;
JonFreeman 0:77803b3ee157 66 case 37: // set pwm scale factor
JonFreeman 0:77803b3ee157 67 if (temps[1] >= option_list2[PWM_SCALE].min && temps[1] <= option_list2[PWM_SCALE].max)
JonFreeman 1:450090bdb6f4 68 user_settings.wr(temps[1], PWM_SCALE);
JonFreeman 0:77803b3ee157 69 break;
JonFreeman 0:77803b3ee157 70 case 83: // set to defaults
JonFreeman 1:450090bdb6f4 71 user_settings.set_defaults ();
JonFreeman 0:77803b3ee157 72 break;
JonFreeman 0:77803b3ee157 73 case 9: // 9 Save settings
JonFreeman 1:450090bdb6f4 74 user_settings.save ();
JonFreeman 0:77803b3ee157 75 pc.printf ("Saving settings to EEPROM\r\n");
JonFreeman 0:77803b3ee157 76 break;
JonFreeman 0:77803b3ee157 77 default:
JonFreeman 0:77803b3ee157 78 break;
JonFreeman 0:77803b3ee157 79 } // endof switch
JonFreeman 0:77803b3ee157 80 } // endof // If more than 0 parameters supplied
JonFreeman 0:77803b3ee157 81 else {
JonFreeman 0:77803b3ee157 82 pc.printf ("No Changes\r\n");
JonFreeman 0:77803b3ee157 83 }
JonFreeman 1:450090bdb6f4 84 pc.printf ("mode 0\t%s, [%d]\r\n", option_list2[0].t, user_settings.rd(RPM0));
JonFreeman 1:450090bdb6f4 85 pc.printf ("mode 1\t%s, [%d]\r\n", option_list2[1].t, user_settings.rd(RPM1));
JonFreeman 1:450090bdb6f4 86 pc.printf ("mode 2\t%s, [%d]\r\n", option_list2[2].t, user_settings.rd(RPM2));
JonFreeman 1:450090bdb6f4 87 pc.printf ("mode 3\t%s, [%d]\r\n", option_list2[3].t, user_settings.rd(RPM3));
JonFreeman 1:450090bdb6f4 88 pc.printf ("mode 4\t%s, [%d]\r\n", option_list2[4].t, user_settings.rd(RPM4));
JonFreeman 1:450090bdb6f4 89 pc.printf ("mode 5\t%s, [%d]\r\n", option_list2[5].t, user_settings.rd(RPM5));
JonFreeman 1:450090bdb6f4 90 pc.printf ("mode 6\t%s, [%d]\r\n", option_list2[6].t, user_settings.rd(RPM6));
JonFreeman 1:450090bdb6f4 91 pc.printf ("mode 7\t%s, [%d]\r\n", option_list2[7].t, user_settings.rd(RPM7));
JonFreeman 1:450090bdb6f4 92 pc.printf ("mode 8\t%s, [%d]\r\n", option_list2[8].t, user_settings.rd(RPM8));
JonFreeman 0:77803b3ee157 93
JonFreeman 1:450090bdb6f4 94 pc.printf ("mode 37\t%s, [%d]\r\n", option_list2[PWM_SCALE].t, user_settings.rd(PWM_SCALE));
JonFreeman 0:77803b3ee157 95 pc.printf ("mode 83\tSet to defaults\r\n");
JonFreeman 0:77803b3ee157 96 pc.printf ("mode 9\tSave settings\r\r\n");
JonFreeman 0:77803b3ee157 97
JonFreeman 0:77803b3ee157 98 }
JonFreeman 0:77803b3ee157 99
JonFreeman 0:77803b3ee157 100 void gpcmd (struct parameters & a) {
JonFreeman 1:450090bdb6f4 101 pc.printf ("pwm=%.3f\r\n", user_settings.get_pwm ((int)a.dbl[0]));
JonFreeman 0:77803b3ee157 102 }
JonFreeman 0:77803b3ee157 103
JonFreeman 1:450090bdb6f4 104 extern VEXT_Data Field;
JonFreeman 1:450090bdb6f4 105
JonFreeman 0:77803b3ee157 106 void rfcmd (struct parameters & a) {
JonFreeman 1:450090bdb6f4 107 pc.printf ("Field.measured_period = %d, Field.measured_pw_us = %d, duty_cycle = %.3f\r\n", Field.measured_period, Field.measured_pw_us, Field.duty_cycle());
JonFreeman 0:77803b3ee157 108 }
JonFreeman 0:77803b3ee157 109
JonFreeman 0:77803b3ee157 110 extern void set_RPM_demand (uint32_t d) ;
JonFreeman 0:77803b3ee157 111
JonFreeman 0:77803b3ee157 112 void set_rpm_cmd (struct parameters & a) {
JonFreeman 0:77803b3ee157 113 pc.printf ("setting RPM to %d\r\n",(int)a.dbl[0]);
JonFreeman 0:77803b3ee157 114 set_RPM_demand ((uint32_t)a.dbl[0]);
JonFreeman 0:77803b3ee157 115 }
JonFreeman 0:77803b3ee157 116
JonFreeman 0:77803b3ee157 117 void speedcmd (struct parameters & a) {
JonFreeman 0:77803b3ee157 118 int s = ReadEngineRPM ();
JonFreeman 1:450090bdb6f4 119 pc.printf ("speed %d, pwm %.3f\r\n", s, user_settings.get_pwm(s));
JonFreeman 0:77803b3ee157 120 }
JonFreeman 0:77803b3ee157 121
JonFreeman 0:77803b3ee157 122 void vcmd (struct parameters & a) {
JonFreeman 0:77803b3ee157 123 pc.printf ("volts %.2f\r\n", Read_BatteryVolts());
JonFreeman 0:77803b3ee157 124 }
JonFreeman 0:77803b3ee157 125
JonFreeman 1:450090bdb6f4 126 void icmd (struct parameters & a) {
JonFreeman 1:450090bdb6f4 127 double results[4];
JonFreeman 1:450090bdb6f4 128 //double * ampsptr =
JonFreeman 1:450090bdb6f4 129 Read_Ammeter(results) ;
JonFreeman 1:450090bdb6f4 130 pc.printf ("amps %.3f, offset %.3f\r\n", results[0], results[1]);
JonFreeman 1:450090bdb6f4 131 }
JonFreeman 1:450090bdb6f4 132
JonFreeman 0:77803b3ee157 133 extern void set_servo (double p) ; // Only for test, called from cli
JonFreeman 0:77803b3ee157 134
JonFreeman 0:77803b3ee157 135 void set_servo_cmd (struct parameters & a) {
JonFreeman 0:77803b3ee157 136 double p = a.dbl[0] / 100.0;
JonFreeman 0:77803b3ee157 137 pc.printf ("servo %.2f\r\n", p);
JonFreeman 0:77803b3ee157 138 set_servo (p);
JonFreeman 0:77803b3ee157 139 }
JonFreeman 0:77803b3ee157 140
JonFreeman 1:450090bdb6f4 141 extern bool set_pwm (double) ; // Range 0.0 to 1.0
JonFreeman 1:450090bdb6f4 142 void p_cmd (struct parameters & a) {
JonFreeman 1:450090bdb6f4 143 // int32_t i = (int32_t)a.dbl[0];
JonFreeman 1:450090bdb6f4 144 pc.printf ("Setting PWM to %d percent\r\n", (int)(a.dbl[0] * 100.0));
JonFreeman 1:450090bdb6f4 145 set_pwm (a.dbl[0]);
JonFreeman 1:450090bdb6f4 146 }
JonFreeman 1:450090bdb6f4 147
JonFreeman 0:77803b3ee157 148 void null_cmd (struct parameters & a) {
JonFreeman 0:77803b3ee157 149 pc.printf ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
JonFreeman 0:77803b3ee157 150 }
JonFreeman 0:77803b3ee157 151
JonFreeman 0:77803b3ee157 152 void menucmd (struct parameters & a);
JonFreeman 0:77803b3ee157 153
JonFreeman 0:77803b3ee157 154 struct kb_command {
JonFreeman 0:77803b3ee157 155 const char * cmd_word; // points to text e.g. "menu"
JonFreeman 0:77803b3ee157 156 const char * explan;
JonFreeman 0:77803b3ee157 157 void (*f)(struct parameters &); // points to function
JonFreeman 0:77803b3ee157 158 } ;
JonFreeman 0:77803b3ee157 159
JonFreeman 0:77803b3ee157 160 struct kb_command const command_list[] = {
JonFreeman 0:77803b3ee157 161 {"?", "Lists available commands, same as ls", menucmd},
JonFreeman 0:77803b3ee157 162 {"rf", "Check rise and fall on VEXT", rfcmd},
JonFreeman 0:77803b3ee157 163 {"s", "Speed, RPM", speedcmd},
JonFreeman 0:77803b3ee157 164 {"v", "Read Battery volts", vcmd},
JonFreeman 1:450090bdb6f4 165 {"i", "Read Ammeter", icmd},
JonFreeman 1:450090bdb6f4 166 {"p", "Set PWM 0 to 2400???", p_cmd},
JonFreeman 1:450090bdb6f4 167 {"q", "Query system - toggle message stream on/off", query_system},
JonFreeman 0:77803b3ee157 168 {"gp","Get pwm from RPM", gpcmd},
JonFreeman 0:77803b3ee157 169 {"mode", "See or set eeprom values", mode19_cmd},
JonFreeman 0:77803b3ee157 170 {"nu", "do nothing", null_cmd},
JonFreeman 1:450090bdb6f4 171 #ifndef SPEED_CONTROL_ENABLE // Includes engine revs servo control loop
JonFreeman 0:77803b3ee157 172 {"ser","set throttle servo direct 0 - 99", set_servo_cmd},
JonFreeman 1:450090bdb6f4 173 #endif
JonFreeman 1:450090bdb6f4 174 {"sf","set speed control factor", speed_control_factor_set},
JonFreeman 1:450090bdb6f4 175 {"sv","set engine RPM demand 2500 - 6000", set_rpm_cmd},
JonFreeman 1:450090bdb6f4 176 {"tl","set throttle_limit 0.0-1.0", set_throttle_limit},
JonFreeman 0:77803b3ee157 177 };
JonFreeman 0:77803b3ee157 178
JonFreeman 0:77803b3ee157 179 const int numof_menu_items = sizeof(command_list) / sizeof(kb_command);
JonFreeman 0:77803b3ee157 180 void menucmd (struct parameters & a)
JonFreeman 0:77803b3ee157 181 {
JonFreeman 1:450090bdb6f4 182 pc.printf("\r\nIntelligent Alternator Controller - Jon Freeman 2020\r\nAt menucmd function - listing commands:-\r\n");
JonFreeman 0:77803b3ee157 183 for(int i = 0; i < numof_menu_items; i++)
JonFreeman 0:77803b3ee157 184 pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan);
JonFreeman 0:77803b3ee157 185 pc.printf("End of List of Commands\r\n");
JonFreeman 0:77803b3ee157 186 }
JonFreeman 0:77803b3ee157 187
JonFreeman 0:77803b3ee157 188 void command_line_interpreter ()
JonFreeman 0:77803b3ee157 189 {
JonFreeman 1:450090bdb6f4 190
JonFreeman 0:77803b3ee157 191 const int MAX_CMD_LEN = 120;
JonFreeman 0:77803b3ee157 192 static char cmd_line[MAX_CMD_LEN + 4];
JonFreeman 0:77803b3ee157 193 static int cl_index = 0;
JonFreeman 0:77803b3ee157 194 int ch;
JonFreeman 0:77803b3ee157 195 char * pEnd;
JonFreeman 0:77803b3ee157 196 static struct parameters param_block ;
JonFreeman 0:77803b3ee157 197 while (pc.readable()) {
JonFreeman 0:77803b3ee157 198 ch = tolower(pc.getc());
JonFreeman 0:77803b3ee157 199 // pc.printf("%c", ch);
JonFreeman 0:77803b3ee157 200 if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines
JonFreeman 0:77803b3ee157 201 pc.printf ("Error!! Stupidly long cmd line\r\n");
JonFreeman 0:77803b3ee157 202 cl_index = 0;
JonFreeman 0:77803b3ee157 203 }
JonFreeman 0:77803b3ee157 204 if (ch == '\r' || ch >= ' ' && ch <= 'z')
JonFreeman 0:77803b3ee157 205 pc.printf("%c", ch);
JonFreeman 0:77803b3ee157 206 else { // Using <Ctrl>+ 'F', 'B' for Y, 'L', 'R' for X, 'U', 'D' for Z
JonFreeman 0:77803b3ee157 207 cl_index = 0; // 6 2 12 18 21 4
JonFreeman 0:77803b3ee157 208 pc.printf("[%d]", ch);
JonFreeman 0:77803b3ee157 209 //nudger (ch); // was used on cnc to nudge axes a tad
JonFreeman 0:77803b3ee157 210 }
JonFreeman 0:77803b3ee157 211 if(ch != '\r') // was this the 'Enter' key?
JonFreeman 0:77803b3ee157 212 cmd_line[cl_index++] = ch; // added char to command being assembled
JonFreeman 0:77803b3ee157 213 else { // key was CR, may or may not be command to lookup
JonFreeman 0:77803b3ee157 214 cmd_line[cl_index] = 0; // null terminate command string
JonFreeman 0:77803b3ee157 215 if(cl_index) { // If have got some chars to lookup
JonFreeman 0:77803b3ee157 216 int i, wrdlen;
JonFreeman 0:77803b3ee157 217 for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list
JonFreeman 0:77803b3ee157 218 wrdlen = strlen(command_list[i].cmd_word);
JonFreeman 0:77803b3ee157 219 if(strncmp(command_list[i].cmd_word, cmd_line, wrdlen) == 0 && !isalpha(cmd_line[wrdlen])) { // If match found
JonFreeman 0:77803b3ee157 220 for (int k = 0; k < MAX_PARAMS; k++) {
JonFreeman 0:77803b3ee157 221 param_block.dbl[k] = 0.0;
JonFreeman 0:77803b3ee157 222 }
JonFreeman 0:77803b3ee157 223 param_block.position_in_list = i;
JonFreeman 0:77803b3ee157 224 param_block.last_time = clock ();
JonFreeman 0:77803b3ee157 225 param_block.numof_dbls = 0;
JonFreeman 0:77803b3ee157 226 pEnd = cmd_line + wrdlen;
JonFreeman 0:77803b3ee157 227 while (*pEnd) { // Assemble all numerics as doubles
JonFreeman 0:77803b3ee157 228 param_block.dbl[param_block.numof_dbls++] = strtod (pEnd, &pEnd);
JonFreeman 0:77803b3ee157 229 while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) {
JonFreeman 0:77803b3ee157 230 pEnd++;
JonFreeman 0:77803b3ee157 231 }
JonFreeman 0:77803b3ee157 232 }
JonFreeman 0:77803b3ee157 233 pc.printf ("\r\n");
JonFreeman 0:77803b3ee157 234 // for (int k = 0; k < param_block.numof_dbls; k++)
JonFreeman 0:77803b3ee157 235 // pc.printf ("Read %.3f\r\n", param_block.dbl[k]);
JonFreeman 0:77803b3ee157 236 param_block.times[i] = clock();
JonFreeman 0:77803b3ee157 237 command_list[i].f(param_block); // execute command
JonFreeman 0:77803b3ee157 238 i = numof_menu_items + 1; // to exit for loop
JonFreeman 0:77803b3ee157 239 } // end of match found
JonFreeman 0:77803b3ee157 240 } // End of for numof_menu_items
JonFreeman 0:77803b3ee157 241 if(i == numof_menu_items)
JonFreeman 0:77803b3ee157 242 pc.printf("No Match Found for CMD [%s]\r\n", cmd_line);
JonFreeman 0:77803b3ee157 243 } // End of If have got some chars to lookup
JonFreeman 0:77803b3ee157 244 pc.printf("\r\n>");
JonFreeman 0:77803b3ee157 245 cl_index = 0;
JonFreeman 0:77803b3ee157 246 } // End of else key was CR, may or may not be command to lookup
JonFreeman 0:77803b3ee157 247 } // End of while (pc.readable())
JonFreeman 1:450090bdb6f4 248
JonFreeman 0:77803b3ee157 249 }
JonFreeman 0:77803b3ee157 250
JonFreeman 0:77803b3ee157 251