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
Electric_Loco.h@14:6bcec5ac21ca, 2019-03-04 (annotated)
- Committer:
- JonFreeman
- Date:
- Mon Mar 04 17:47:27 2019 +0000
- Revision:
- 14:6bcec5ac21ca
- Parent:
- 12:a25bdf135348
'Brute' Locomotive Touch Screen Controller - Driver's Controls; Always a 'Work In Progress', snapshot March 2019
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| JonFreeman | 4:67478861c670 | 1 | #include "mbed.h" |
| JonFreeman | 12:a25bdf135348 | 2 | #include "movingcoilmeter.h" |
| JonFreeman | 12:a25bdf135348 | 3 | #include <cctype> |
| JonFreeman | 12:a25bdf135348 | 4 | /* Updated January 2019 |
| JonFreeman | 4:67478861c670 | 5 | Jon Freeman |
| JonFreeman | 4:67478861c670 | 6 | |
| JonFreeman | 4:67478861c670 | 7 | 5" and 7.25" gauge Electric Locomotive Controller - ST DISCO-F746NG |
| JonFreeman | 4:67478861c670 | 8 | Uses built in display and touch screen. |
| JonFreeman | 4:67478861c670 | 9 | |
| JonFreeman | 4:67478861c670 | 10 | Display shows 'analogue' moving coil meter movements for : |
| JonFreeman | 4:67478861c670 | 11 | Locomotive speed Miles per Hour |
| JonFreeman | 12:a25bdf135348 | 12 | System voltage (range 10v - 63v or thereabouts) |
| JonFreeman | 12:a25bdf135348 | 13 | Power Watts delivered to drive motors or dumped. |
| JonFreeman | 4:67478861c670 | 14 | |
| JonFreeman | 12:a25bdf135348 | 15 | Touch screen has three 'buttons', and are where the meter movements show. |
| JonFreeman | 12:a25bdf135348 | 16 | Two smaller meter buttons for two horns, larger speedo button currently unsused |
| JonFreeman | 4:67478861c670 | 17 | |
| JonFreeman | 4:67478861c670 | 18 | Display has 'slider' touch control. This drives the loco. |
| JonFreeman | 4:67478861c670 | 19 | Control in central position when not driving or drfting. |
| JonFreeman | 4:67478861c670 | 20 | Moving towards bottom of screen applies regenerative braking - move further down applies harder braking. |
| JonFreeman | 4:67478861c670 | 21 | Moving towards top of screen powers drive motors, move further up applies more torque (current controller implemented) |
| JonFreeman | 4:67478861c670 | 22 | Take finger off and control drifts down to central 'neutral' position. |
| JonFreeman | 4:67478861c670 | 23 | */ |
| JonFreeman | 4:67478861c670 | 24 | |
| JonFreeman | 4:67478861c670 | 25 | |
| JonFreeman | 4:67478861c670 | 26 | #define MAX_TOUCHES 6 // Touch screen can decode up to this many simultaneous finger press positions |
| JonFreeman | 4:67478861c670 | 27 | #define NEUTRAL_VAL 150 // Number of pixels |
| JonFreeman | 4:67478861c670 | 28 | |
| JonFreeman | 4:67478861c670 | 29 | #define SLIDERX 418 // slider graphic x position |
| JonFreeman | 4:67478861c670 | 30 | #define SLIDERY 2 // slider graphic y position |
| JonFreeman | 4:67478861c670 | 31 | #define SLIDERW 50 // pixel width of slider |
| JonFreeman | 4:67478861c670 | 32 | #define SLIDERH 268 // pixel height of slider |
| JonFreeman | 4:67478861c670 | 33 | |
| JonFreeman | 12:a25bdf135348 | 34 | #define VOLTMETER_X 68 // Voltmeter screen position |
| JonFreeman | 12:a25bdf135348 | 35 | #define VOLTMETER_Y 68 |
| JonFreeman | 12:a25bdf135348 | 36 | #define AMMETER_X 68 // Ammeter screen position - Now replaced by Power meter |
| JonFreeman | 12:a25bdf135348 | 37 | #define AMMETER_Y 202 |
| JonFreeman | 12:a25bdf135348 | 38 | #define SPEEDO_X 274 // Speedometer screen position |
| JonFreeman | 12:a25bdf135348 | 39 | #define SPEEDO_Y 135 |
| JonFreeman | 12:a25bdf135348 | 40 | |
| JonFreeman | 12:a25bdf135348 | 41 | #define V_A_SIZE 56 // Size of voltmeter and ammeter |
| JonFreeman | 12:a25bdf135348 | 42 | #define SPEEDO_SIZE 114 |
| JonFreeman | 4:67478861c670 | 43 | |
| JonFreeman | 12:a25bdf135348 | 44 | #define SPEEDO_BODY_COLOUR LCD_COLOR_BLACK |
| JonFreeman | 12:a25bdf135348 | 45 | #define SPEEDO_DIAL_COLOUR LCD_COLOR_WHITE |
| JonFreeman | 12:a25bdf135348 | 46 | #define SPEEDO_TEXT_COLOUR LCD_COLOR_BLUE |
| JonFreeman | 12:a25bdf135348 | 47 | |
| JonFreeman | 12:a25bdf135348 | 48 | #define VMETER_BODY_COLOUR LCD_COLOR_BLACK |
| JonFreeman | 12:a25bdf135348 | 49 | #define VMETER_DIAL_COLOUR LCD_COLOR_WHITE |
| JonFreeman | 12:a25bdf135348 | 50 | #define VMETER_TEXT_COLOUR LCD_COLOR_BLUE |
| JonFreeman | 12:a25bdf135348 | 51 | |
| JonFreeman | 12:a25bdf135348 | 52 | #define AMETER_BODY_COLOUR LCD_COLOR_BLACK |
| JonFreeman | 12:a25bdf135348 | 53 | #define AMETER_DIAL_COLOUR LCD_COLOR_WHITE |
| JonFreeman | 12:a25bdf135348 | 54 | #define AMETER_TEXT_COLOUR LCD_COLOR_BLUE |
| JonFreeman | 4:67478861c670 | 55 | const int |
| JonFreeman | 4:67478861c670 | 56 | BUTTON_RAD = (SLIDERW / 2) - 4, // radius of circular 'knob' in slider control |
| JonFreeman | 4:67478861c670 | 57 | MIN_POS = BUTTON_RAD + 5, // top of screen |
| JonFreeman | 4:67478861c670 | 58 | MAX_POS = SLIDERH - (BUTTON_RAD + 1), // bottom of screen |
| JonFreeman | 12:a25bdf135348 | 59 | CIRC_CTR = SLIDERX + BUTTON_RAD + 4; |
| JonFreeman | 4:67478861c670 | 60 | |
| JonFreeman | 12:a25bdf135348 | 61 | static const double PI = 4.0 * atan(1.0); |
| JonFreeman | 12:a25bdf135348 | 62 | static const double TWO_PI = 8.0 * atan(1.0); |
| JonFreeman | 4:67478861c670 | 63 | |
| JonFreeman | 12:a25bdf135348 | 64 | enum {HI_HORN, LO_HORN}; |
| JonFreeman | 4:67478861c670 | 65 | enum {NO_DPS, ONE_DP}; |
| JonFreeman | 4:67478861c670 | 66 | // Assign unique number to every button we may use, and keep count of total number of them |
| JonFreeman | 12:a25bdf135348 | 67 | enum {ENTER, SLIDER_BUTTON, SPEEDO_BUTTON, VMETER_BUTTON, AMETER_BUTTON,NUMOF_BUTTONS} ; // button names |
| JonFreeman | 12:a25bdf135348 | 68 | enum {STATES, RUN, NEUTRAL_DRIFT, REGEN_BRAKE, RUN_DOWN, INTO_RUN, INTO_REGEN_BRAKE, INTO_NEUTRAL_DRIFT}; |
| JonFreeman | 12:a25bdf135348 | 69 | enum {SLIDER_PRESS, SLIDER_RELEASE, SLIDER_AUTOREP}; |
| JonFreeman | 4:67478861c670 | 70 | |
| JonFreeman | 4:67478861c670 | 71 | struct point { int x; int y; } ; |
| JonFreeman | 12:a25bdf135348 | 72 | struct keystr { int keynum; int x; int y; } ; |
| JonFreeman | 12:a25bdf135348 | 73 | struct ky_bd { int count, slider_y; keystr key[MAX_TOUCHES + 1]; bool sli; } ; |
| JonFreeman | 4:67478861c670 | 74 | |
| JonFreeman | 12:a25bdf135348 | 75 | class screen_touch_handler |
| JonFreeman | 12:a25bdf135348 | 76 | { |
| JonFreeman | 12:a25bdf135348 | 77 | ky_bd kybd_a, kybd_b; // alternating present - previous keyboard structures |
| JonFreeman | 12:a25bdf135348 | 78 | ky_bd * present_kybd, * previous_kybd; // pointers |
| JonFreeman | 12:a25bdf135348 | 79 | bool in_list (struct ky_bd & , int ) ; |
| JonFreeman | 12:a25bdf135348 | 80 | void motor_power () ; |
| JonFreeman | 12:a25bdf135348 | 81 | void flush () ; |
| JonFreeman | 12:a25bdf135348 | 82 | int viscous_drag (int, double, double) ; |
| JonFreeman | 12:a25bdf135348 | 83 | int position; |
| JonFreeman | 12:a25bdf135348 | 84 | int oldpos; |
| JonFreeman | 12:a25bdf135348 | 85 | int next_state; |
| JonFreeman | 12:a25bdf135348 | 86 | public: |
| JonFreeman | 12:a25bdf135348 | 87 | int direction; |
| JonFreeman | 12:a25bdf135348 | 88 | void DrawSlider () ; |
| JonFreeman | 12:a25bdf135348 | 89 | void HandleFingerInput () ; |
| JonFreeman | 12:a25bdf135348 | 90 | screen_touch_handler () ; // default constructor |
| JonFreeman | 12:a25bdf135348 | 91 | } ; |
| JonFreeman | 12:a25bdf135348 | 92 | |
| JonFreeman | 12:a25bdf135348 | 93 | const int MAX_PARAMS = 30; |
| JonFreeman | 12:a25bdf135348 | 94 | const int MAX_CMD_LINE_LEN = 180; |
| JonFreeman | 12:a25bdf135348 | 95 | const int MAX_ESCS = 12; |
| JonFreeman | 12:a25bdf135348 | 96 | |
| JonFreeman | 5:21a8ac83142c | 97 | struct parameters { |
| JonFreeman | 12:a25bdf135348 | 98 | int32_t numof_menu_items, numof_cl_values_read; |
| JonFreeman | 5:21a8ac83142c | 99 | double dbl[MAX_PARAMS]; |
| JonFreeman | 5:21a8ac83142c | 100 | } ; |
| JonFreeman | 5:21a8ac83142c | 101 | |
| JonFreeman | 12:a25bdf135348 | 102 | enum { |
| JonFreeman | 12:a25bdf135348 | 103 | FAULT_0, |
| JonFreeman | 12:a25bdf135348 | 104 | FAULT_BOARD_ID_IN_MSG, |
| JonFreeman | 12:a25bdf135348 | 105 | FAULT_TS, |
| JonFreeman | 12:a25bdf135348 | 106 | FAULT_PC, |
| JonFreeman | 12:a25bdf135348 | 107 | FAULT_COM, |
| JonFreeman | 12:a25bdf135348 | 108 | FAULT_COM_NO_MATCH, |
| JonFreeman | 12:a25bdf135348 | 109 | FAULT_COM_LINE_LEN, |
| JonFreeman | 12:a25bdf135348 | 110 | FAULT_QSPI, |
| JonFreeman | 12:a25bdf135348 | 111 | FAULT_ODOMETER, |
| JonFreeman | 12:a25bdf135348 | 112 | FAULT_MAX, |
| JonFreeman | 12:a25bdf135348 | 113 | NUMOF_REPORTABLE_TS_ERRORS |
| JonFreeman | 12:a25bdf135348 | 114 | } ; |
| JonFreeman | 12:a25bdf135348 | 115 | |
| JonFreeman | 12:a25bdf135348 | 116 | class error_handling_Jan_2019 |
| JonFreeman | 12:a25bdf135348 | 117 | { |
| JonFreeman | 12:a25bdf135348 | 118 | int32_t TS_fault[NUMOF_REPORTABLE_TS_ERRORS] ; // Some number of reportable error codes, accessible through set and read members |
| JonFreeman | 11:a573664b1a59 | 119 | public: |
| JonFreeman | 12:a25bdf135348 | 120 | error_handling_Jan_2019 () { // default constructor |
| JonFreeman | 12:a25bdf135348 | 121 | for (int i = 0; i < (sizeof(TS_fault) / sizeof(int32_t)); i++) |
| JonFreeman | 12:a25bdf135348 | 122 | TS_fault[i] = 0; |
| JonFreeman | 12:a25bdf135348 | 123 | } |
| JonFreeman | 12:a25bdf135348 | 124 | void set (uint32_t, int32_t) ; |
| JonFreeman | 12:a25bdf135348 | 125 | void clr (uint32_t) ; |
| JonFreeman | 12:a25bdf135348 | 126 | uint32_t read (uint32_t) ; |
| JonFreeman | 12:a25bdf135348 | 127 | bool all_good () ; |
| JonFreeman | 14:6bcec5ac21ca | 128 | void report_any (bool) ; |
| JonFreeman | 12:a25bdf135348 | 129 | } ; |
| JonFreeman | 12:a25bdf135348 | 130 | |
| JonFreeman | 12:a25bdf135348 | 131 | class command_line_interpreter_core { |
| JonFreeman | 12:a25bdf135348 | 132 | parameters a ; // as opposed to clicore(¶meters) |
| JonFreeman | 12:a25bdf135348 | 133 | struct kb_command const * clist; |
| JonFreeman | 12:a25bdf135348 | 134 | int32_t portio, cl_index, target_unit; |
| JonFreeman | 12:a25bdf135348 | 135 | char cmd_line[MAX_CMD_LINE_LEN]; |
| JonFreeman | 12:a25bdf135348 | 136 | char * cmd_line_ptr; |
| JonFreeman | 12:a25bdf135348 | 137 | int clreadable (); |
| JonFreeman | 12:a25bdf135348 | 138 | int clgetc (); |
| JonFreeman | 12:a25bdf135348 | 139 | void clputc (int); |
| JonFreeman | 12:a25bdf135348 | 140 | public: |
| JonFreeman | 12:a25bdf135348 | 141 | command_line_interpreter_core () {}; // default constructor |
| JonFreeman | 12:a25bdf135348 | 142 | command_line_interpreter_core (int, int, struct kb_command const * ) ; //{ // constructor including io port id value |
| JonFreeman | 12:a25bdf135348 | 143 | void sniff () ; // The function to call often to sniff out commands from command line and act upon them |
| JonFreeman | 12:a25bdf135348 | 144 | } ; |
| JonFreeman | 12:a25bdf135348 | 145 | |
| JonFreeman | 12:a25bdf135348 | 146 | class STM3_ESC_Interface |
| JonFreeman | 12:a25bdf135348 | 147 | { |
| JonFreeman | 12:a25bdf135348 | 148 | int board_IDs [MAX_ESCS], // allow up to 4 boards in practical system, size for 10+ as 10 discrete ID nums exist |
| JonFreeman | 12:a25bdf135348 | 149 | board_count, |
| JonFreeman | 12:a25bdf135348 | 150 | reqno; |
| JonFreeman | 12:a25bdf135348 | 151 | public: |
| JonFreeman | 12:a25bdf135348 | 152 | double last_V, last_I, mph, esc_speeds[MAX_ESCS]; |
| JonFreeman | 12:a25bdf135348 | 153 | STM3_ESC_Interface () { // Constructor |
| JonFreeman | 12:a25bdf135348 | 154 | board_count = 0; |
| JonFreeman | 12:a25bdf135348 | 155 | reqno = 0; |
| JonFreeman | 12:a25bdf135348 | 156 | last_V = last_I = mph = 0.0; |
| JonFreeman | 12:a25bdf135348 | 157 | for (int i = 0; i < MAX_ESCS; i++) { |
| JonFreeman | 12:a25bdf135348 | 158 | board_IDs[i] = 0; |
| JonFreeman | 12:a25bdf135348 | 159 | esc_speeds[i] = 0.0; |
| JonFreeman | 12:a25bdf135348 | 160 | } |
| JonFreeman | 12:a25bdf135348 | 161 | } |
| JonFreeman | 14:6bcec5ac21ca | 162 | bool request_mph () ; // Issue "'n'mph\r" to one particular STM3_ESC board to request MPH 22/06/2018 |
| JonFreeman | 12:a25bdf135348 | 163 | void mph_update (double) ; // touched 08/01/2019 |
| JonFreeman | 12:a25bdf135348 | 164 | void set_board_ID (int) ; // called in response to 'whon' coming back from a STM3_ESC |
| JonFreeman | 12:a25bdf135348 | 165 | void search_for_escs () ; // one-off call during startup to identify all connected STM3_ESCs |
| JonFreeman | 12:a25bdf135348 | 166 | void get_boards_list (int *) ; // copies board list |
| JonFreeman | 12:a25bdf135348 | 167 | void set_V_limit (double) ; // Set max motor voltage |
| JonFreeman | 12:a25bdf135348 | 168 | void set_I_limit (double) ; // Set max motor current |
| JonFreeman | 12:a25bdf135348 | 169 | void message (char *) ; // Broadcast message to all STM3_ESCs |
| JonFreeman | 12:a25bdf135348 | 170 | void message (int, char *) ; // Send message to one individual STM3_ESC |
| JonFreeman | 11:a573664b1a59 | 171 | } ; |
| JonFreeman | 5:21a8ac83142c | 172 | |
| JonFreeman | 11:a573664b1a59 | 173 | |
| JonFreeman | 12:a25bdf135348 | 174 |