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
cli_TS_nortos.cpp
- Committer:
- JonFreeman
- Date:
- 2018-06-23
- Revision:
- 11:a573664b1a59
- Parent:
- cli_nortos.cpp@ 7:3b1f44cd4735
- Child:
- 12:a25bdf135348
File content as of revision 11:a573664b1a59:
//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 () ; genio::genio (int dtype, int dlen) { d_type = dtype; d_len = dlen; for (int i = 0; i < MAX_PARAMS; i++) { ui[i] = 0; dbl[i] = 0.0; } count = 0; available = false; } void genio::store (struct parameters & a) { // count++; available = true; for (int i = 0; i < d_len; i++) { ui[i] = (int32_t)a.dbl[i]; dbl[i] = a.dbl[i]; } } bool genio::read (uint32_t ** addr) { if (!available) return false; available = false; *addr = ui; return true; } 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]); } /*void who_cmd (struct parameters & a) { int i = I_Am (); if (I_Am() == a.target_unit) pc.printf ("Hi there, I am %c\r\n", a.target_unit); }*/ struct kb_command { const char * cmd_word; // points to text e.g. "menu" const char * explan; void (*f)(struct parameters &); // points to function } ; 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}, {"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}, {"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) { 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()) } /* 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. Commands without prefix digit - broadcast to all units, none to respond. 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; 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 else { // key was CR, may or may not be command to lookup param_block.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]); } 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 (int k = 0; k < MAX_PARAMS; k++) { param_block.dbl[k] = 0.0; } param_block.position_in_list = i; param_block.numof_dbls = 0; pEnd = cmd_line_ptr + wrdlen; while (*pEnd) { // Assemble all numerics as doubles param_block.dbl[param_block.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; command_list[i].f(param_block); // execute command i = numof_menu_items + 1; // to exit for loop } // end of match found } // End of for numof_menu_items if(i == numof_menu_items) pc.printf("No Match Found for CMD [%s]\r\n", cmd_line); } // 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 // } } */