Touch screen drivers control dashboard for miniature locomotive. Features meters for speed, volts, power. Switches for lights, horns. Drives multiple STM3_ESC brushless motor controllers for complete brushless loco system as used in "The Brute" - www.jons-workshop.com
Dependencies: TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM
Diff: cli_TS_nortos.cpp
- Revision:
- 12:a25bdf135348
- Parent:
- 11:a573664b1a59
- Child:
- 14:6bcec5ac21ca
--- a/cli_TS_nortos.cpp Sat Jun 23 09:37:41 2018 +0000 +++ b/cli_TS_nortos.cpp Mon Jan 14 16:39:41 2019 +0000 @@ -1,87 +1,131 @@ //Loco_TS_2018 #include "mbed.h" -//#include "BufferedSerial.h" #include "AsyncSerial.hpp" #include <cctype> #include "Electric_Loco.h" using namespace std; -//extern int I_Am () ; // Returns boards id number as ASCII char '0', '1' etc. Code for Broadcast = '\r' -//typedef double fl_typ; // - const int BROADCAST = '\r'; // WithOUT RTOS extern Serial pc; -extern AsyncSerial com; -extern void send_test () ; +extern AsyncSerial com2escs; +extern error_handling_Jan_2019 Controller_Error ; +extern const char const_version_string[] ; // Version string, readable from serial ports -genio::genio (int dtype, int dlen) { +extern STM3_ESC_Interface My_STM3_ESC_boards ; + +/*genio::genio (int dtype, int dlen) { // constructor d_type = dtype; d_len = dlen; for (int i = 0; i < MAX_PARAMS; i++) { - ui[i] = 0; + si[i] = 0; dbl[i] = 0.0; } - count = 0; - available = false; + count = 0; // running total of times called + available = false; // bool + //available = 0; // if using integer rather than bool } -void genio::store (struct parameters & a) { // - count++; +void genio::store (struct parameters & a) { // copies up to MAX_PARAMS into int and double arrays + count++; // number of times this response rec'd this session available = true; - for (int i = 0; i < d_len; i++) { - ui[i] = (int32_t)a.dbl[i]; + for (int i = 0; i < d_len; i++) { // dlen // loaded on setup indicating expected num of parameters to handle. Why not just use MAX_PARAMS ? + si[i] = (int32_t)a.dbl[i]; dbl[i] = a.dbl[i]; } } -bool genio::read (uint32_t ** addr) { +bool genio::read (int32_t ** addr) { if (!available) return false; available = false; - *addr = ui; + *addr = si; // int32_t ui[MAX_PARAMS]; return true; } +*/ + +command_line_interpreter_core::command_line_interpreter_core (int p, int menulen, struct kb_command const * clistp) { + clist = clistp; + a.numof_menu_items = menulen; + a.numof_cl_values_read = 0; + portio = p; + cl_index = 0; +} + +int command_line_interpreter_core::clreadable () { + if (portio == 0) + return pc.readable(); + return com2escs.readable(); +} + +void command_line_interpreter_core::clputc (int c) { + if (portio == 0) + pc.putc (c); + else + com2escs.putc (c); +} + +int command_line_interpreter_core::clgetc () { + if (portio == 0) + return pc.getc(); + return com2escs.getc(); +} + void null_cmd (struct parameters & a) { pc.printf ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]); } - void menucmd (struct parameters & a); void kd_cmd (struct parameters & a) // kick the watchdog { } -extern void rpm_push (struct parameters & a) ; -extern void mph_push (struct parameters & a) ; -void uprpm_cmd (struct parameters & a) // controller rec'd rpm from driver boards -{ - rpm_push (a); -// a.gp_i ^= 1; // toggle lsb -} - void upmph_cmd (struct parameters & a) // controller rec'd mph from driver boards { - mph_push (a); -// a.gp_i ^= 1; // toggle lsb -} - -void uprdi_cmd (struct parameters & a) // controller rec'd rpm from driver boards -{ -// pc.printf ("RPM %d %d\r\n", (int)a.dbl[0], (int)a.dbl[1]); + My_STM3_ESC_boards.mph_update (a.dbl[1]); } -/*void who_cmd (struct parameters & a) +void TSver_cmd (struct parameters & a) // Report current TS software version to pc { - int i = I_Am (); - if (I_Am() == a.target_unit) - pc.printf ("Hi there, I am %c\r\n", a.target_unit); -}*/ + pc.printf ("ver %s\r\n", const_version_string); +} + +void boards_cmd (struct parameters & a) { + int boards[MAX_ESCS], count = 0; + My_STM3_ESC_boards.get_boards_list (boards); + while (boards[count] && count < MAX_ESCS) + count++; + pc.printf ("Board Count = %d\r\n", count); + if (count) { + pc.printf ("Boards found ^"); + for (int i = 0; i < count; i++) + pc.printf ("%c ", boards[i]); + pc.printf ("\r\n"); + } + else + pc.printf ("No STM3_ESC boards found\r\n"); +} + +void who_cmd (struct parameters & a) // Have read "whon" back from STM3_ESC where 'n' is STM3_Esc board ID number (ascii digit) +{ + int v = (int)a.dbl[0] | '0'; + if (a.numof_cl_values_read == 1 && isdigit(v)) { +// pc.printf ("who%c, vals read %d\r\n", (int)a.dbl[0] | '0', a.numof_cl_values_read); + My_STM3_ESC_boards.set_board_ID (v);// set_board_id (v); // just to test and prove can not add same board twice + } + else + pc.printf ("Garbage response to 'who', numof vals %d, value %c\r\n", a.numof_cl_values_read, v); +} + +void ver_req_cmd (struct parameters & a) // Touch Screen controller requesting version string from one specific ESC board +{ + pc.printf ("ver_req_cmd not yet implemented\r\n"); +} struct kb_command { const char * cmd_word; // points to text e.g. "menu" @@ -92,142 +136,32 @@ struct kb_command const command_list[] = { {"ls", "Lists available commands", menucmd}, {"?", "Lists available commands, same as ls", menucmd}, -// {"fw", "forward", fw_cmd}, -// {"re", "reverse", re_cmd}, -// {"rb", "regen brake 0 to 99 %", rb_cmd}, -// {"hb", "hand brake", hb_cmd}, -// {"v", "set motors V percent RANGE 0 to 100", v_cmd}, -// {"i", "set motors I percent RANGE 0 to 100", i_cmd}, -// {"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd}, -// {"who", "search for connected units, e.g. 3who returs 'Hi there' if found", who_cmd}, -// {"mode", "read or set params in eeprom", mode_cmd}, -// {"erase", "set eeprom contents to all 0xff", erase_cmd}, + {"ver", "report const_version_string", TSver_cmd}, // Report TS controller version + {"boards", "List STM3_ESC boards connected", boards_cmd}, {"kd", "kick the dog", kd_cmd}, - {"rpm", "rpm reading from 2 motors", uprpm_cmd}, {"nu", "do nothing", null_cmd}, }; -const int numof_menu_items = sizeof(command_list) / sizeof(kb_command); -void menucmd (struct parameters & a) -{ -// struct kb_command const * cl = command_list; - pc.printf("\r\n\nTS_2018 Locomotive Touch Screen Controller\r\nAt menucmd function - listing commands:-\r\n"); - for(int i = 0; i < numof_menu_items; i++) - pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan); - pc.printf("End of List of Commands\r\n"); -} - struct kb_command const loco_command_list[] = { {"ls", "Lists available commands", menucmd}, {"?", "Lists available commands, same as ls", menucmd}, - {"rpm", "rpm reading from 2 motors", uprpm_cmd}, + {"who", "Reads 'whon' response from STM3_ESC where 'n' is board num ascii from eeprom", who_cmd}, + {"ver", "report const_version_string", ver_req_cmd}, // Request software version of one specific ESC board {"mph", "bogie mph reading", upmph_cmd}, // 22/06/2018 - {"rdi", "rpm reading from 2 motors", uprdi_cmd}, {"nu", "do nothing", null_cmd}, } ; -struct parameters pccom, lococom; -/*struct parameters { - struct kb_command const * clist; - char cmd_line[120]; - char * cmd_line_ptr; - int32_t position_in_list, numof_dbls, target_unit, numof_menu_items; - double dbl[MAX_PARAMS]; - bool respond; -} ; -*/ -int getc (int which_port) -{ - if (which_port == 0) - return pc.getc (); - if (which_port == 1) - return com.getc (); - return -1; -} -int readable (int which_port) -{ - if (which_port == 0) - return pc.readable (); - if (which_port == 1) - return com.readable (); - return -1; - -} - -void setup_pccom () -{ - pccom.clist = command_list; - pccom.numof_menu_items = sizeof(command_list) / sizeof(kb_command); - pccom.com_no = 0; - pccom.cl_index = 0; - pccom.gp_i = 0; // general puropse integer, not used to 30/4/2018 -} - -void setup_lococom () -{ - lococom.clist = loco_command_list; - lococom.numof_menu_items = sizeof(loco_command_list) / sizeof(kb_command); - lococom.com_no = 1; - lococom.cl_index = 0; - lococom.gp_i = 0; // general puropse integer, toggles 0 / 1 to best guess source of rpm -} - -void clicore (struct parameters & a) +void menucmd (struct parameters & a) { - int ch; - char * pEnd; - while (readable(a.com_no)) { - ch = getc (a.com_no); - if(ch != '\r') // was this the 'Enter' key? - a.cmd_line[a.cl_index++] = ch; // added char to command being assembled - else { // key was CR, may or may not be command to lookup - a.target_unit = BROADCAST; // Broadcast - a.cmd_line_ptr = a.cmd_line; - a.cmd_line[a.cl_index] = 0; // null terminate command string - if(a.cl_index) { // If have got some chars to lookup - int i, wrdlen; - if (isdigit(a.cmd_line[0])) { // Look for command with prefix digit - a.cmd_line_ptr++; // point past identified digit prefix - a.target_unit = a.cmd_line[0]; // '0' to '9' - //pc.printf ("Got prefix %c\r\n", cmd_line[0]); - } - for (i = 0; i < a.numof_menu_items; i++) { // Look for input match in command list - wrdlen = strlen(a.clist[i].cmd_word); - if(strncmp(a.clist[i].cmd_word, a.cmd_line_ptr, wrdlen) == 0 && !isalpha(a.cmd_line_ptr[wrdlen])) { // If match found - for (int k = 0; k < MAX_PARAMS; k++) { - a.dbl[k] = 0.0; - } - a.position_in_list = i; - a.numof_dbls = 0; - pEnd = a.cmd_line_ptr + wrdlen; - while (*pEnd) { // Assemble all numerics as doubles - a.dbl[a.numof_dbls++] = strtod (pEnd, &pEnd); - while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) { - pEnd++; - } - } - //pc.printf ("\r\n"); // Not allowed as many may output this. - //for (int k = 0; k < param_block.numof_dbls; k++) - // pc.printf ("Read %.3f\r\n", param_block.dbl[k]); -// param_block.times[i] = clock(); -// if ((param_block.target_unit == BROADCAST) && (I_Am() == '0')) -// param_block.respond = true; - a.clist[i].f(a); // execute command - i = a.numof_menu_items + 1; // to exit for loop - } // end of match found - } // End of for numof_menu_items - if(i == a.numof_menu_items) - pc.printf("No Match Found for CMD [%s]\r\n", a.cmd_line); - } // End of If have got some chars to lookup - //pc.printf("\r\n>"); - a.cl_index = 0; - } // End of else key was CR, may or may not be command to lookup - } // End of while (pc.readable()) + pc.printf("\r\n\nTS_2018 Locomotive Touch Screen Controller\r\nAt menucmd function - listing commands:-\r\n"); + for(int i = 0; i < a.numof_menu_items; i++) + pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan); + pc.printf("End of List of Commands\r\n"); } -/* +/** New - March 2018 Using opto isolated serial port, paralleled up using same pair to multiple boards running this code. New feature - commands have optional prefix digit 0-9 indicating which unit message is addressed to. @@ -235,68 +169,68 @@ Only units recognising its address from prefix digit may respond. This avoids bus contention. But for BROADCAST commands, '0' may respond on behalf of the group */ -//void command_line_interpreter (void const *argument) -/*void command_line_interpreter () -{ - const int MAX_CMD_LEN = 120; - static char cmd_line[MAX_CMD_LEN + 4]; - static int cl_index = 0; +command_line_interpreter_core pcli (0, sizeof(command_list) / sizeof(kb_command), command_list); +command_line_interpreter_core ploco (1, sizeof(loco_command_list) / sizeof(kb_command), loco_command_list); + +void command_line_interpreter_core::sniff () { // look for recieved commands and act upon them int ch; - char * pEnd, * cmd_line_ptr; - static struct parameters param_block ; - while (pc.readable()) { - ch = pc.getc(); -// if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines -// pc.printf ("Error!! Stupidly long cmd line\r\n"); -// cl_index = 0; -// } - if(ch != '\r') // was this the 'Enter' key? - cmd_line[cl_index++] = ch; // added char to command being assembled + char * pEnd; + while (clreadable()) { + ch = clgetc (); + if(ch != '\r') {// was this the 'Enter' key? + if (ch != '\n') { // Ignore line feeds + cmd_line[cl_index++] = ch; // added char to command being assembled + if (cl_index >= MAX_CMD_LINE_LEN-2) { + cl_index = 0; // Line is garbage anyway, so might as well junk the lot ? + pc.printf ("cl_index=%d TOO LONG in clicore\r\n", cl_index); + Controller_Error.set (FAULT_COM_LINE_LEN, 1); + } + } // endof if(ch != '\n') ignore line feeds + } // endof if(ch != '\r') else { // key was CR, may or may not be command to lookup - param_block.target_unit = BROADCAST; // Broadcast + target_unit = BROADCAST; // Broadcast cmd_line_ptr = cmd_line; cmd_line[cl_index] = 0; // null terminate command string if(cl_index) { // If have got some chars to lookup int i, wrdlen; if (isdigit(cmd_line[0])) { // Look for command with prefix digit cmd_line_ptr++; // point past identified digit prefix - param_block.target_unit = cmd_line[0]; // '0' to '9' - //pc.printf ("Got prefix %c\r\n", cmd_line[0]); + target_unit = cmd_line[0]; // '0' to '9' + //pc.printf ("Got prefix %c\r\n", a.cmd_line[0]); } - for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list - wrdlen = strlen(command_list[i].cmd_word); - if(strncmp(command_list[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen])) { // If match found + for (i = 0; i < a.numof_menu_items; i++) { // Look for input match in command list + wrdlen = strlen(clist[i].cmd_word); + if(strncmp(clist[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen])) { // If match found for (int k = 0; k < MAX_PARAMS; k++) { - param_block.dbl[k] = 0.0; + a.dbl[k] = 0.0; } - param_block.position_in_list = i; - param_block.numof_dbls = 0; + //position_in_list = i; + a.numof_cl_values_read = 0; pEnd = cmd_line_ptr + wrdlen; while (*pEnd) { // Assemble all numerics as doubles - param_block.dbl[param_block.numof_dbls++] = strtod (pEnd, &pEnd); + a.dbl[a.numof_cl_values_read++] = strtod (pEnd, &pEnd); while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) { pEnd++; } } //pc.printf ("\r\n"); // Not allowed as many may output this. - //for (int k = 0; k < param_block.numof_dbls; k++) + //for (int k = 0; k < param_block.a.numof_cl_values_read; k++) // pc.printf ("Read %.3f\r\n", param_block.dbl[k]); // param_block.times[i] = clock(); // if ((param_block.target_unit == BROADCAST) && (I_Am() == '0')) // param_block.respond = true; - command_list[i].f(param_block); // execute command - i = numof_menu_items + 1; // to exit for loop + clist[i].f(a); // execute command + i = a.numof_menu_items + 1; // to exit for loop } // end of match found } // End of for numof_menu_items - if(i == numof_menu_items) + if(i == a.numof_menu_items) { pc.printf("No Match Found for CMD [%s]\r\n", cmd_line); + Controller_Error.set (FAULT_COM_NO_MATCH, 1); + } } // End of If have got some chars to lookup - //pc.printf("\r\n>"); cl_index = 0; } // End of else key was CR, may or may not be command to lookup } // End of while (pc.readable()) -// Thread::wait(20); // Using RTOS on this project -// } -} -*/ +} +