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

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?

UserRevisionLine numberNew contents of line
JonFreeman 4:67478861c670 1 /*
JonFreeman 12:a25bdf135348 2 November 2018 - Jon Freeman
JonFreeman 12:a25bdf135348 3 Cloned from Loco_TS_2018_06 on 23rd November 2018
JonFreeman 4:67478861c670 4
JonFreeman 12:a25bdf135348 5 Touch Screen controller communicates with 1, 2, ... n Brushless STM3 Controller boards via opto-isolated serial port.
JonFreeman 4:67478861c670 6
JonFreeman 4:67478861c670 7 9 pid D connector retained but wiring NOT compatible with 2017.
JonFreeman 4:67478861c670 8 This time pins are : -
JonFreeman 4:67478861c670 9 1 Not Used on TS2018, connection from Twin BLDC Controller only - Pot wiper
JonFreeman 4:67478861c670 10 2 Not Used on TS2018, connection from Twin BLDC Controller only - GND
JonFreeman 4:67478861c670 11 3 Not Used on TS2018, connection from Twin BLDC Controller only - Weak +5 (top of pot)
JonFreeman 12:a25bdf135348 12 4 Not Used on TS2018, connection from Twin BLDC Controller only - Fwd / Rev switched between pins 2 and 3 above
JonFreeman 4:67478861c670 13 5 TS2018 high voltage output - power up signal to Twin BLDC Controllers, +10 to + 70 Volt (full supply via 3k3 0.5W safety resistor)
JonFreeman 4:67478861c670 14 6 Twin BLDC Rx- <- TS2018 Tx data ||GND to avoid exposing TS +5v rail to the outside world
JonFreeman 4:67478861c670 15 7 Twin BLDC Rx+ <- TS2018 +5v ||Tx\ to avoid exposing TS +5v rail to the outside world, INVERTED Txd idles lo
JonFreeman 4:67478861c670 16 8 Twin BLDC Tx- <- TS2018 GND
JonFreeman 4:67478861c670 17 9 Twin BLDC Tx+ <- TS2018 Rx data with 1k pullup to +5, line idles hi
JonFreeman 4:67478861c670 18 */
adustm 0:99e26e18b424 19 #include "mbed.h"
JonFreeman 4:67478861c670 20 #include "Electric_Loco.h"
JonFreeman 5:21a8ac83142c 21 #include "AsyncSerial.hpp"
JonFreeman 5:21a8ac83142c 22 #include "Servo.h"
JonFreeman 4:67478861c670 23 #include "TS_DISCO_F746NG.h"
JonFreeman 4:67478861c670 24 #include "LCD_DISCO_F746NG.h"
JonFreeman 12:a25bdf135348 25
JonFreeman 12:a25bdf135348 26 char const_version_string[] = {"1.0.0\0"}; // Version string, readable from serial ports
JonFreeman 12:a25bdf135348 27
JonFreeman 12:a25bdf135348 28 LCD_DISCO_F746NG lcd ; // LCD display
JonFreeman 12:a25bdf135348 29 TS_DISCO_F746NG touch_screen ; // Touch Screen
JonFreeman 12:a25bdf135348 30 screen_touch_handler slider ; // Loco driver's slider control
JonFreeman 4:67478861c670 31
JonFreeman 12:a25bdf135348 32 // see movingcoilmeter.h ffi
JonFreeman 12:a25bdf135348 33 moving_coil_meter Voltmeter ( LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_MAGENTA,
JonFreeman 12:a25bdf135348 34 VOLTMETER_X, VOLTMETER_Y, V_A_SIZE, 22.0, 61.0, 1.25 * PI, -0.25 * PI , 20, "V", ONE_DP, false),
JonFreeman 12:a25bdf135348 35 Powermeter ( LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_BLUE,
JonFreeman 12:a25bdf135348 36 AMMETER_X, AMMETER_Y, V_A_SIZE, -1400.0, 1400.0, 1.25 * PI, -0.25 * PI , 14, "Watt", NO_DPS, false),
JonFreeman 12:a25bdf135348 37 Speedo ( SPEEDO_BODY_COLOUR, SPEEDO_DIAL_COLOUR, LCD_COLOR_RED, SPEEDO_TEXT_COLOUR, LCD_COLOR_BLACK,
JonFreeman 12:a25bdf135348 38 SPEEDO_X, SPEEDO_Y, SPEEDO_SIZE, 0.0, 12.0, 1.25 * PI, -0.25 * PI , 12, "MPH", ONE_DP, false);
JonFreeman 12:a25bdf135348 39 // 3 instances of moving coil meter graphic
JonFreeman 4:67478861c670 40
JonFreeman 12:a25bdf135348 41 error_handling_Jan_2019 Controller_Error ; // Provides array usable to store error codes.
JonFreeman 12:a25bdf135348 42 STM3_ESC_Interface My_STM3_ESC_boards ;
JonFreeman 12:a25bdf135348 43
JonFreeman 12:a25bdf135348 44 extern command_line_interpreter_core pcli, ploco; // pcli handles comms with pc, ploco handles comms with STM3_ESC boards
JonFreeman 4:67478861c670 45
JonFreeman 12:a25bdf135348 46 /*
JonFreeman 12:a25bdf135348 47 STRANGE BEHAVIOUR WARNING !
JonFreeman 12:a25bdf135348 48 This project requires two serial ports.
JonFreeman 12:a25bdf135348 49 The following combination of one 'Serial' and one 'AsyncSerial' is the only combination found to work !
JonFreeman 12:a25bdf135348 50 MODSERIAL has not been adapted to F746NG, will not compile.
JonFreeman 12:a25bdf135348 51 Does compile with BufferedSerial but crashes the whole thing. No startup.
JonFreeman 12:a25bdf135348 52 */
JonFreeman 4:67478861c670 53
JonFreeman 12:a25bdf135348 54 Serial pc (USBTX, USBRX); // AsyncSerial does not work here. Comms to 'PuTTY' or similar comms programme on pc
JonFreeman 12:a25bdf135348 55 AsyncSerial com2escs (A4, A5); // Com port to opto isolators on Twin BLDC Controller boards. Only AsyncSerial works here
JonFreeman 12:a25bdf135348 56
JonFreeman 12:a25bdf135348 57 //DigitalOut reverse_pin (D7); // These pins no longer used to set mode and direction, now commands issued to com
JonFreeman 12:a25bdf135348 58 //DigitalOut forward_pin (D9); //was D6, these two decode to fwd, rev, regen_braking and park
JonFreeman 12:a25bdf135348 59
JonFreeman 12:a25bdf135348 60 DigitalOut I_sink1 (D14); // a horn
JonFreeman 12:a25bdf135348 61 DigitalOut I_sink2 (D15); // lamp
JonFreeman 12:a25bdf135348 62 DigitalOut I_sink3 (D3); // lamp
JonFreeman 12:a25bdf135348 63 DigitalOut I_sink4 (D4);
JonFreeman 12:a25bdf135348 64 DigitalOut I_sink5 (D5);
JonFreeman 12:a25bdf135348 65 DigitalOut led_grn (LED1); // the only on board user led
JonFreeman 4:67478861c670 66
JonFreeman 5:21a8ac83142c 67 DigitalIn f_r_switch (D2); // was D0, Reads position of centre-off ignition switch
JonFreeman 4:67478861c670 68 //DigitalIn spareio_d8 (D8);
JonFreeman 5:21a8ac83142c 69 //DigitalIn spareio_d9 (D9);
JonFreeman 4:67478861c670 70 DigitalIn spareio_d10 (D10); // D8, D9, D10 wired to jumper on pcb - not used to Apr 2017
JonFreeman 4:67478861c670 71
JonFreeman 4:67478861c670 72 AnalogIn ht_volts_ain (A0); // Jan 2017
JonFreeman 4:67478861c670 73 AnalogIn ht_amps_ain (A1); // Jan 2017
JonFreeman 5:21a8ac83142c 74 //AnalogIn spare_ain2 (A2);
JonFreeman 5:21a8ac83142c 75 //AnalogIn spare_ain3 (A3);
JonFreeman 4:67478861c670 76 //AnalogIn spare_ain4 (A4); // hardware on pcb for these 3 spare analogue inputs - not used to Apr 2017
JonFreeman 4:67478861c670 77 //AnalogIn spare_ain5 (A5); // causes display flicker !
JonFreeman 5:21a8ac83142c 78
JonFreeman 12:a25bdf135348 79 Servo servo1 (D6); // Model control servo used to adjust Honda engine speed
JonFreeman 4:67478861c670 80
JonFreeman 12:a25bdf135348 81 extern bool test_qspi () ;
JonFreeman 4:67478861c670 82 extern bool odometer_zero () ; // Returns true on success
JonFreeman 4:67478861c670 83 extern bool odometer_update (uint32_t pulsetot, uint16_t pow, uint16_t volt) ; // Hall pulse total updated once per sec and saved in blocks of 4096 bytes on QSPI onboard memory
JonFreeman 4:67478861c670 84
JonFreeman 4:67478861c670 85 extern void setup_buttons () ;
JonFreeman 12:a25bdf135348 86 extern void rewrite_odometer () ;
JonFreeman 7:3b1f44cd4735 87
JonFreeman 4:67478861c670 88 static const int
JonFreeman 4:67478861c670 89 MAF_PTS = 140, // Moving Average Filter points. Filters reduce noise on volatage and current readings
JonFreeman 4:67478861c670 90 FWD = 0,
JonFreeman 4:67478861c670 91 REV = ~FWD;
JonFreeman 4:67478861c670 92
JonFreeman 12:a25bdf135348 93 int32_t V_maf[MAF_PTS + 2], I_maf[MAF_PTS + 2], maf_ptr = 0; //
JonFreeman 12:a25bdf135348 94 volatile uint32_t sys_timer_32Hz = 0;
JonFreeman 12:a25bdf135348 95 double recent_distance = 0.0;
adustm 0:99e26e18b424 96
JonFreeman 12:a25bdf135348 97 bool qtrsec_trig = false;
JonFreeman 12:a25bdf135348 98 bool trigger_current_read = false;
JonFreeman 4:67478861c670 99 volatile bool trigger_32ms = false;
JonFreeman 4:67478861c670 100
JonFreeman 12:a25bdf135348 101 double read_voltmeter ()
JonFreeman 4:67478861c670 102 {
JonFreeman 7:3b1f44cd4735 103 int32_t a = 0;
JonFreeman 4:67478861c670 104 for (int b = 0; b < MAF_PTS; b++)
JonFreeman 12:a25bdf135348 105 a += V_maf[b];
JonFreeman 12:a25bdf135348 106 a /= MAF_PTS;
JonFreeman 12:a25bdf135348 107 double v = (double) a;
JonFreeman 12:a25bdf135348 108 return (v / 932.0) + 0.0; // fiddled to suit resistor values
JonFreeman 12:a25bdf135348 109 }
JonFreeman 12:a25bdf135348 110
JonFreeman 12:a25bdf135348 111 double read_ammeter () // Returns amps taken by STM3escs - amps dumped due to over-voltage
JonFreeman 12:a25bdf135348 112 { // Could make sense to read this at up to 32 times per second
JonFreeman 12:a25bdf135348 113 int32_t a = 0; // MAF data almost completely renewed at this rate
JonFreeman 12:a25bdf135348 114 for (int b = 0; b < MAF_PTS; b++) // MAF updated every 250us, MAF size = MAF_PTS (once set to 140, probably still is)
JonFreeman 4:67478861c670 115 a += I_maf[b];
JonFreeman 4:67478861c670 116 a /= MAF_PTS;
JonFreeman 7:3b1f44cd4735 117 a -= 0x4000;
JonFreeman 7:3b1f44cd4735 118 double i = (double) (0 - a);
JonFreeman 7:3b1f44cd4735 119 return i / 200.0; // Fiddled to get current reading close enough
JonFreeman 4:67478861c670 120 }
JonFreeman 4:67478861c670 121
JonFreeman 12:a25bdf135348 122 const int BIGMAFSIZ = 8;
JonFreeman 12:a25bdf135348 123
JonFreeman 12:a25bdf135348 124 class ammeter_reading {
JonFreeman 12:a25bdf135348 125 double bigImaf[BIGMAFSIZ];
JonFreeman 12:a25bdf135348 126 int bigImafptr;
JonFreeman 12:a25bdf135348 127 double amps_longave, // internal use only
JonFreeman 12:a25bdf135348 128 amps_latest, // update() called @ 32Hz. Value stored here is average over most recent 3125us
JonFreeman 12:a25bdf135348 129 amps_filtered; // Average of the BIGMAFSIZ most recent samples stored in latest
JonFreeman 12:a25bdf135348 130 public:
JonFreeman 12:a25bdf135348 131 ammeter_reading () { // constructor
JonFreeman 12:a25bdf135348 132 bigImafptr = 0;
JonFreeman 12:a25bdf135348 133 amps_longave = amps_latest = amps_filtered = 0.0;
JonFreeman 12:a25bdf135348 134 for (int i = 0; i < BIGMAFSIZ; i++)
JonFreeman 12:a25bdf135348 135 bigImaf[i] = 0.0;
JonFreeman 12:a25bdf135348 136 }
JonFreeman 12:a25bdf135348 137 void update () ; // Read ammeter core, store most recent 32ms or so worth in amps_latest, 250ms average in amps_filtered
JonFreeman 12:a25bdf135348 138 double latest () ;
JonFreeman 12:a25bdf135348 139 double filtered() ;
JonFreeman 12:a25bdf135348 140 } Ammeter ;
JonFreeman 12:a25bdf135348 141
JonFreeman 12:a25bdf135348 142 double ammeter_reading::latest () {
JonFreeman 12:a25bdf135348 143 return amps_latest;
JonFreeman 4:67478861c670 144 }
JonFreeman 4:67478861c670 145
JonFreeman 12:a25bdf135348 146 double ammeter_reading::filtered () {
JonFreeman 12:a25bdf135348 147 return amps_filtered;
JonFreeman 12:a25bdf135348 148 }
JonFreeman 12:a25bdf135348 149
JonFreeman 12:a25bdf135348 150 void ammeter_reading::update () {
JonFreeman 12:a25bdf135348 151 amps_latest = read_ammeter();
JonFreeman 12:a25bdf135348 152 amps_longave -= bigImaf[bigImafptr];
JonFreeman 12:a25bdf135348 153 bigImaf[bigImafptr] = amps_latest;
JonFreeman 12:a25bdf135348 154 amps_longave += amps_latest;
JonFreeman 12:a25bdf135348 155 bigImafptr++;
JonFreeman 12:a25bdf135348 156 if (bigImafptr >= BIGMAFSIZ)
JonFreeman 12:a25bdf135348 157 bigImafptr = 0;
JonFreeman 12:a25bdf135348 158 amps_filtered = amps_longave / BIGMAFSIZ;
JonFreeman 12:a25bdf135348 159 }
JonFreeman 12:a25bdf135348 160
JonFreeman 12:a25bdf135348 161
JonFreeman 4:67478861c670 162 // Interrupt Service Routines
JonFreeman 4:67478861c670 163
JonFreeman 4:67478861c670 164 void ISR_current_reader (void) // FIXED at 250us
JonFreeman 4:67478861c670 165 {
JonFreeman 4:67478861c670 166 static int ms32 = 0, ms250 = 0;
JonFreeman 4:67478861c670 167 trigger_current_read = true; // every 250us, i.e. 4kHz NOTE only sets trigger here, readings taken in main loop
JonFreeman 4:67478861c670 168 ms32++;
JonFreeman 12:a25bdf135348 169 if (ms32 >= 125) { // 31.25ms, not 32ms, is 32Hz
JonFreeman 4:67478861c670 170 ms32 = 0;
JonFreeman 5:21a8ac83142c 171 sys_timer_32Hz++; // , usable anywhere as general measure of elapsed time
JonFreeman 4:67478861c670 172 trigger_32ms = true;
JonFreeman 4:67478861c670 173 ms250++;
JonFreeman 12:a25bdf135348 174 if (ms250 >= 8) {
JonFreeman 4:67478861c670 175 ms250 = 0;
JonFreeman 4:67478861c670 176 qtrsec_trig = true;
JonFreeman 4:67478861c670 177 }
JonFreeman 4:67478861c670 178 }
JonFreeman 4:67478861c670 179 }
JonFreeman 4:67478861c670 180
JonFreeman 4:67478861c670 181 // End of Interrupt Service Routines
JonFreeman 4:67478861c670 182
JonFreeman 5:21a8ac83142c 183 void throttle (double p) { // New Apr 2018 ; servo adjusts throttle lever on Honda GX120
JonFreeman 12:a25bdf135348 184 const double THR_MAX = 0.92; // Values tweaked to suit servo and linkage fitted to loco power unit
JonFreeman 12:a25bdf135348 185 const double THR_MIN = 0.09;
JonFreeman 12:a25bdf135348 186 const double RANGE = (THR_MAX - THR_MIN);
JonFreeman 5:21a8ac83142c 187 if (p > 1.0)
JonFreeman 5:21a8ac83142c 188 p = 1.0;
JonFreeman 5:21a8ac83142c 189 if (p < 0.0)
JonFreeman 5:21a8ac83142c 190 p = 0.0;
JonFreeman 5:21a8ac83142c 191 // p = 1.0 - p; // if direction needs swapping
JonFreeman 5:21a8ac83142c 192 p *= RANGE;
JonFreeman 5:21a8ac83142c 193 p += THR_MIN;
JonFreeman 5:21a8ac83142c 194 servo1 = p;
adustm 0:99e26e18b424 195 }
adustm 0:99e26e18b424 196
JonFreeman 5:21a8ac83142c 197
JonFreeman 12:a25bdf135348 198 void horn (int which, int onoff) {
JonFreeman 12:a25bdf135348 199 if (which == HI_HORN)
JonFreeman 12:a25bdf135348 200 I_sink5 = onoff;
JonFreeman 12:a25bdf135348 201 else
JonFreeman 12:a25bdf135348 202 I_sink4 = onoff;
JonFreeman 12:a25bdf135348 203 }
JonFreeman 12:a25bdf135348 204
JonFreeman 12:a25bdf135348 205
JonFreeman 7:3b1f44cd4735 206 void lights (int onoff) {
JonFreeman 7:3b1f44cd4735 207 I_sink2 = onoff; // lamp right
JonFreeman 7:3b1f44cd4735 208 I_sink3 = onoff; // lamp left
JonFreeman 7:3b1f44cd4735 209 }
JonFreeman 4:67478861c670 210
JonFreeman 12:a25bdf135348 211
JonFreeman 12:a25bdf135348 212 void draw_normal_run_screen () {
JonFreeman 12:a25bdf135348 213 lcd.Clear(LCD_COLOR_LIGHTGRAY);
JonFreeman 12:a25bdf135348 214 setup_buttons(); // draws buttons
JonFreeman 12:a25bdf135348 215 slider.DrawSlider ();
JonFreeman 12:a25bdf135348 216 // Draw 3 analogue meter movements, speedo, voltmeter, ammeter
JonFreeman 12:a25bdf135348 217 Speedo.redraw();
JonFreeman 12:a25bdf135348 218 Voltmeter.redraw();
JonFreeman 12:a25bdf135348 219 Powermeter.redraw();
JonFreeman 12:a25bdf135348 220 }
JonFreeman 12:a25bdf135348 221
JonFreeman 12:a25bdf135348 222
JonFreeman 12:a25bdf135348 223 int main() // Programme entry point
JonFreeman 4:67478861c670 224 {
JonFreeman 12:a25bdf135348 225 int qtr_sec = 0, seconds = 0, minutes = 0;
JonFreeman 12:a25bdf135348 226 double electrical_power_Watt = 0.0, volts = 0.0;
JonFreeman 12:a25bdf135348 227
JonFreeman 7:3b1f44cd4735 228 pc.baud (9600);
JonFreeman 12:a25bdf135348 229 com2escs.baud (19200);
JonFreeman 7:3b1f44cd4735 230
JonFreeman 7:3b1f44cd4735 231 I_sink1 = 0; // turn outputs off
JonFreeman 7:3b1f44cd4735 232 I_sink2 = 0; // lamp right
JonFreeman 7:3b1f44cd4735 233 I_sink3 = 0; // lamp left
JonFreeman 12:a25bdf135348 234 I_sink4 = 0; // low horn
JonFreeman 12:a25bdf135348 235 I_sink5 = 0; // high horn
JonFreeman 7:3b1f44cd4735 236 spareio_d10.mode(PullUp);
JonFreeman 7:3b1f44cd4735 237
JonFreeman 12:a25bdf135348 238 Ticker tick250us; // Master 4kHz interrupt timebase
JonFreeman 7:3b1f44cd4735 239
JonFreeman 7:3b1f44cd4735 240 // Setup User Interrupt Vectors
JonFreeman 12:a25bdf135348 241 tick250us.attach_us (&ISR_current_reader, 250); // count 125 interrupts to trig 31.25ms
JonFreeman 4:67478861c670 242
JonFreeman 12:a25bdf135348 243 // QSPI memory is now in constant use for odometer
JonFreeman 12:a25bdf135348 244 if (!test_qspi())
JonFreeman 12:a25bdf135348 245 Controller_Error.set (FAULT_QSPI, -1); // pc.printf ("Problem with qspimemcheck\r\n");
JonFreeman 4:67478861c670 246
JonFreeman 12:a25bdf135348 247 slider.direction = f_r_switch ? REV : FWD; // Only place in the code where direction gets set. Centre-Off power switch REV-OFF-FWD.
JonFreeman 4:67478861c670 248
JonFreeman 12:a25bdf135348 249 My_STM3_ESC_boards.set_I_limit (0.0);
JonFreeman 12:a25bdf135348 250 My_STM3_ESC_boards.set_V_limit (0.0);
JonFreeman 12:a25bdf135348 251 My_STM3_ESC_boards.message ("rb\r");
JonFreeman 12:a25bdf135348 252 throttle (0.0); // Set revs to idle. Start engine and warm up before powering up control
JonFreeman 12:a25bdf135348 253 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");
JonFreeman 4:67478861c670 254
JonFreeman 4:67478861c670 255 uint8_t lcd_status = touch_screen.Init(lcd.GetXSize(), lcd.GetYSize());
JonFreeman 4:67478861c670 256 if (lcd_status != TS_OK) {
JonFreeman 12:a25bdf135348 257 Controller_Error.set (FAULT_TS, -1);
JonFreeman 12:a25bdf135348 258 }
JonFreeman 12:a25bdf135348 259 lcd.Clear(LCD_COLOR_DARKBLUE);
JonFreeman 12:a25bdf135348 260 lcd.SetBackColor(LCD_COLOR_GREEN);
JonFreeman 12:a25bdf135348 261 lcd.SetTextColor(LCD_COLOR_WHITE);
JonFreeman 12:a25bdf135348 262 lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT OK", CENTER_MODE);
JonFreeman 4:67478861c670 263
JonFreeman 7:3b1f44cd4735 264 // if (odometer_zero ())
JonFreeman 7:3b1f44cd4735 265 // pc.printf ("TRUE from odometer_zero\r\n");
JonFreeman 7:3b1f44cd4735 266 // else
JonFreeman 7:3b1f44cd4735 267 // pc.printf ("FALSE from odometer_zero\r\n");
JonFreeman 5:21a8ac83142c 268
JonFreeman 7:3b1f44cd4735 269 lights (1); // Headlights ON!
JonFreeman 7:3b1f44cd4735 270
JonFreeman 12:a25bdf135348 271 My_STM3_ESC_boards.search_for_escs (); // Build list of connected STM3_ESC IDs
JonFreeman 4:67478861c670 272
JonFreeman 12:a25bdf135348 273 /* Controller_Error.set (3, 99);
JonFreeman 12:a25bdf135348 274 pc.printf ("%lx red\r\n", LCD_COLOR_RED); //LCD_COLOR is 0xffrrggbb
JonFreeman 12:a25bdf135348 275 pc.printf ("%lx grn\r\n", LCD_COLOR_GREEN);
JonFreeman 12:a25bdf135348 276 pc.printf ("%lx blu\r\n", LCD_COLOR_BLUE);
JonFreeman 12:a25bdf135348 277 pc.printf ("%lx blk\r\n", LCD_COLOR_BLACK);
JonFreeman 12:a25bdf135348 278 pc.printf ("%lx white\r\n", LCD_COLOR_WHITE);
JonFreeman 12:a25bdf135348 279 */
JonFreeman 12:a25bdf135348 280 draw_normal_run_screen ();
JonFreeman 4:67478861c670 281
JonFreeman 12:a25bdf135348 282 pc.printf ("Controller_Error.all_good() ret'd %s\r\n", Controller_Error.all_good() ? "true" : "false");
JonFreeman 4:67478861c670 283
JonFreeman 12:a25bdf135348 284 while (1) { // main prog loop
JonFreeman 4:67478861c670 285
JonFreeman 12:a25bdf135348 286 pcli.sniff (); // Do any actions from command line serial port via usb link
JonFreeman 4:67478861c670 287
JonFreeman 12:a25bdf135348 288 if (trigger_current_read) { // flag set in interrupt handler every 250us
JonFreeman 12:a25bdf135348 289 trigger_current_read = false;
JonFreeman 12:a25bdf135348 290 I_maf[maf_ptr] = ht_amps_ain.read_u16(); // Read raw ACS709 ammeter module
JonFreeman 12:a25bdf135348 291 V_maf[maf_ptr] = ht_volts_ain.read_u16(); // Read raw system voltage
JonFreeman 12:a25bdf135348 292 maf_ptr++;
JonFreeman 12:a25bdf135348 293 if (maf_ptr > MAF_PTS - 1)
JonFreeman 12:a25bdf135348 294 maf_ptr = 0;
JonFreeman 12:a25bdf135348 295 } // endof stuff to do every 250us
JonFreeman 4:67478861c670 296
JonFreeman 12:a25bdf135348 297 if (trigger_32ms == true) { // Stuff to do every 31.25 milli secs (32Hz)
JonFreeman 12:a25bdf135348 298 trigger_32ms = false;
JonFreeman 12:a25bdf135348 299 ploco.sniff (); // Only call within main loop, checks message responses from STM3_ESC boards
JonFreeman 12:a25bdf135348 300 Ammeter.update (); // This updates Ammeter 'latest' and 'filtered' variables every 31.25ms
JonFreeman 12:a25bdf135348 301 slider.HandleFingerInput (); // Do everything concerning fingers on touch screen
JonFreeman 12:a25bdf135348 302 } // endof doing 32Hz stuff
JonFreeman 4:67478861c670 303
JonFreeman 4:67478861c670 304 if (qtrsec_trig == true) { // do every quarter second stuff here
JonFreeman 4:67478861c670 305 qtrsec_trig = false;
JonFreeman 12:a25bdf135348 306 volts = read_voltmeter(); // voltage and current readings updated @ 250us, these are averaged over 35ms or so
JonFreeman 12:a25bdf135348 307 electrical_power_Watt = volts * Ammeter.filtered(); // visible throughout main
JonFreeman 12:a25bdf135348 308 // Update meters
JonFreeman 12:a25bdf135348 309 Powermeter.set_value(electrical_power_Watt);
JonFreeman 12:a25bdf135348 310 Voltmeter.set_value (volts);
JonFreeman 12:a25bdf135348 311 Speedo.set_value (My_STM3_ESC_boards.mph);
JonFreeman 12:a25bdf135348 312
JonFreeman 4:67478861c670 313 led_grn = !led_grn;
JonFreeman 12:a25bdf135348 314 /*
JonFreeman 12:a25bdf135348 315 Handbrake more sensibly implemented on STM3_ESC boards ?
JonFreeman 12:a25bdf135348 316
JonFreeman 4:67478861c670 317 if (slider.state == PARK) {
JonFreeman 12:a25bdf135348 318 if (My_STM3_ESC_boards.mph > LOCO_HANDBRAKE_ESCAPE_SPEED / 4.0) {
JonFreeman 4:67478861c670 319 slider.handbrake_effort *= 1.1;
JonFreeman 4:67478861c670 320 if (slider.handbrake_effort > 0.55) slider.handbrake_effort = 0.55;
JonFreeman 4:67478861c670 321 set_run_mode (PARK);
JonFreeman 4:67478861c670 322 pc.printf ("Handbrake slipping, effort %.2f\r\n", slider.handbrake_effort);
JonFreeman 4:67478861c670 323 }
JonFreeman 12:a25bdf135348 324 if (My_STM3_ESC_boards.mph < 0.02) {
JonFreeman 4:67478861c670 325 slider.handbrake_effort *= 0.9;
JonFreeman 4:67478861c670 326 if (slider.handbrake_effort < 0.05) slider.handbrake_effort = 0.05;
JonFreeman 4:67478861c670 327 set_run_mode (PARK);
JonFreeman 4:67478861c670 328 pc.printf ("Handbrake not slipping, effort %.2f\r\n", slider.handbrake_effort);
JonFreeman 4:67478861c670 329 }
JonFreeman 4:67478861c670 330 }
JonFreeman 12:a25bdf135348 331 */
JonFreeman 12:a25bdf135348 332 My_STM3_ESC_boards.request_mph (); // issues "'n'rpm\r", takes care of cycling through available boards in sequence
JonFreeman 7:3b1f44cd4735 333 // switch (qtr_sec) { // Can do sequential stuff quarter second apart here
JonFreeman 7:3b1f44cd4735 334 // } // End of switch qtr_sec
JonFreeman 4:67478861c670 335 qtr_sec++;
JonFreeman 4:67478861c670 336 // Can do stuff once per second here
JonFreeman 4:67478861c670 337 if(qtr_sec > 3) {
JonFreeman 4:67478861c670 338 qtr_sec = 0;
JonFreeman 4:67478861c670 339 seconds++;
JonFreeman 4:67478861c670 340 if (seconds > 59) {
JonFreeman 4:67478861c670 341 seconds = 0;
JonFreeman 4:67478861c670 342 minutes++;
JonFreeman 4:67478861c670 343 // do once per minute stuff here
JonFreeman 12:a25bdf135348 344 Controller_Error.report_any ();
JonFreeman 4:67478861c670 345 } // fall back into once per second
JonFreeman 12:a25bdf135348 346 if (seconds & 1)
JonFreeman 12:a25bdf135348 347 Speedo.LED (0, LCD_COLOR_DARKGRAY);
JonFreeman 12:a25bdf135348 348 else
JonFreeman 12:a25bdf135348 349 Speedo.LED (0, LCD_COLOR_RED);
JonFreeman 12:a25bdf135348 350 My_STM3_ESC_boards.message ("kd\r"); // Kick the WatchDog timers in the Twin BLDC drive boards
JonFreeman 12:a25bdf135348 351 recent_distance += (My_STM3_ESC_boards.mph * (111.76 * 4.0)); // Convert mph to distance mm travelled in one second
JonFreeman 12:a25bdf135348 352 uint32_t new_metres = ((uint32_t)recent_distance) / 1000;
JonFreeman 12:a25bdf135348 353 recent_distance -= (double)(new_metres * 1000);
JonFreeman 12:a25bdf135348 354 if (!odometer_update (new_metres, (uint16_t)electrical_power_Watt, (uint16_t)(volts * 500.0))) {
JonFreeman 12:a25bdf135348 355 pc.printf ("Probs with odometer_update");
JonFreeman 12:a25bdf135348 356 Controller_Error.set (FAULT_ODOMETER, 1);
JonFreeman 12:a25bdf135348 357 }
JonFreeman 12:a25bdf135348 358 rewrite_odometer () ; // Update text on speedo dial face
JonFreeman 4:67478861c670 359 } // endof if(qtr_sec > 3
JonFreeman 4:67478861c670 360 } // endof if (qtrsec_trig == true) {
JonFreeman 4:67478861c670 361 } // endof while(1) main programme loop
JonFreeman 12:a25bdf135348 362 } // endof main ()
JonFreeman 4:67478861c670 363