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
Revision 14:6bcec5ac21ca, committed 2019-03-04
- Comitter:
- JonFreeman
- Date:
- Mon Mar 04 17:47:27 2019 +0000
- Parent:
- 13:390430631255
- Commit message:
- 'Brute' Locomotive Touch Screen Controller - Driver's Controls; Always a 'Work In Progress', snapshot March 2019
Changed in this revision
diff -r 390430631255 -r 6bcec5ac21ca Electric_Loco.h --- a/Electric_Loco.h Mon Jan 14 16:51:16 2019 +0000 +++ b/Electric_Loco.h Mon Mar 04 17:47:27 2019 +0000 @@ -37,8 +37,6 @@ #define AMMETER_Y 202 #define SPEEDO_X 274 // Speedometer screen position #define SPEEDO_Y 135 -//#define V_A_SIZE 54 // Size of voltmeter and ammeter -//#define SPEEDO_SIZE 112 #define V_A_SIZE 56 // Size of voltmeter and ammeter #define SPEEDO_SIZE 114 @@ -127,7 +125,7 @@ void clr (uint32_t) ; uint32_t read (uint32_t) ; bool all_good () ; - void report_any () ; + void report_any (bool) ; } ; class command_line_interpreter_core { @@ -161,7 +159,7 @@ esc_speeds[i] = 0.0; } } - bool request_mph () ; // Issue "'n'mph\r" to one particular STM3_ESC board to request RPM 22/06/2018 + bool request_mph () ; // Issue "'n'mph\r" to one particular STM3_ESC board to request MPH 22/06/2018 void mph_update (double) ; // touched 08/01/2019 void set_board_ID (int) ; // called in response to 'whon' coming back from a STM3_ESC void search_for_escs () ; // one-off call during startup to identify all connected STM3_ESCs
diff -r 390430631255 -r 6bcec5ac21ca cli_TS_nortos.cpp --- a/cli_TS_nortos.cpp Mon Jan 14 16:51:16 2019 +0000 +++ b/cli_TS_nortos.cpp Mon Mar 04 17:47:27 2019 +0000 @@ -102,10 +102,10 @@ count++; pc.printf ("Board Count = %d\r\n", count); if (count) { - pc.printf ("Boards found ^"); + pc.printf ("Boards found ["); for (int i = 0; i < count; i++) pc.printf ("%c ", boards[i]); - pc.printf ("\r\n"); + pc.printf ("]\r\n"); } else pc.printf ("No STM3_ESC boards found\r\n"); @@ -127,28 +127,52 @@ pc.printf ("ver_req_cmd not yet implemented\r\n"); } +void queryv (struct parameters & a) { // Handle response from ESC resulting from prior TSC "n?v\r" sent request - ESC'n' system voltage + pc.printf ("Responding ESC id=%d, volts=%.2f\r\n", (int)a.dbl[0], a.dbl[1]); +} +void queryi (struct parameters & a) { // Handle response from ESC resulting from prior TSC "n?i\r" sent request - ESC'n' motor pair currents + pc.printf ("Responding ESC id=%d, I MotorA=%.2f, I MotorB=%.2f\r\n", (int)a.dbl[0], a.dbl[1], a.dbl[2]); +} + 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[] = { +* +* struct kb_command const xx_list[] +* +* Each line in list has 3 elements +* e.g. "ver\r" is message we may expect to be recieved here as a command or command response sent from somewhere else +* "waffle" is purely to inform you something about this message +* cmd is pointer to function, the what to do in response to the incoming message +* function type is void (*foo) (struct parameters &) +* This gives function access to parameters recieved with the message, e.g. "?i 7.45 8.23\r" +* User is at liberty to send using e.g. 'STM3_ESC_Interface::message' anything to any remote connected entity at any time. +* It is up to the user to ensure whatever is out there can make sense of it ! +* The list of commands and responses the 'Brute_TS_Controller' is expected to recognise and act upon +* One such list for commands from pc terminal, another for comms with some number of STM3_Esc boards +*/ struct kb_command const command_list[] = { {"ls", "Lists available commands", menucmd}, - {"?", "Lists available commands, same as ls", menucmd}, - {"ver", "report const_version_string", TSver_cmd}, // Report TS controller version + {"?", "Lists available commands, same as ls", menucmd}, // Send this list, a menu + {"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}, + {"kd", "kick the dog", kd_cmd}, // Broadcast Command to STM3_ESCs, resets and enables WatchDog timeout + {"?v", "Ask ESC for system voltage reading", queryv}, // Makes no sense for pc to ask this of TS controller, just to test function + {"?i", "Ask ESC for pair of motor current readings", queryi}, // Makes no sense for pc to ask this of TS controller, just to test function {"nu", "do nothing", null_cmd}, -}; +} ; struct kb_command const loco_command_list[] = { - {"ls", "Lists available commands", menucmd}, - {"?", "Lists available commands, same as ls", menucmd}, {"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 - {"nu", "do nothing", null_cmd}, + {"?v", "Ask ESC for system voltage reading", queryv}, + {"?i", "Ask ESC for pair of motor current readings", queryi}, } ;
diff -r 390430631255 -r 6bcec5ac21ca error_handler.cpp --- a/error_handler.cpp Mon Jan 14 16:51:16 2019 +0000 +++ b/error_handler.cpp Mon Mar 04 17:47:27 2019 +0000 @@ -69,10 +69,21 @@ } extern Serial pc; -void error_handling_Jan_2019::report_any () { +/*void error_handling_Jan_2019::report_any () { for (int i = 0; i < NUMOF_REPORTABLE_TS_ERRORS; i++) { if (TS_fault[i]) pc.printf ("Error report, number %d, value %d, %s\r\n", i, TS_fault[i], FaultList[i]); } } +*/ +void error_handling_Jan_2019::report_any (bool retain) { + for (int i = 0; i < NUMOF_REPORTABLE_TS_ERRORS; i++) { + if (TS_fault[i]) { + pc.printf ("Error report, number %d, value %d, %s\r\n", i, TS_fault[i], FaultList[i]); + if (!retain) + TS_fault[i] = 0; + } + } +} +
diff -r 390430631255 -r 6bcec5ac21ca main.cpp --- a/main.cpp Mon Jan 14 16:51:16 2019 +0000 +++ b/main.cpp Mon Mar 04 17:47:27 2019 +0000 @@ -126,23 +126,30 @@ int bigImafptr; double amps_longave, // internal use only amps_latest, // update() called @ 32Hz. Value stored here is average over most recent 3125us - amps_filtered; // Average of the BIGMAFSIZ most recent samples stored in latest + amps_filtered, // Average of the BIGMAFSIZ most recent samples stored in latest + amps_filtered2; // Average of the BIGMAFSIZ most recent samples stored in latest public: ammeter_reading () { // constructor bigImafptr = 0; - amps_longave = amps_latest = amps_filtered = 0.0; + amps_longave = amps_latest = amps_filtered = amps_filtered2 = 0.0; for (int i = 0; i < BIGMAFSIZ; i++) bigImaf[i] = 0.0; } void update () ; // Read ammeter core, store most recent 32ms or so worth in amps_latest, 250ms average in amps_filtered double latest () ; double filtered() ; + double filtered2() ; } Ammeter ; double ammeter_reading::latest () { return amps_latest; } +double ammeter_reading::filtered2 () { +// could use filter without buffer, weights result more towards more frecent samples + return amps_filtered2; +} + double ammeter_reading::filtered () { return amps_filtered; } @@ -156,6 +163,10 @@ if (bigImafptr >= BIGMAFSIZ) bigImafptr = 0; amps_filtered = amps_longave / BIGMAFSIZ; +const double sampweight = (double)(1) / (double)BIGMAFSIZ; +const double shrinkby = 1.0 - sampweight; + amps_filtered2 *= shrinkby; + amps_filtered2 += amps_latest * sampweight; } @@ -247,9 +258,9 @@ slider.direction = f_r_switch ? REV : FWD; // Only place in the code where direction gets set. Centre-Off power switch REV-OFF-FWD. My_STM3_ESC_boards.set_I_limit (0.0); - My_STM3_ESC_boards.set_V_limit (0.0); - My_STM3_ESC_boards.message ("rb\r"); - throttle (0.0); // Set revs to idle. Start engine and warm up before powering up control + My_STM3_ESC_boards.set_V_limit (0.0); // zero power to motors + My_STM3_ESC_boards.message ("rb\r"); // regen brake mode + throttle (0.0); // Set revs to idle. Start engine and warm up before powering up control pc.printf ("\r\n\n\nJon's Loco_TS_2018 Loco Controller ver %s starting, direction %s\r\n", const_version_string, slider.direction ? "Forward":"Reverse"); uint8_t lcd_status = touch_screen.Init(lcd.GetXSize(), lcd.GetYSize()); @@ -311,25 +322,7 @@ Speedo.set_value (My_STM3_ESC_boards.mph); led_grn = !led_grn; -/* -Handbrake more sensibly implemented on STM3_ESC boards ? - - if (slider.state == PARK) { - if (My_STM3_ESC_boards.mph > LOCO_HANDBRAKE_ESCAPE_SPEED / 4.0) { - slider.handbrake_effort *= 1.1; - if (slider.handbrake_effort > 0.55) slider.handbrake_effort = 0.55; - set_run_mode (PARK); - pc.printf ("Handbrake slipping, effort %.2f\r\n", slider.handbrake_effort); - } - if (My_STM3_ESC_boards.mph < 0.02) { - slider.handbrake_effort *= 0.9; - if (slider.handbrake_effort < 0.05) slider.handbrake_effort = 0.05; - set_run_mode (PARK); - pc.printf ("Handbrake not slipping, effort %.2f\r\n", slider.handbrake_effort); - } - } -*/ - My_STM3_ESC_boards.request_mph (); // issues "'n'rpm\r", takes care of cycling through available boards in sequence + My_STM3_ESC_boards.request_mph (); // issues "'n'mph\r", takes care of cycling through available boards in sequence // switch (qtr_sec) { // Can do sequential stuff quarter second apart here // } // End of switch qtr_sec qtr_sec++; @@ -341,12 +334,13 @@ seconds = 0; minutes++; // do once per minute stuff here - Controller_Error.report_any (); + Controller_Error.report_any (false); // Reset error having reported it once } // fall back into once per second if (seconds & 1) Speedo.LED (0, LCD_COLOR_DARKGRAY); else Speedo.LED (0, LCD_COLOR_RED); +// pc.printf ("Filter test %.3f, %.3f\r\n", Ammeter.filtered(), Ammeter.filtered2()); My_STM3_ESC_boards.message ("kd\r"); // Kick the WatchDog timers in the Twin BLDC drive boards recent_distance += (My_STM3_ESC_boards.mph * (111.76 * 4.0)); // Convert mph to distance mm travelled in one second uint32_t new_metres = ((uint32_t)recent_distance) / 1000;