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 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?

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 14:6bcec5ac21ca 129 amps_filtered, // Average of the BIGMAFSIZ most recent samples stored in latest
JonFreeman 14:6bcec5ac21ca 130 amps_filtered2; // Average of the BIGMAFSIZ most recent samples stored in latest
JonFreeman 12:a25bdf135348 131 public:
JonFreeman 12:a25bdf135348 132 ammeter_reading () { // constructor
JonFreeman 12:a25bdf135348 133 bigImafptr = 0;
JonFreeman 14:6bcec5ac21ca 134 amps_longave = amps_latest = amps_filtered = amps_filtered2 = 0.0;
JonFreeman 12:a25bdf135348 135 for (int i = 0; i < BIGMAFSIZ; i++)
JonFreeman 12:a25bdf135348 136 bigImaf[i] = 0.0;
JonFreeman 12:a25bdf135348 137 }
JonFreeman 12:a25bdf135348 138 void update () ; // Read ammeter core, store most recent 32ms or so worth in amps_latest, 250ms average in amps_filtered
JonFreeman 12:a25bdf135348 139 double latest () ;
JonFreeman 12:a25bdf135348 140 double filtered() ;
JonFreeman 14:6bcec5ac21ca 141 double filtered2() ;
JonFreeman 12:a25bdf135348 142 } Ammeter ;
JonFreeman 12:a25bdf135348 143
JonFreeman 12:a25bdf135348 144 double ammeter_reading::latest () {
JonFreeman 12:a25bdf135348 145 return amps_latest;
JonFreeman 4:67478861c670 146 }
JonFreeman 4:67478861c670 147
JonFreeman 14:6bcec5ac21ca 148 double ammeter_reading::filtered2 () {
JonFreeman 14:6bcec5ac21ca 149 // could use filter without buffer, weights result more towards more frecent samples
JonFreeman 14:6bcec5ac21ca 150 return amps_filtered2;
JonFreeman 14:6bcec5ac21ca 151 }
JonFreeman 14:6bcec5ac21ca 152
JonFreeman 12:a25bdf135348 153 double ammeter_reading::filtered () {
JonFreeman 12:a25bdf135348 154 return amps_filtered;
JonFreeman 12:a25bdf135348 155 }
JonFreeman 12:a25bdf135348 156
JonFreeman 12:a25bdf135348 157 void ammeter_reading::update () {
JonFreeman 12:a25bdf135348 158 amps_latest = read_ammeter();
JonFreeman 12:a25bdf135348 159 amps_longave -= bigImaf[bigImafptr];
JonFreeman 12:a25bdf135348 160 bigImaf[bigImafptr] = amps_latest;
JonFreeman 12:a25bdf135348 161 amps_longave += amps_latest;
JonFreeman 12:a25bdf135348 162 bigImafptr++;
JonFreeman 12:a25bdf135348 163 if (bigImafptr >= BIGMAFSIZ)
JonFreeman 12:a25bdf135348 164 bigImafptr = 0;
JonFreeman 12:a25bdf135348 165 amps_filtered = amps_longave / BIGMAFSIZ;
JonFreeman 14:6bcec5ac21ca 166 const double sampweight = (double)(1) / (double)BIGMAFSIZ;
JonFreeman 14:6bcec5ac21ca 167 const double shrinkby = 1.0 - sampweight;
JonFreeman 14:6bcec5ac21ca 168 amps_filtered2 *= shrinkby;
JonFreeman 14:6bcec5ac21ca 169 amps_filtered2 += amps_latest * sampweight;
JonFreeman 12:a25bdf135348 170 }
JonFreeman 12:a25bdf135348 171
JonFreeman 12:a25bdf135348 172
JonFreeman 4:67478861c670 173 // Interrupt Service Routines
JonFreeman 4:67478861c670 174
JonFreeman 4:67478861c670 175 void ISR_current_reader (void) // FIXED at 250us
JonFreeman 4:67478861c670 176 {
JonFreeman 4:67478861c670 177 static int ms32 = 0, ms250 = 0;
JonFreeman 4:67478861c670 178 trigger_current_read = true; // every 250us, i.e. 4kHz NOTE only sets trigger here, readings taken in main loop
JonFreeman 4:67478861c670 179 ms32++;
JonFreeman 12:a25bdf135348 180 if (ms32 >= 125) { // 31.25ms, not 32ms, is 32Hz
JonFreeman 4:67478861c670 181 ms32 = 0;
JonFreeman 5:21a8ac83142c 182 sys_timer_32Hz++; // , usable anywhere as general measure of elapsed time
JonFreeman 4:67478861c670 183 trigger_32ms = true;
JonFreeman 4:67478861c670 184 ms250++;
JonFreeman 12:a25bdf135348 185 if (ms250 >= 8) {
JonFreeman 4:67478861c670 186 ms250 = 0;
JonFreeman 4:67478861c670 187 qtrsec_trig = true;
JonFreeman 4:67478861c670 188 }
JonFreeman 4:67478861c670 189 }
JonFreeman 4:67478861c670 190 }
JonFreeman 4:67478861c670 191
JonFreeman 4:67478861c670 192 // End of Interrupt Service Routines
JonFreeman 4:67478861c670 193
JonFreeman 5:21a8ac83142c 194 void throttle (double p) { // New Apr 2018 ; servo adjusts throttle lever on Honda GX120
JonFreeman 12:a25bdf135348 195 const double THR_MAX = 0.92; // Values tweaked to suit servo and linkage fitted to loco power unit
JonFreeman 12:a25bdf135348 196 const double THR_MIN = 0.09;
JonFreeman 12:a25bdf135348 197 const double RANGE = (THR_MAX - THR_MIN);
JonFreeman 5:21a8ac83142c 198 if (p > 1.0)
JonFreeman 5:21a8ac83142c 199 p = 1.0;
JonFreeman 5:21a8ac83142c 200 if (p < 0.0)
JonFreeman 5:21a8ac83142c 201 p = 0.0;
JonFreeman 5:21a8ac83142c 202 // p = 1.0 - p; // if direction needs swapping
JonFreeman 5:21a8ac83142c 203 p *= RANGE;
JonFreeman 5:21a8ac83142c 204 p += THR_MIN;
JonFreeman 5:21a8ac83142c 205 servo1 = p;
adustm 0:99e26e18b424 206 }
adustm 0:99e26e18b424 207
JonFreeman 5:21a8ac83142c 208
JonFreeman 12:a25bdf135348 209 void horn (int which, int onoff) {
JonFreeman 12:a25bdf135348 210 if (which == HI_HORN)
JonFreeman 12:a25bdf135348 211 I_sink5 = onoff;
JonFreeman 12:a25bdf135348 212 else
JonFreeman 12:a25bdf135348 213 I_sink4 = onoff;
JonFreeman 12:a25bdf135348 214 }
JonFreeman 12:a25bdf135348 215
JonFreeman 12:a25bdf135348 216
JonFreeman 7:3b1f44cd4735 217 void lights (int onoff) {
JonFreeman 7:3b1f44cd4735 218 I_sink2 = onoff; // lamp right
JonFreeman 7:3b1f44cd4735 219 I_sink3 = onoff; // lamp left
JonFreeman 7:3b1f44cd4735 220 }
JonFreeman 4:67478861c670 221
JonFreeman 12:a25bdf135348 222
JonFreeman 12:a25bdf135348 223 void draw_normal_run_screen () {
JonFreeman 12:a25bdf135348 224 lcd.Clear(LCD_COLOR_LIGHTGRAY);
JonFreeman 12:a25bdf135348 225 setup_buttons(); // draws buttons
JonFreeman 12:a25bdf135348 226 slider.DrawSlider ();
JonFreeman 12:a25bdf135348 227 // Draw 3 analogue meter movements, speedo, voltmeter, ammeter
JonFreeman 12:a25bdf135348 228 Speedo.redraw();
JonFreeman 12:a25bdf135348 229 Voltmeter.redraw();
JonFreeman 12:a25bdf135348 230 Powermeter.redraw();
JonFreeman 12:a25bdf135348 231 }
JonFreeman 12:a25bdf135348 232
JonFreeman 12:a25bdf135348 233
JonFreeman 12:a25bdf135348 234 int main() // Programme entry point
JonFreeman 4:67478861c670 235 {
JonFreeman 12:a25bdf135348 236 int qtr_sec = 0, seconds = 0, minutes = 0;
JonFreeman 12:a25bdf135348 237 double electrical_power_Watt = 0.0, volts = 0.0;
JonFreeman 12:a25bdf135348 238
JonFreeman 7:3b1f44cd4735 239 pc.baud (9600);
JonFreeman 12:a25bdf135348 240 com2escs.baud (19200);
JonFreeman 7:3b1f44cd4735 241
JonFreeman 7:3b1f44cd4735 242 I_sink1 = 0; // turn outputs off
JonFreeman 7:3b1f44cd4735 243 I_sink2 = 0; // lamp right
JonFreeman 7:3b1f44cd4735 244 I_sink3 = 0; // lamp left
JonFreeman 12:a25bdf135348 245 I_sink4 = 0; // low horn
JonFreeman 12:a25bdf135348 246 I_sink5 = 0; // high horn
JonFreeman 7:3b1f44cd4735 247 spareio_d10.mode(PullUp);
JonFreeman 7:3b1f44cd4735 248
JonFreeman 12:a25bdf135348 249 Ticker tick250us; // Master 4kHz interrupt timebase
JonFreeman 7:3b1f44cd4735 250
JonFreeman 7:3b1f44cd4735 251 // Setup User Interrupt Vectors
JonFreeman 12:a25bdf135348 252 tick250us.attach_us (&ISR_current_reader, 250); // count 125 interrupts to trig 31.25ms
JonFreeman 4:67478861c670 253
JonFreeman 12:a25bdf135348 254 // QSPI memory is now in constant use for odometer
JonFreeman 12:a25bdf135348 255 if (!test_qspi())
JonFreeman 12:a25bdf135348 256 Controller_Error.set (FAULT_QSPI, -1); // pc.printf ("Problem with qspimemcheck\r\n");
JonFreeman 4:67478861c670 257
JonFreeman 12:a25bdf135348 258 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 259
JonFreeman 12:a25bdf135348 260 My_STM3_ESC_boards.set_I_limit (0.0);
JonFreeman 14:6bcec5ac21ca 261 My_STM3_ESC_boards.set_V_limit (0.0); // zero power to motors
JonFreeman 14:6bcec5ac21ca 262 My_STM3_ESC_boards.message ("rb\r"); // regen brake mode
JonFreeman 14:6bcec5ac21ca 263 throttle (0.0); // Set revs to idle. Start engine and warm up before powering up control
JonFreeman 12:a25bdf135348 264 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 265
JonFreeman 4:67478861c670 266 uint8_t lcd_status = touch_screen.Init(lcd.GetXSize(), lcd.GetYSize());
JonFreeman 4:67478861c670 267 if (lcd_status != TS_OK) {
JonFreeman 12:a25bdf135348 268 Controller_Error.set (FAULT_TS, -1);
JonFreeman 12:a25bdf135348 269 }
JonFreeman 12:a25bdf135348 270 lcd.Clear(LCD_COLOR_DARKBLUE);
JonFreeman 12:a25bdf135348 271 lcd.SetBackColor(LCD_COLOR_GREEN);
JonFreeman 12:a25bdf135348 272 lcd.SetTextColor(LCD_COLOR_WHITE);
JonFreeman 12:a25bdf135348 273 lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT OK", CENTER_MODE);
JonFreeman 4:67478861c670 274
JonFreeman 7:3b1f44cd4735 275 // if (odometer_zero ())
JonFreeman 7:3b1f44cd4735 276 // pc.printf ("TRUE from odometer_zero\r\n");
JonFreeman 7:3b1f44cd4735 277 // else
JonFreeman 7:3b1f44cd4735 278 // pc.printf ("FALSE from odometer_zero\r\n");
JonFreeman 5:21a8ac83142c 279
JonFreeman 7:3b1f44cd4735 280 lights (1); // Headlights ON!
JonFreeman 7:3b1f44cd4735 281
JonFreeman 12:a25bdf135348 282 My_STM3_ESC_boards.search_for_escs (); // Build list of connected STM3_ESC IDs
JonFreeman 4:67478861c670 283
JonFreeman 12:a25bdf135348 284 /* Controller_Error.set (3, 99);
JonFreeman 12:a25bdf135348 285 pc.printf ("%lx red\r\n", LCD_COLOR_RED); //LCD_COLOR is 0xffrrggbb
JonFreeman 12:a25bdf135348 286 pc.printf ("%lx grn\r\n", LCD_COLOR_GREEN);
JonFreeman 12:a25bdf135348 287 pc.printf ("%lx blu\r\n", LCD_COLOR_BLUE);
JonFreeman 12:a25bdf135348 288 pc.printf ("%lx blk\r\n", LCD_COLOR_BLACK);
JonFreeman 12:a25bdf135348 289 pc.printf ("%lx white\r\n", LCD_COLOR_WHITE);
JonFreeman 12:a25bdf135348 290 */
JonFreeman 12:a25bdf135348 291 draw_normal_run_screen ();
JonFreeman 4:67478861c670 292
JonFreeman 12:a25bdf135348 293 pc.printf ("Controller_Error.all_good() ret'd %s\r\n", Controller_Error.all_good() ? "true" : "false");
JonFreeman 4:67478861c670 294
JonFreeman 12:a25bdf135348 295 while (1) { // main prog loop
JonFreeman 4:67478861c670 296
JonFreeman 12:a25bdf135348 297 pcli.sniff (); // Do any actions from command line serial port via usb link
JonFreeman 4:67478861c670 298
JonFreeman 12:a25bdf135348 299 if (trigger_current_read) { // flag set in interrupt handler every 250us
JonFreeman 12:a25bdf135348 300 trigger_current_read = false;
JonFreeman 12:a25bdf135348 301 I_maf[maf_ptr] = ht_amps_ain.read_u16(); // Read raw ACS709 ammeter module
JonFreeman 12:a25bdf135348 302 V_maf[maf_ptr] = ht_volts_ain.read_u16(); // Read raw system voltage
JonFreeman 12:a25bdf135348 303 maf_ptr++;
JonFreeman 12:a25bdf135348 304 if (maf_ptr > MAF_PTS - 1)
JonFreeman 12:a25bdf135348 305 maf_ptr = 0;
JonFreeman 12:a25bdf135348 306 } // endof stuff to do every 250us
JonFreeman 4:67478861c670 307
JonFreeman 12:a25bdf135348 308 if (trigger_32ms == true) { // Stuff to do every 31.25 milli secs (32Hz)
JonFreeman 12:a25bdf135348 309 trigger_32ms = false;
JonFreeman 12:a25bdf135348 310 ploco.sniff (); // Only call within main loop, checks message responses from STM3_ESC boards
JonFreeman 12:a25bdf135348 311 Ammeter.update (); // This updates Ammeter 'latest' and 'filtered' variables every 31.25ms
JonFreeman 12:a25bdf135348 312 slider.HandleFingerInput (); // Do everything concerning fingers on touch screen
JonFreeman 12:a25bdf135348 313 } // endof doing 32Hz stuff
JonFreeman 4:67478861c670 314
JonFreeman 4:67478861c670 315 if (qtrsec_trig == true) { // do every quarter second stuff here
JonFreeman 4:67478861c670 316 qtrsec_trig = false;
JonFreeman 12:a25bdf135348 317 volts = read_voltmeter(); // voltage and current readings updated @ 250us, these are averaged over 35ms or so
JonFreeman 12:a25bdf135348 318 electrical_power_Watt = volts * Ammeter.filtered(); // visible throughout main
JonFreeman 12:a25bdf135348 319 // Update meters
JonFreeman 12:a25bdf135348 320 Powermeter.set_value(electrical_power_Watt);
JonFreeman 12:a25bdf135348 321 Voltmeter.set_value (volts);
JonFreeman 12:a25bdf135348 322 Speedo.set_value (My_STM3_ESC_boards.mph);
JonFreeman 12:a25bdf135348 323
JonFreeman 4:67478861c670 324 led_grn = !led_grn;
JonFreeman 14:6bcec5ac21ca 325 My_STM3_ESC_boards.request_mph (); // issues "'n'mph\r", takes care of cycling through available boards in sequence
JonFreeman 7:3b1f44cd4735 326 // switch (qtr_sec) { // Can do sequential stuff quarter second apart here
JonFreeman 7:3b1f44cd4735 327 // } // End of switch qtr_sec
JonFreeman 4:67478861c670 328 qtr_sec++;
JonFreeman 4:67478861c670 329 // Can do stuff once per second here
JonFreeman 4:67478861c670 330 if(qtr_sec > 3) {
JonFreeman 4:67478861c670 331 qtr_sec = 0;
JonFreeman 4:67478861c670 332 seconds++;
JonFreeman 4:67478861c670 333 if (seconds > 59) {
JonFreeman 4:67478861c670 334 seconds = 0;
JonFreeman 4:67478861c670 335 minutes++;
JonFreeman 4:67478861c670 336 // do once per minute stuff here
JonFreeman 14:6bcec5ac21ca 337 Controller_Error.report_any (false); // Reset error having reported it once
JonFreeman 4:67478861c670 338 } // fall back into once per second
JonFreeman 12:a25bdf135348 339 if (seconds & 1)
JonFreeman 12:a25bdf135348 340 Speedo.LED (0, LCD_COLOR_DARKGRAY);
JonFreeman 12:a25bdf135348 341 else
JonFreeman 12:a25bdf135348 342 Speedo.LED (0, LCD_COLOR_RED);
JonFreeman 14:6bcec5ac21ca 343 // pc.printf ("Filter test %.3f, %.3f\r\n", Ammeter.filtered(), Ammeter.filtered2());
JonFreeman 12:a25bdf135348 344 My_STM3_ESC_boards.message ("kd\r"); // Kick the WatchDog timers in the Twin BLDC drive boards
JonFreeman 12:a25bdf135348 345 recent_distance += (My_STM3_ESC_boards.mph * (111.76 * 4.0)); // Convert mph to distance mm travelled in one second
JonFreeman 12:a25bdf135348 346 uint32_t new_metres = ((uint32_t)recent_distance) / 1000;
JonFreeman 12:a25bdf135348 347 recent_distance -= (double)(new_metres * 1000);
JonFreeman 12:a25bdf135348 348 if (!odometer_update (new_metres, (uint16_t)electrical_power_Watt, (uint16_t)(volts * 500.0))) {
JonFreeman 12:a25bdf135348 349 pc.printf ("Probs with odometer_update");
JonFreeman 12:a25bdf135348 350 Controller_Error.set (FAULT_ODOMETER, 1);
JonFreeman 12:a25bdf135348 351 }
JonFreeman 12:a25bdf135348 352 rewrite_odometer () ; // Update text on speedo dial face
JonFreeman 4:67478861c670 353 } // endof if(qtr_sec > 3
JonFreeman 4:67478861c670 354 } // endof if (qtrsec_trig == true) {
JonFreeman 4:67478861c670 355 } // endof while(1) main programme loop
JonFreeman 12:a25bdf135348 356 } // endof main ()
JonFreeman 4:67478861c670 357