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:
Fri Jun 28 19:32:51 2019 +0000
Revision:
0:77803b3ee157
Child:
1:450090bdb6f4
As at end June 2019

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