Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM
cli_nortos.cpp@4:67478861c670, 2018-04-09 (annotated)
- Committer:
- JonFreeman
- Date:
- Mon Apr 09 07:51:37 2018 +0000
- Revision:
- 4:67478861c670
- Child:
- 5:21a8ac83142c
First edit of code from 2017 for new Twin BLDC controller boards
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| JonFreeman | 4:67478861c670 | 1 | #include "mbed.h" |
| JonFreeman | 4:67478861c670 | 2 | //#include "BufferedSerial.h" |
| JonFreeman | 4:67478861c670 | 3 | #include <cctype> |
| JonFreeman | 4:67478861c670 | 4 | #include "Electric_Loco.h" |
| JonFreeman | 4:67478861c670 | 5 | using namespace std; |
| JonFreeman | 4:67478861c670 | 6 | |
| JonFreeman | 4:67478861c670 | 7 | //extern int I_Am () ; // Returns boards id number as ASCII char '0', '1' etc. Code for Broadcast = '\r' |
| JonFreeman | 4:67478861c670 | 8 | //typedef double fl_typ; // |
| JonFreeman | 4:67478861c670 | 9 | |
| JonFreeman | 4:67478861c670 | 10 | const int BROADCAST = '\r'; |
| JonFreeman | 4:67478861c670 | 11 | const int MAX_PARAMS = 20; |
| JonFreeman | 4:67478861c670 | 12 | struct parameters { |
| JonFreeman | 4:67478861c670 | 13 | // int32_t times[numof_menu_items]; |
| JonFreeman | 4:67478861c670 | 14 | // int32_t times[50]; |
| JonFreeman | 4:67478861c670 | 15 | int32_t position_in_list, last_time, numof_dbls, target_unit; |
| JonFreeman | 4:67478861c670 | 16 | double dbl[MAX_PARAMS]; |
| JonFreeman | 4:67478861c670 | 17 | bool respond; |
| JonFreeman | 4:67478861c670 | 18 | } ; |
| JonFreeman | 4:67478861c670 | 19 | |
| JonFreeman | 4:67478861c670 | 20 | // WithOUT RTOS |
| JonFreeman | 4:67478861c670 | 21 | extern Serial pc; |
| JonFreeman | 4:67478861c670 | 22 | //extern void set_I_limit (double p) ; // Sets max motor current |
| JonFreeman | 4:67478861c670 | 23 | //extern void set_V_limit (double p) ; // Sets max motor voltage |
| JonFreeman | 4:67478861c670 | 24 | extern void send_test () ; |
| JonFreeman | 4:67478861c670 | 25 | |
| JonFreeman | 4:67478861c670 | 26 | void null_cmd (struct parameters & a) { |
| JonFreeman | 4:67478861c670 | 27 | pc.printf ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]); |
| JonFreeman | 4:67478861c670 | 28 | } |
| JonFreeman | 4:67478861c670 | 29 | |
| JonFreeman | 4:67478861c670 | 30 | |
| JonFreeman | 4:67478861c670 | 31 | /*struct motorpairoptions { // This to be user settable in eeprom, 32 bytes |
| JonFreeman | 4:67478861c670 | 32 | uint8_t MotA_dir, // 0 or 1 |
| JonFreeman | 4:67478861c670 | 33 | MotB_dir, // 0 or 1 |
| JonFreeman | 4:67478861c670 | 34 | gang, // 0 for separate control (robot mode), 1 for ganged loco bogie mode |
| JonFreeman | 4:67478861c670 | 35 | serv1, // 0, 1, 2 = Not used, Input, Output |
| JonFreeman | 4:67478861c670 | 36 | serv2, // 0, 1, 2 = Not used, Input, Output |
| JonFreeman | 4:67478861c670 | 37 | cmd_source, // 0 Invalid, 1 COM1, 2 COM2, 3 Pot, 4 Servo1, 5 Servo2 |
| JonFreeman | 4:67478861c670 | 38 | last; |
| JonFreeman | 4:67478861c670 | 39 | } ; |
| JonFreeman | 4:67478861c670 | 40 | */ |
| JonFreeman | 4:67478861c670 | 41 | /*struct optpar { |
| JonFreeman | 4:67478861c670 | 42 | int min, max, def; |
| JonFreeman | 4:67478861c670 | 43 | const char * t; |
| JonFreeman | 4:67478861c670 | 44 | } ; |
| JonFreeman | 4:67478861c670 | 45 | struct optpar const option_list[] = { |
| JonFreeman | 4:67478861c670 | 46 | {0, 1, 1, "MotorA direction 0 or 1"}, |
| JonFreeman | 4:67478861c670 | 47 | {0, 1, 0, "MotorB direction 0 or 1"}, |
| JonFreeman | 4:67478861c670 | 48 | {0, 1, 1, "gang 0 for separate control (robot mode), 1 for ganged loco bogie mode"}, |
| JonFreeman | 4:67478861c670 | 49 | {0, 2, 2, "Servo1 0, 1, 2 = Not used, Input, Output"}, |
| JonFreeman | 4:67478861c670 | 50 | {0, 2, 2, "Servo2 0, 1, 2 = Not used, Input, Output"}, |
| JonFreeman | 4:67478861c670 | 51 | {1, 5, 2, "Command source 0 Invalid, 1 COM1, 2 COM2, 3 Pot, 4 Servo1, 5 Servo2"}, |
| JonFreeman | 4:67478861c670 | 52 | {0, 9, 0, "Alternative ID 0 to 9"}, |
| JonFreeman | 4:67478861c670 | 53 | } ; |
| JonFreeman | 4:67478861c670 | 54 | */ |
| JonFreeman | 4:67478861c670 | 55 | void menucmd (struct parameters & a); |
| JonFreeman | 4:67478861c670 | 56 | |
| JonFreeman | 4:67478861c670 | 57 | void kd_cmd (struct parameters & a) // kick the watchdog |
| JonFreeman | 4:67478861c670 | 58 | { |
| JonFreeman | 4:67478861c670 | 59 | } |
| JonFreeman | 4:67478861c670 | 60 | |
| JonFreeman | 4:67478861c670 | 61 | |
| JonFreeman | 4:67478861c670 | 62 | /*void who_cmd (struct parameters & a) |
| JonFreeman | 4:67478861c670 | 63 | { |
| JonFreeman | 4:67478861c670 | 64 | int i = I_Am (); |
| JonFreeman | 4:67478861c670 | 65 | if (I_Am() == a.target_unit) |
| JonFreeman | 4:67478861c670 | 66 | pc.printf ("Hi there, I am %c\r\n", a.target_unit); |
| JonFreeman | 4:67478861c670 | 67 | }*/ |
| JonFreeman | 4:67478861c670 | 68 | |
| JonFreeman | 4:67478861c670 | 69 | struct kb_command { |
| JonFreeman | 4:67478861c670 | 70 | const char * cmd_word; // points to text e.g. "menu" |
| JonFreeman | 4:67478861c670 | 71 | const char * explan; |
| JonFreeman | 4:67478861c670 | 72 | void (*f)(struct parameters &); // points to function |
| JonFreeman | 4:67478861c670 | 73 | } ; |
| JonFreeman | 4:67478861c670 | 74 | |
| JonFreeman | 4:67478861c670 | 75 | struct kb_command const command_list[] = { |
| JonFreeman | 4:67478861c670 | 76 | {"ls", "Lists available commands", menucmd}, |
| JonFreeman | 4:67478861c670 | 77 | {"?", "Lists available commands, same as ls", menucmd}, |
| JonFreeman | 4:67478861c670 | 78 | // {"s", "seredgetest", s_cmd}, |
| JonFreeman | 4:67478861c670 | 79 | // {"fw", "forward", fw_cmd}, |
| JonFreeman | 4:67478861c670 | 80 | // {"re", "reverse", re_cmd}, |
| JonFreeman | 4:67478861c670 | 81 | // {"rb", "regen brake 0 to 99 %", rb_cmd}, |
| JonFreeman | 4:67478861c670 | 82 | // {"hb", "hand brake", hb_cmd}, |
| JonFreeman | 4:67478861c670 | 83 | // {"v", "set motors V percent RANGE 0 to 100", v_cmd}, |
| JonFreeman | 4:67478861c670 | 84 | // {"i", "set motors I percent RANGE 0 to 100", i_cmd}, |
| JonFreeman | 4:67478861c670 | 85 | // {"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd}, |
| JonFreeman | 4:67478861c670 | 86 | // {"who", "search for connected units, e.g. 3who returs 'Hi there' if found", who_cmd}, |
| JonFreeman | 4:67478861c670 | 87 | // {"mode", "read or set params in eeprom", mode_cmd}, |
| JonFreeman | 4:67478861c670 | 88 | // {"erase", "set eeprom contents to all 0xff", erase_cmd}, |
| JonFreeman | 4:67478861c670 | 89 | {"kd", "kick the dog", kd_cmd}, |
| JonFreeman | 4:67478861c670 | 90 | {"nu", "do nothing", null_cmd}, |
| JonFreeman | 4:67478861c670 | 91 | }; |
| JonFreeman | 4:67478861c670 | 92 | |
| JonFreeman | 4:67478861c670 | 93 | const int numof_menu_items = sizeof(command_list) / sizeof(kb_command); |
| JonFreeman | 4:67478861c670 | 94 | void menucmd (struct parameters & a) |
| JonFreeman | 4:67478861c670 | 95 | { |
| JonFreeman | 4:67478861c670 | 96 | pc.printf("\r\n\nDouble Brushless Motor Driver 2018\r\nAt menucmd function - listing commands:-\r\n"); |
| JonFreeman | 4:67478861c670 | 97 | for(int i = 0; i < numof_menu_items; i++) |
| JonFreeman | 4:67478861c670 | 98 | pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan); |
| JonFreeman | 4:67478861c670 | 99 | pc.printf("End of List of Commands\r\n"); |
| JonFreeman | 4:67478861c670 | 100 | } |
| JonFreeman | 4:67478861c670 | 101 | |
| JonFreeman | 4:67478861c670 | 102 | |
| JonFreeman | 4:67478861c670 | 103 | /* |
| JonFreeman | 4:67478861c670 | 104 | New - March 2018 |
| JonFreeman | 4:67478861c670 | 105 | Using opto isolated serial port, paralleled up using same pair to multiple boards running this code. |
| JonFreeman | 4:67478861c670 | 106 | New feature - commands have optional prefix digit 0-9 indicating which unit message is addressed to. |
| JonFreeman | 4:67478861c670 | 107 | Commands without prefix digit - broadcast to all units, none to respond. |
| JonFreeman | 4:67478861c670 | 108 | Only units recognising its address from prefix digit may respond. This avoids bus contention. |
| JonFreeman | 4:67478861c670 | 109 | But for BROADCAST commands, '0' may respond on behalf of the group |
| JonFreeman | 4:67478861c670 | 110 | */ |
| JonFreeman | 4:67478861c670 | 111 | //void command_line_interpreter (void const *argument) |
| JonFreeman | 4:67478861c670 | 112 | void command_line_interpreter () |
| JonFreeman | 4:67478861c670 | 113 | { |
| JonFreeman | 4:67478861c670 | 114 | const int MAX_CMD_LEN = 120; |
| JonFreeman | 4:67478861c670 | 115 | static char cmd_line[MAX_CMD_LEN + 4]; |
| JonFreeman | 4:67478861c670 | 116 | static int cl_index = 0; |
| JonFreeman | 4:67478861c670 | 117 | int ch; |
| JonFreeman | 4:67478861c670 | 118 | char * pEnd, * cmd_line_ptr; |
| JonFreeman | 4:67478861c670 | 119 | static struct parameters param_block ; |
| JonFreeman | 4:67478861c670 | 120 | // com = &com2; |
| JonFreeman | 4:67478861c670 | 121 | // while (pc.readable()) { |
| JonFreeman | 4:67478861c670 | 122 | while (pc.readable()) { |
| JonFreeman | 4:67478861c670 | 123 | ch = tolower(pc.getc()); |
| JonFreeman | 4:67478861c670 | 124 | if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines |
| JonFreeman | 4:67478861c670 | 125 | pc.printf ("Error!! Stupidly long cmd line\r\n"); |
| JonFreeman | 4:67478861c670 | 126 | cl_index = 0; |
| JonFreeman | 4:67478861c670 | 127 | } |
| JonFreeman | 4:67478861c670 | 128 | if(ch != '\r') // was this the 'Enter' key? |
| JonFreeman | 4:67478861c670 | 129 | cmd_line[cl_index++] = ch; // added char to command being assembled |
| JonFreeman | 4:67478861c670 | 130 | else { // key was CR, may or may not be command to lookup |
| JonFreeman | 4:67478861c670 | 131 | param_block.target_unit = BROADCAST; // Broadcast |
| JonFreeman | 4:67478861c670 | 132 | cmd_line_ptr = cmd_line; |
| JonFreeman | 4:67478861c670 | 133 | cmd_line[cl_index] = 0; // null terminate command string |
| JonFreeman | 4:67478861c670 | 134 | if(cl_index) { // If have got some chars to lookup |
| JonFreeman | 4:67478861c670 | 135 | int i, wrdlen; |
| JonFreeman | 4:67478861c670 | 136 | if (isdigit(cmd_line[0])) { // Look for command with prefix digit |
| JonFreeman | 4:67478861c670 | 137 | cmd_line_ptr++; // point past identified digit prefix |
| JonFreeman | 4:67478861c670 | 138 | param_block.target_unit = cmd_line[0]; // '0' to '9' |
| JonFreeman | 4:67478861c670 | 139 | //pc.printf ("Got prefix %c\r\n", cmd_line[0]); |
| JonFreeman | 4:67478861c670 | 140 | } |
| JonFreeman | 4:67478861c670 | 141 | for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list |
| JonFreeman | 4:67478861c670 | 142 | wrdlen = strlen(command_list[i].cmd_word); |
| JonFreeman | 4:67478861c670 | 143 | if(strncmp(command_list[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen])) { // If match found |
| JonFreeman | 4:67478861c670 | 144 | for (int k = 0; k < MAX_PARAMS; k++) { |
| JonFreeman | 4:67478861c670 | 145 | param_block.dbl[k] = 0.0; |
| JonFreeman | 4:67478861c670 | 146 | } |
| JonFreeman | 4:67478861c670 | 147 | param_block.position_in_list = i; |
| JonFreeman | 4:67478861c670 | 148 | param_block.last_time = clock (); |
| JonFreeman | 4:67478861c670 | 149 | param_block.numof_dbls = 0; |
| JonFreeman | 4:67478861c670 | 150 | pEnd = cmd_line_ptr + wrdlen; |
| JonFreeman | 4:67478861c670 | 151 | while (*pEnd) { // Assemble all numerics as doubles |
| JonFreeman | 4:67478861c670 | 152 | param_block.dbl[param_block.numof_dbls++] = strtod (pEnd, &pEnd); |
| JonFreeman | 4:67478861c670 | 153 | while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) { |
| JonFreeman | 4:67478861c670 | 154 | pEnd++; |
| JonFreeman | 4:67478861c670 | 155 | } |
| JonFreeman | 4:67478861c670 | 156 | } |
| JonFreeman | 4:67478861c670 | 157 | //pc.printf ("\r\n"); // Not allowed as many may output this. |
| JonFreeman | 4:67478861c670 | 158 | //for (int k = 0; k < param_block.numof_dbls; k++) |
| JonFreeman | 4:67478861c670 | 159 | // pc.printf ("Read %.3f\r\n", param_block.dbl[k]); |
| JonFreeman | 4:67478861c670 | 160 | // param_block.times[i] = clock(); |
| JonFreeman | 4:67478861c670 | 161 | // if ((param_block.target_unit == BROADCAST) && (I_Am() == '0')) |
| JonFreeman | 4:67478861c670 | 162 | // param_block.respond = true; |
| JonFreeman | 4:67478861c670 | 163 | command_list[i].f(param_block); // execute command |
| JonFreeman | 4:67478861c670 | 164 | i = numof_menu_items + 1; // to exit for loop |
| JonFreeman | 4:67478861c670 | 165 | } // end of match found |
| JonFreeman | 4:67478861c670 | 166 | } // End of for numof_menu_items |
| JonFreeman | 4:67478861c670 | 167 | if(i == numof_menu_items) |
| JonFreeman | 4:67478861c670 | 168 | pc.printf("No Match Found for CMD [%s]\r\n", cmd_line); |
| JonFreeman | 4:67478861c670 | 169 | } // End of If have got some chars to lookup |
| JonFreeman | 4:67478861c670 | 170 | //pc.printf("\r\n>"); |
| JonFreeman | 4:67478861c670 | 171 | cl_index = 0; |
| JonFreeman | 4:67478861c670 | 172 | } // End of else key was CR, may or may not be command to lookup |
| JonFreeman | 4:67478861c670 | 173 | } // End of while (pc.readable()) |
| JonFreeman | 4:67478861c670 | 174 | // Thread::wait(20); // Using RTOS on this project |
| JonFreeman | 4:67478861c670 | 175 | // } |
| JonFreeman | 4:67478861c670 | 176 | } |
| JonFreeman | 4:67478861c670 | 177 | |
| JonFreeman | 4:67478861c670 | 178 |