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@12:a25bdf135348, 2019-01-14 (annotated)
- Committer:
- JonFreeman
- Date:
- Mon Jan 14 16:39:41 2019 +0000
- Revision:
- 12:a25bdf135348
- Parent:
- 11:a573664b1a59
- Child:
- 14:6bcec5ac21ca
Tidied, better documented, more OOP, interim release
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 | //#define V_A_SIZE 54 // Size of voltmeter and ammeter |
JonFreeman | 12:a25bdf135348 | 41 | //#define SPEEDO_SIZE 112 |
JonFreeman | 12:a25bdf135348 | 42 | |
JonFreeman | 12:a25bdf135348 | 43 | #define V_A_SIZE 56 // Size of voltmeter and ammeter |
JonFreeman | 12:a25bdf135348 | 44 | #define SPEEDO_SIZE 114 |
JonFreeman | 4:67478861c670 | 45 | |
JonFreeman | 12:a25bdf135348 | 46 | #define SPEEDO_BODY_COLOUR LCD_COLOR_BLACK |
JonFreeman | 12:a25bdf135348 | 47 | #define SPEEDO_DIAL_COLOUR LCD_COLOR_WHITE |
JonFreeman | 12:a25bdf135348 | 48 | #define SPEEDO_TEXT_COLOUR LCD_COLOR_BLUE |
JonFreeman | 12:a25bdf135348 | 49 | |
JonFreeman | 12:a25bdf135348 | 50 | #define VMETER_BODY_COLOUR LCD_COLOR_BLACK |
JonFreeman | 12:a25bdf135348 | 51 | #define VMETER_DIAL_COLOUR LCD_COLOR_WHITE |
JonFreeman | 12:a25bdf135348 | 52 | #define VMETER_TEXT_COLOUR LCD_COLOR_BLUE |
JonFreeman | 12:a25bdf135348 | 53 | |
JonFreeman | 12:a25bdf135348 | 54 | #define AMETER_BODY_COLOUR LCD_COLOR_BLACK |
JonFreeman | 12:a25bdf135348 | 55 | #define AMETER_DIAL_COLOUR LCD_COLOR_WHITE |
JonFreeman | 12:a25bdf135348 | 56 | #define AMETER_TEXT_COLOUR LCD_COLOR_BLUE |
JonFreeman | 4:67478861c670 | 57 | const int |
JonFreeman | 4:67478861c670 | 58 | BUTTON_RAD = (SLIDERW / 2) - 4, // radius of circular 'knob' in slider control |
JonFreeman | 4:67478861c670 | 59 | MIN_POS = BUTTON_RAD + 5, // top of screen |
JonFreeman | 4:67478861c670 | 60 | MAX_POS = SLIDERH - (BUTTON_RAD + 1), // bottom of screen |
JonFreeman | 12:a25bdf135348 | 61 | CIRC_CTR = SLIDERX + BUTTON_RAD + 4; |
JonFreeman | 4:67478861c670 | 62 | |
JonFreeman | 12:a25bdf135348 | 63 | static const double PI = 4.0 * atan(1.0); |
JonFreeman | 12:a25bdf135348 | 64 | static const double TWO_PI = 8.0 * atan(1.0); |
JonFreeman | 4:67478861c670 | 65 | |
JonFreeman | 12:a25bdf135348 | 66 | enum {HI_HORN, LO_HORN}; |
JonFreeman | 4:67478861c670 | 67 | enum {NO_DPS, ONE_DP}; |
JonFreeman | 4:67478861c670 | 68 | // Assign unique number to every button we may use, and keep count of total number of them |
JonFreeman | 12:a25bdf135348 | 69 | enum {ENTER, SLIDER_BUTTON, SPEEDO_BUTTON, VMETER_BUTTON, AMETER_BUTTON,NUMOF_BUTTONS} ; // button names |
JonFreeman | 12:a25bdf135348 | 70 | enum {STATES, RUN, NEUTRAL_DRIFT, REGEN_BRAKE, RUN_DOWN, INTO_RUN, INTO_REGEN_BRAKE, INTO_NEUTRAL_DRIFT}; |
JonFreeman | 12:a25bdf135348 | 71 | enum {SLIDER_PRESS, SLIDER_RELEASE, SLIDER_AUTOREP}; |
JonFreeman | 4:67478861c670 | 72 | |
JonFreeman | 4:67478861c670 | 73 | struct point { int x; int y; } ; |
JonFreeman | 12:a25bdf135348 | 74 | struct keystr { int keynum; int x; int y; } ; |
JonFreeman | 12:a25bdf135348 | 75 | struct ky_bd { int count, slider_y; keystr key[MAX_TOUCHES + 1]; bool sli; } ; |
JonFreeman | 4:67478861c670 | 76 | |
JonFreeman | 12:a25bdf135348 | 77 | class screen_touch_handler |
JonFreeman | 12:a25bdf135348 | 78 | { |
JonFreeman | 12:a25bdf135348 | 79 | ky_bd kybd_a, kybd_b; // alternating present - previous keyboard structures |
JonFreeman | 12:a25bdf135348 | 80 | ky_bd * present_kybd, * previous_kybd; // pointers |
JonFreeman | 12:a25bdf135348 | 81 | bool in_list (struct ky_bd & , int ) ; |
JonFreeman | 12:a25bdf135348 | 82 | void motor_power () ; |
JonFreeman | 12:a25bdf135348 | 83 | void flush () ; |
JonFreeman | 12:a25bdf135348 | 84 | int viscous_drag (int, double, double) ; |
JonFreeman | 12:a25bdf135348 | 85 | int position; |
JonFreeman | 12:a25bdf135348 | 86 | int oldpos; |
JonFreeman | 12:a25bdf135348 | 87 | int next_state; |
JonFreeman | 12:a25bdf135348 | 88 | public: |
JonFreeman | 12:a25bdf135348 | 89 | int direction; |
JonFreeman | 12:a25bdf135348 | 90 | void DrawSlider () ; |
JonFreeman | 12:a25bdf135348 | 91 | void HandleFingerInput () ; |
JonFreeman | 12:a25bdf135348 | 92 | screen_touch_handler () ; // default constructor |
JonFreeman | 12:a25bdf135348 | 93 | } ; |
JonFreeman | 12:a25bdf135348 | 94 | |
JonFreeman | 12:a25bdf135348 | 95 | const int MAX_PARAMS = 30; |
JonFreeman | 12:a25bdf135348 | 96 | const int MAX_CMD_LINE_LEN = 180; |
JonFreeman | 12:a25bdf135348 | 97 | const int MAX_ESCS = 12; |
JonFreeman | 12:a25bdf135348 | 98 | |
JonFreeman | 5:21a8ac83142c | 99 | struct parameters { |
JonFreeman | 12:a25bdf135348 | 100 | int32_t numof_menu_items, numof_cl_values_read; |
JonFreeman | 5:21a8ac83142c | 101 | double dbl[MAX_PARAMS]; |
JonFreeman | 5:21a8ac83142c | 102 | } ; |
JonFreeman | 5:21a8ac83142c | 103 | |
JonFreeman | 12:a25bdf135348 | 104 | enum { |
JonFreeman | 12:a25bdf135348 | 105 | FAULT_0, |
JonFreeman | 12:a25bdf135348 | 106 | FAULT_BOARD_ID_IN_MSG, |
JonFreeman | 12:a25bdf135348 | 107 | FAULT_TS, |
JonFreeman | 12:a25bdf135348 | 108 | FAULT_PC, |
JonFreeman | 12:a25bdf135348 | 109 | FAULT_COM, |
JonFreeman | 12:a25bdf135348 | 110 | FAULT_COM_NO_MATCH, |
JonFreeman | 12:a25bdf135348 | 111 | FAULT_COM_LINE_LEN, |
JonFreeman | 12:a25bdf135348 | 112 | FAULT_QSPI, |
JonFreeman | 12:a25bdf135348 | 113 | FAULT_ODOMETER, |
JonFreeman | 12:a25bdf135348 | 114 | FAULT_MAX, |
JonFreeman | 12:a25bdf135348 | 115 | NUMOF_REPORTABLE_TS_ERRORS |
JonFreeman | 12:a25bdf135348 | 116 | } ; |
JonFreeman | 12:a25bdf135348 | 117 | |
JonFreeman | 12:a25bdf135348 | 118 | class error_handling_Jan_2019 |
JonFreeman | 12:a25bdf135348 | 119 | { |
JonFreeman | 12:a25bdf135348 | 120 | int32_t TS_fault[NUMOF_REPORTABLE_TS_ERRORS] ; // Some number of reportable error codes, accessible through set and read members |
JonFreeman | 11:a573664b1a59 | 121 | public: |
JonFreeman | 12:a25bdf135348 | 122 | error_handling_Jan_2019 () { // default constructor |
JonFreeman | 12:a25bdf135348 | 123 | for (int i = 0; i < (sizeof(TS_fault) / sizeof(int32_t)); i++) |
JonFreeman | 12:a25bdf135348 | 124 | TS_fault[i] = 0; |
JonFreeman | 12:a25bdf135348 | 125 | } |
JonFreeman | 12:a25bdf135348 | 126 | void set (uint32_t, int32_t) ; |
JonFreeman | 12:a25bdf135348 | 127 | void clr (uint32_t) ; |
JonFreeman | 12:a25bdf135348 | 128 | uint32_t read (uint32_t) ; |
JonFreeman | 12:a25bdf135348 | 129 | bool all_good () ; |
JonFreeman | 12:a25bdf135348 | 130 | void report_any () ; |
JonFreeman | 12:a25bdf135348 | 131 | } ; |
JonFreeman | 12:a25bdf135348 | 132 | |
JonFreeman | 12:a25bdf135348 | 133 | class command_line_interpreter_core { |
JonFreeman | 12:a25bdf135348 | 134 | parameters a ; // as opposed to clicore(¶meters) |
JonFreeman | 12:a25bdf135348 | 135 | struct kb_command const * clist; |
JonFreeman | 12:a25bdf135348 | 136 | int32_t portio, cl_index, target_unit; |
JonFreeman | 12:a25bdf135348 | 137 | char cmd_line[MAX_CMD_LINE_LEN]; |
JonFreeman | 12:a25bdf135348 | 138 | char * cmd_line_ptr; |
JonFreeman | 12:a25bdf135348 | 139 | int clreadable (); |
JonFreeman | 12:a25bdf135348 | 140 | int clgetc (); |
JonFreeman | 12:a25bdf135348 | 141 | void clputc (int); |
JonFreeman | 12:a25bdf135348 | 142 | public: |
JonFreeman | 12:a25bdf135348 | 143 | command_line_interpreter_core () {}; // default constructor |
JonFreeman | 12:a25bdf135348 | 144 | command_line_interpreter_core (int, int, struct kb_command const * ) ; //{ // constructor including io port id value |
JonFreeman | 12:a25bdf135348 | 145 | void sniff () ; // The function to call often to sniff out commands from command line and act upon them |
JonFreeman | 12:a25bdf135348 | 146 | } ; |
JonFreeman | 12:a25bdf135348 | 147 | |
JonFreeman | 12:a25bdf135348 | 148 | class STM3_ESC_Interface |
JonFreeman | 12:a25bdf135348 | 149 | { |
JonFreeman | 12:a25bdf135348 | 150 | 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 | 151 | board_count, |
JonFreeman | 12:a25bdf135348 | 152 | reqno; |
JonFreeman | 12:a25bdf135348 | 153 | public: |
JonFreeman | 12:a25bdf135348 | 154 | double last_V, last_I, mph, esc_speeds[MAX_ESCS]; |
JonFreeman | 12:a25bdf135348 | 155 | STM3_ESC_Interface () { // Constructor |
JonFreeman | 12:a25bdf135348 | 156 | board_count = 0; |
JonFreeman | 12:a25bdf135348 | 157 | reqno = 0; |
JonFreeman | 12:a25bdf135348 | 158 | last_V = last_I = mph = 0.0; |
JonFreeman | 12:a25bdf135348 | 159 | for (int i = 0; i < MAX_ESCS; i++) { |
JonFreeman | 12:a25bdf135348 | 160 | board_IDs[i] = 0; |
JonFreeman | 12:a25bdf135348 | 161 | esc_speeds[i] = 0.0; |
JonFreeman | 12:a25bdf135348 | 162 | } |
JonFreeman | 12:a25bdf135348 | 163 | } |
JonFreeman | 12:a25bdf135348 | 164 | bool request_mph () ; // Issue "'n'mph\r" to one particular STM3_ESC board to request RPM 22/06/2018 |
JonFreeman | 12:a25bdf135348 | 165 | void mph_update (double) ; // touched 08/01/2019 |
JonFreeman | 12:a25bdf135348 | 166 | void set_board_ID (int) ; // called in response to 'whon' coming back from a STM3_ESC |
JonFreeman | 12:a25bdf135348 | 167 | void search_for_escs () ; // one-off call during startup to identify all connected STM3_ESCs |
JonFreeman | 12:a25bdf135348 | 168 | void get_boards_list (int *) ; // copies board list |
JonFreeman | 12:a25bdf135348 | 169 | void set_V_limit (double) ; // Set max motor voltage |
JonFreeman | 12:a25bdf135348 | 170 | void set_I_limit (double) ; // Set max motor current |
JonFreeman | 12:a25bdf135348 | 171 | void message (char *) ; // Broadcast message to all STM3_ESCs |
JonFreeman | 12:a25bdf135348 | 172 | void message (int, char *) ; // Send message to one individual STM3_ESC |
JonFreeman | 11:a573664b1a59 | 173 | } ; |
JonFreeman | 5:21a8ac83142c | 174 | |
JonFreeman | 11:a573664b1a59 | 175 | |
JonFreeman | 12:a25bdf135348 | 176 |