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
main.cpp@7:3b1f44cd4735, 2018-05-09 (annotated)
- Committer:
- JonFreeman
- Date:
- Wed May 09 15:42:43 2018 +0000
- Revision:
- 7:3b1f44cd4735
- Parent:
- 5:21a8ac83142c
- Child:
- 8:5945d506a872
Panic recovery from updating mbed lib causing total wipeout
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JonFreeman | 4:67478861c670 | 1 | /* |
JonFreeman | 4:67478861c670 | 2 | April 2018 - Jon Freeman |
JonFreeman | 4:67478861c670 | 3 | |
JonFreeman | 4:67478861c670 | 4 | Touch Screen controller communicates with 1, 2, ... n Twin BLDC Controller boards via opto-isolated serial port. |
JonFreeman | 4:67478861c670 | 5 | |
JonFreeman | 4:67478861c670 | 6 | 9 pid D connector retained but wiring NOT compatible with 2017. |
JonFreeman | 4:67478861c670 | 7 | This time pins are : - |
JonFreeman | 4:67478861c670 | 8 | 1 Not Used on TS2018, connection from Twin BLDC Controller only - Pot wiper |
JonFreeman | 4:67478861c670 | 9 | 2 Not Used on TS2018, connection from Twin BLDC Controller only - GND |
JonFreeman | 4:67478861c670 | 10 | 3 Not Used on TS2018, connection from Twin BLDC Controller only - Weak +5 (top of pot) |
JonFreeman | 4:67478861c670 | 11 | 4 Not Used on TS2018, connection from Twin BLDC Controller only - Possible Fwd / Rev switched between pins 2 and 3 above |
JonFreeman | 4:67478861c670 | 12 | 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 | 13 | 6 Twin BLDC Rx- <- TS2018 Tx data ||GND to avoid exposing TS +5v rail to the outside world |
JonFreeman | 4:67478861c670 | 14 | 7 Twin BLDC Rx+ <- TS2018 +5v ||Tx\ to avoid exposing TS +5v rail to the outside world, INVERTED Txd idles lo |
JonFreeman | 4:67478861c670 | 15 | 8 Twin BLDC Tx- <- TS2018 GND |
JonFreeman | 4:67478861c670 | 16 | 9 Twin BLDC Tx+ <- TS2018 Rx data with 1k pullup to +5, line idles hi |
JonFreeman | 4:67478861c670 | 17 | */ |
adustm | 0:99e26e18b424 | 18 | #include "mbed.h" |
JonFreeman | 4:67478861c670 | 19 | #include "Electric_Loco.h" |
JonFreeman | 5:21a8ac83142c | 20 | #include "AsyncSerial.hpp" |
JonFreeman | 5:21a8ac83142c | 21 | #include "Servo.h" |
JonFreeman | 4:67478861c670 | 22 | #include "TS_DISCO_F746NG.h" |
JonFreeman | 4:67478861c670 | 23 | #include "LCD_DISCO_F746NG.h" |
JonFreeman | 5:21a8ac83142c | 24 | #include <cctype> |
JonFreeman | 7:3b1f44cd4735 | 25 | #include <cerrno> |
JonFreeman | 4:67478861c670 | 26 | |
JonFreeman | 4:67478861c670 | 27 | LCD_DISCO_F746NG lcd; |
JonFreeman | 4:67478861c670 | 28 | TS_DISCO_F746NG touch_screen; |
JonFreeman | 4:67478861c670 | 29 | |
JonFreeman | 5:21a8ac83142c | 30 | //FastPWM maxv (D12, 1), |
JonFreeman | 5:21a8ac83142c | 31 | // maxi (D11, 1); // pin, prescaler value |
JonFreeman | 5:21a8ac83142c | 32 | Serial pc (USBTX, USBRX); // AsyncSerial does not work here. Comms to 'PuTTY' or similar comms programme on pc |
JonFreeman | 4:67478861c670 | 33 | |
JonFreeman | 5:21a8ac83142c | 34 | DigitalOut reverse_pin (D7); // These pins no longer used to set mode and direction, now commands issued to com |
JonFreeman | 5:21a8ac83142c | 35 | DigitalOut forward_pin (D9); //was D6, these two decode to fwd, rev, regen_braking and park |
JonFreeman | 4:67478861c670 | 36 | |
JonFreeman | 5:21a8ac83142c | 37 | DigitalOut I_sink1 (D14); // a horn |
JonFreeman | 7:3b1f44cd4735 | 38 | DigitalOut I_sink2 (D15); // lamp |
JonFreeman | 7:3b1f44cd4735 | 39 | DigitalOut I_sink3 (D3); // lamp |
JonFreeman | 5:21a8ac83142c | 40 | DigitalOut I_sink4 (D4); |
JonFreeman | 5:21a8ac83142c | 41 | DigitalOut I_sink5 (D5); |
JonFreeman | 5:21a8ac83142c | 42 | DigitalOut led_grn (LED1); // the only on board user led |
JonFreeman | 4:67478861c670 | 43 | |
JonFreeman | 5:21a8ac83142c | 44 | DigitalIn f_r_switch (D2); // was D0, Reads position of centre-off ignition switch |
JonFreeman | 4:67478861c670 | 45 | //DigitalIn spareio_d8 (D8); |
JonFreeman | 5:21a8ac83142c | 46 | //DigitalIn spareio_d9 (D9); |
JonFreeman | 4:67478861c670 | 47 | DigitalIn spareio_d10 (D10); // D8, D9, D10 wired to jumper on pcb - not used to Apr 2017 |
JonFreeman | 4:67478861c670 | 48 | |
JonFreeman | 4:67478861c670 | 49 | AnalogIn ht_volts_ain (A0); // Jan 2017 |
JonFreeman | 4:67478861c670 | 50 | AnalogIn ht_amps_ain (A1); // Jan 2017 |
JonFreeman | 5:21a8ac83142c | 51 | //AnalogIn spare_ain2 (A2); |
JonFreeman | 5:21a8ac83142c | 52 | //AnalogIn spare_ain3 (A3); |
JonFreeman | 4:67478861c670 | 53 | //AnalogIn spare_ain4 (A4); // hardware on pcb for these 3 spare analogue inputs - not used to Apr 2017 |
JonFreeman | 4:67478861c670 | 54 | //AnalogIn spare_ain5 (A5); // causes display flicker ! |
JonFreeman | 5:21a8ac83142c | 55 | |
JonFreeman | 5:21a8ac83142c | 56 | |
JonFreeman | 5:21a8ac83142c | 57 | AsyncSerial com (A4, A5); // Com port to opto isolators on Twin BLDC Controller boards |
JonFreeman | 5:21a8ac83142c | 58 | //AsyncSerial ir (D1, D0); // Second port does work, but gives the old broken-up display flicker nonsense problem |
JonFreeman | 4:67478861c670 | 59 | |
JonFreeman | 5:21a8ac83142c | 60 | Servo servo1 (D6); // Now used to adjust Honda speed |
JonFreeman | 5:21a8ac83142c | 61 | |
JonFreeman | 7:3b1f44cd4735 | 62 | extern uint32_t odometer_out () ; // Read latest total of metres travelled ever |
JonFreeman | 4:67478861c670 | 63 | extern bool odometer_zero () ; // Returns true on success |
JonFreeman | 4:67478861c670 | 64 | 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 | 65 | |
JonFreeman | 4:67478861c670 | 66 | extern int get_button_press (struct point & pt) ; |
JonFreeman | 4:67478861c670 | 67 | extern void displaytext (int x, int y, const int font, uint32_t BCol, uint32_t TCol, char * txt) ; |
JonFreeman | 4:67478861c670 | 68 | extern void displaytext (int x, int y, const int font, char * txt) ; |
JonFreeman | 4:67478861c670 | 69 | extern void displaytext (int x, int y, char * txt) ; |
JonFreeman | 4:67478861c670 | 70 | extern void setup_buttons () ; |
JonFreeman | 4:67478861c670 | 71 | extern void draw_numeric_keypad (int colour) ; |
JonFreeman | 4:67478861c670 | 72 | extern void draw_button_hilight (int bu, int colour) ; |
JonFreeman | 4:67478861c670 | 73 | extern void read_presses (int * a) ; |
JonFreeman | 4:67478861c670 | 74 | extern void read_keypresses (struct ky_bd & a) ; |
JonFreeman | 4:67478861c670 | 75 | extern void SliderGraphic (struct slide & q) ; |
JonFreeman | 4:67478861c670 | 76 | extern void vm_set () ; |
JonFreeman | 4:67478861c670 | 77 | extern void update_meters (double, double, double) ; |
JonFreeman | 4:67478861c670 | 78 | |
JonFreeman | 7:3b1f44cd4735 | 79 | extern void setup_pccom () ; |
JonFreeman | 7:3b1f44cd4735 | 80 | extern void setup_lococom () ; |
JonFreeman | 7:3b1f44cd4735 | 81 | extern void clicore (struct parameters & a) ; |
JonFreeman | 7:3b1f44cd4735 | 82 | extern struct parameters pccom, lococom; |
JonFreeman | 7:3b1f44cd4735 | 83 | |
JonFreeman | 4:67478861c670 | 84 | static const int |
JonFreeman | 4:67478861c670 | 85 | DAMPER_DECAY = 42, // Small num -> fast 'viscous damper' on dead-mans function with finger removed from panel |
JonFreeman | 4:67478861c670 | 86 | MAF_PTS = 140, // Moving Average Filter points. Filters reduce noise on volatage and current readings |
JonFreeman | 4:67478861c670 | 87 | FWD = 0, |
JonFreeman | 4:67478861c670 | 88 | REV = ~FWD; |
JonFreeman | 4:67478861c670 | 89 | |
JonFreeman | 4:67478861c670 | 90 | //from .h struct slide { int position; int oldpos; int state; int direction; bool recalc_run; bool handbrake_slipping; double handbrake_effort; double loco_speed } ; |
JonFreeman | 4:67478861c670 | 91 | struct slide slider ; |
JonFreeman | 4:67478861c670 | 92 | |
adustm | 0:99e26e18b424 | 93 | |
JonFreeman | 4:67478861c670 | 94 | int V_maf[MAF_PTS + 2], I_maf[MAF_PTS + 2], maf_ptr = 0; // ********* These should be uint16_t |
JonFreeman | 5:21a8ac83142c | 95 | uint32_t sys_timer_32Hz = 0; |
JonFreeman | 5:21a8ac83142c | 96 | double last_V = 0.0, last_I = 0.0, recent_distance = 0.0; |
JonFreeman | 4:67478861c670 | 97 | |
JonFreeman | 4:67478861c670 | 98 | bool qtrsec_trig = false; |
JonFreeman | 4:67478861c670 | 99 | bool trigger_current_read = false; |
JonFreeman | 4:67478861c670 | 100 | volatile bool trigger_32ms = false; |
JonFreeman | 4:67478861c670 | 101 | |
JonFreeman | 5:21a8ac83142c | 102 | class speed_2018 |
JonFreeman | 4:67478861c670 | 103 | { |
JonFreeman | 5:21a8ac83142c | 104 | static const int SPEED_AVE_PTS = 5; // AVE_PTS - points in moving average filters |
JonFreeman | 7:3b1f44cd4735 | 105 | uint32_t speed_maf_mem [(SPEED_AVE_PTS + 1) * 2][8], // Allow for up to 8 axles |
JonFreeman | 7:3b1f44cd4735 | 106 | axle_total [8], // allow up to 8 axles |
JonFreeman | 7:3b1f44cd4735 | 107 | mafptr, |
JonFreeman | 7:3b1f44cd4735 | 108 | board_IDs [4], // allow up to 4 boards |
JonFreeman | 7:3b1f44cd4735 | 109 | board_count, |
JonFreeman | 7:3b1f44cd4735 | 110 | b, reqno; |
JonFreeman | 4:67478861c670 | 111 | public: |
JonFreeman | 5:21a8ac83142c | 112 | speed_2018 () { // Constructor |
JonFreeman | 4:67478861c670 | 113 | memset(speed_maf_mem, 0, sizeof(speed_maf_mem)); |
JonFreeman | 7:3b1f44cd4735 | 114 | for (int i = 0; i < sizeof(axle_total) / sizeof(uint32_t); i++) |
JonFreeman | 7:3b1f44cd4735 | 115 | axle_total[i] = 0; |
JonFreeman | 4:67478861c670 | 116 | mafptr = 0; |
JonFreeman | 7:3b1f44cd4735 | 117 | board_count = 0; |
JonFreeman | 7:3b1f44cd4735 | 118 | b = 0; |
JonFreeman | 7:3b1f44cd4735 | 119 | reqno = 0; |
JonFreeman | 5:21a8ac83142c | 120 | } |
JonFreeman | 7:3b1f44cd4735 | 121 | bool request_rpm () ; |
JonFreeman | 5:21a8ac83142c | 122 | void rpm_update(struct parameters & a) ; |
JonFreeman | 7:3b1f44cd4735 | 123 | void set_board_IDs (uint32_t *) ; |
JonFreeman | 5:21a8ac83142c | 124 | double mph () ; |
JonFreeman | 4:67478861c670 | 125 | } |
JonFreeman | 7:3b1f44cd4735 | 126 | speed ; |
JonFreeman | 7:3b1f44cd4735 | 127 | |
JonFreeman | 7:3b1f44cd4735 | 128 | void speed_2018::set_board_IDs (uint32_t * a) { |
JonFreeman | 7:3b1f44cd4735 | 129 | board_count = 0; |
JonFreeman | 7:3b1f44cd4735 | 130 | while (a[board_count]) { |
JonFreeman | 7:3b1f44cd4735 | 131 | board_IDs[board_count] = a[board_count]; |
JonFreeman | 7:3b1f44cd4735 | 132 | board_count++; |
JonFreeman | 7:3b1f44cd4735 | 133 | } |
JonFreeman | 7:3b1f44cd4735 | 134 | pc.printf ("set_board_IDs %d\r\n", board_count); |
JonFreeman | 7:3b1f44cd4735 | 135 | } |
JonFreeman | 4:67478861c670 | 136 | |
JonFreeman | 5:21a8ac83142c | 137 | double speed_2018::mph () { |
JonFreeman | 7:3b1f44cd4735 | 138 | if (!board_count) { |
JonFreeman | 7:3b1f44cd4735 | 139 | // pc.printf ("No boards\r\n"); |
JonFreeman | 7:3b1f44cd4735 | 140 | return 0.0; |
JonFreeman | 7:3b1f44cd4735 | 141 | } |
JonFreeman | 7:3b1f44cd4735 | 142 | int t[8] = {0,0,0,0,0,0,0,0}; |
JonFreeman | 5:21a8ac83142c | 143 | for (int i = 0; i < SPEED_AVE_PTS; i++) { |
JonFreeman | 7:3b1f44cd4735 | 144 | for (int j = 0; j < board_count * 2; j++) |
JonFreeman | 7:3b1f44cd4735 | 145 | t[j] += speed_maf_mem[i][j]; |
JonFreeman | 4:67478861c670 | 146 | } |
JonFreeman | 5:21a8ac83142c | 147 | int j = 0; |
JonFreeman | 7:3b1f44cd4735 | 148 | for (int i = 0; i < board_count * 2; i++) { |
JonFreeman | 5:21a8ac83142c | 149 | j += t[i]; |
JonFreeman | 5:21a8ac83142c | 150 | axle_total[i] = t[i]; |
JonFreeman | 5:21a8ac83142c | 151 | } |
JonFreeman | 7:3b1f44cd4735 | 152 | return (rpm2mph * ((double) j) / (SPEED_AVE_PTS * board_count * 2)); |
JonFreeman | 7:3b1f44cd4735 | 153 | } |
JonFreeman | 7:3b1f44cd4735 | 154 | |
JonFreeman | 7:3b1f44cd4735 | 155 | bool speed_2018::request_rpm () { // Issue "'n'rpm\r" to BLDC board to request RPM |
JonFreeman | 7:3b1f44cd4735 | 156 | if (board_IDs[0] == 0) |
JonFreeman | 7:3b1f44cd4735 | 157 | return false; // No boards identified |
JonFreeman | 7:3b1f44cd4735 | 158 | if (board_IDs[reqno] == 0) |
JonFreeman | 7:3b1f44cd4735 | 159 | reqno = 0; |
JonFreeman | 7:3b1f44cd4735 | 160 | com.putc (board_IDs[reqno++]); |
JonFreeman | 7:3b1f44cd4735 | 161 | com.printf ("rpm\r"); |
JonFreeman | 7:3b1f44cd4735 | 162 | return true; |
JonFreeman | 4:67478861c670 | 163 | } |
JonFreeman | 4:67478861c670 | 164 | |
JonFreeman | 5:21a8ac83142c | 165 | void speed_2018::rpm_update(struct parameters & a) { // Puts new readings into mem |
JonFreeman | 7:3b1f44cd4735 | 166 | speed_maf_mem [mafptr][b++] = (uint32_t)a.dbl[0]; |
JonFreeman | 7:3b1f44cd4735 | 167 | speed_maf_mem [mafptr][b++] = (uint32_t)a.dbl[1]; |
JonFreeman | 7:3b1f44cd4735 | 168 | if ((b + 1) >= (board_count * 2)) { |
JonFreeman | 7:3b1f44cd4735 | 169 | b = 0; |
JonFreeman | 5:21a8ac83142c | 170 | mafptr++; |
JonFreeman | 7:3b1f44cd4735 | 171 | if (mafptr >= SPEED_AVE_PTS) |
JonFreeman | 5:21a8ac83142c | 172 | mafptr = 0; |
JonFreeman | 4:67478861c670 | 173 | } |
JonFreeman | 4:67478861c670 | 174 | } |
JonFreeman | 4:67478861c670 | 175 | |
JonFreeman | 5:21a8ac83142c | 176 | |
JonFreeman | 5:21a8ac83142c | 177 | void rpm_push (struct parameters & a) { // Latest RPM reports from Dual BLDC Motor Controllers arrive here |
JonFreeman | 7:3b1f44cd4735 | 178 | speed.rpm_update (a); |
JonFreeman | 5:21a8ac83142c | 179 | // pc.printf ("RPM%d %d, mph %.1f\r\n", (int)a.dbl[0], (int)a.dbl[1], speed2.mph()); |
JonFreeman | 4:67478861c670 | 180 | } |
adustm | 0:99e26e18b424 | 181 | |
JonFreeman | 4:67478861c670 | 182 | |
JonFreeman | 4:67478861c670 | 183 | |
JonFreeman | 4:67478861c670 | 184 | void set_V_limit (double p) // Sets max motor voltage |
JonFreeman | 4:67478861c670 | 185 | { |
JonFreeman | 4:67478861c670 | 186 | if (p < 0.0) |
JonFreeman | 4:67478861c670 | 187 | p = 0.0; |
JonFreeman | 4:67478861c670 | 188 | if (p > 1.0) |
JonFreeman | 4:67478861c670 | 189 | p = 1.0; |
JonFreeman | 5:21a8ac83142c | 190 | last_V = p; |
JonFreeman | 5:21a8ac83142c | 191 | com.printf ("v%d\r", (int)(p * 99.0)); |
JonFreeman | 4:67478861c670 | 192 | } |
JonFreeman | 4:67478861c670 | 193 | |
JonFreeman | 4:67478861c670 | 194 | void set_I_limit (double p) // Sets max motor current |
JonFreeman | 4:67478861c670 | 195 | { |
JonFreeman | 4:67478861c670 | 196 | if (p < 0.0) |
JonFreeman | 4:67478861c670 | 197 | p = 0.0; |
JonFreeman | 4:67478861c670 | 198 | if (p > 1.0) |
JonFreeman | 4:67478861c670 | 199 | p = 1.0; |
JonFreeman | 5:21a8ac83142c | 200 | last_I = p; // New 30/4/2018 ; no use for this yet, included to be consistent with V |
JonFreeman | 5:21a8ac83142c | 201 | com.printf ("i%d\r", (int)(p * 99.0)); |
JonFreeman | 4:67478861c670 | 202 | } |
JonFreeman | 4:67478861c670 | 203 | |
JonFreeman | 4:67478861c670 | 204 | double read_ammeter () |
JonFreeman | 4:67478861c670 | 205 | { |
JonFreeman | 7:3b1f44cd4735 | 206 | int32_t a = 0; |
JonFreeman | 4:67478861c670 | 207 | for (int b = 0; b < MAF_PTS; b++) |
JonFreeman | 4:67478861c670 | 208 | a += I_maf[b]; |
JonFreeman | 4:67478861c670 | 209 | a /= MAF_PTS; |
JonFreeman | 7:3b1f44cd4735 | 210 | a -= 0x4000; |
JonFreeman | 7:3b1f44cd4735 | 211 | double i = (double) (0 - a); |
JonFreeman | 7:3b1f44cd4735 | 212 | return i / 200.0; // Fiddled to get current reading close enough |
JonFreeman | 4:67478861c670 | 213 | } |
JonFreeman | 4:67478861c670 | 214 | |
JonFreeman | 4:67478861c670 | 215 | double read_voltmeter () |
JonFreeman | 4:67478861c670 | 216 | { |
JonFreeman | 4:67478861c670 | 217 | int a = 0; |
JonFreeman | 4:67478861c670 | 218 | for (int b = 0; b < MAF_PTS; b++) |
JonFreeman | 4:67478861c670 | 219 | a += V_maf[b]; |
JonFreeman | 4:67478861c670 | 220 | a /= MAF_PTS; |
JonFreeman | 5:21a8ac83142c | 221 | double v = (double) a; |
JonFreeman | 5:21a8ac83142c | 222 | return (v / 932.0) + 0.0; // fiddled to suit resistor values |
JonFreeman | 4:67478861c670 | 223 | } |
JonFreeman | 4:67478861c670 | 224 | |
JonFreeman | 4:67478861c670 | 225 | // Interrupt Service Routines |
JonFreeman | 4:67478861c670 | 226 | |
JonFreeman | 4:67478861c670 | 227 | void ISR_current_reader (void) // FIXED at 250us |
JonFreeman | 4:67478861c670 | 228 | { |
JonFreeman | 4:67478861c670 | 229 | static int ms32 = 0, ms250 = 0; |
JonFreeman | 4:67478861c670 | 230 | trigger_current_read = true; // every 250us, i.e. 4kHz NOTE only sets trigger here, readings taken in main loop |
JonFreeman | 4:67478861c670 | 231 | ms32++; |
JonFreeman | 5:21a8ac83142c | 232 | if (ms32 > 124) { // 31.25ms, not 32ms, is 32Hz |
JonFreeman | 4:67478861c670 | 233 | ms32 = 0; |
JonFreeman | 5:21a8ac83142c | 234 | sys_timer_32Hz++; // , usable anywhere as general measure of elapsed time |
JonFreeman | 4:67478861c670 | 235 | trigger_32ms = true; |
JonFreeman | 4:67478861c670 | 236 | ms250++; |
JonFreeman | 4:67478861c670 | 237 | if (ms250 > 7) { |
JonFreeman | 4:67478861c670 | 238 | ms250 = 0; |
JonFreeman | 4:67478861c670 | 239 | qtrsec_trig = true; |
JonFreeman | 4:67478861c670 | 240 | } |
JonFreeman | 4:67478861c670 | 241 | } |
JonFreeman | 4:67478861c670 | 242 | } |
JonFreeman | 4:67478861c670 | 243 | |
JonFreeman | 4:67478861c670 | 244 | // End of Interrupt Service Routines |
JonFreeman | 4:67478861c670 | 245 | |
JonFreeman | 4:67478861c670 | 246 | |
JonFreeman | 4:67478861c670 | 247 | bool inlist (struct ky_bd & a, int key) |
JonFreeman | 4:67478861c670 | 248 | { |
JonFreeman | 4:67478861c670 | 249 | int i = 0; |
JonFreeman | 4:67478861c670 | 250 | while (i < a.count) { |
JonFreeman | 4:67478861c670 | 251 | if (key == a.ky[i].keynum) |
JonFreeman | 4:67478861c670 | 252 | return true; |
JonFreeman | 4:67478861c670 | 253 | i++; |
JonFreeman | 4:67478861c670 | 254 | } |
JonFreeman | 4:67478861c670 | 255 | return false; |
JonFreeman | 4:67478861c670 | 256 | } |
JonFreeman | 4:67478861c670 | 257 | |
JonFreeman | 4:67478861c670 | 258 | |
JonFreeman | 4:67478861c670 | 259 | void stuff_to_do_every_250us () // Take readings of system voltage and current |
JonFreeman | 4:67478861c670 | 260 | { |
JonFreeman | 4:67478861c670 | 261 | if (!trigger_current_read) |
JonFreeman | 4:67478861c670 | 262 | return; |
JonFreeman | 4:67478861c670 | 263 | trigger_current_read = false; |
JonFreeman | 5:21a8ac83142c | 264 | int ch; |
JonFreeman | 5:21a8ac83142c | 265 | ch++; |
JonFreeman | 7:3b1f44cd4735 | 266 | I_maf[maf_ptr] = ht_amps_ain.read_u16(); // Read ACS709 ammeter module |
JonFreeman | 7:3b1f44cd4735 | 267 | V_maf[maf_ptr] = ht_volts_ain.read_u16(); // Read system voltage |
JonFreeman | 4:67478861c670 | 268 | maf_ptr++; |
JonFreeman | 4:67478861c670 | 269 | if (maf_ptr > MAF_PTS - 1) |
JonFreeman | 4:67478861c670 | 270 | maf_ptr = 0; |
JonFreeman | 4:67478861c670 | 271 | } |
JonFreeman | 4:67478861c670 | 272 | |
JonFreeman | 4:67478861c670 | 273 | void set_run_mode (int mode) |
JonFreeman | 4:67478861c670 | 274 | { // NOTE Nov 2017 - Handbrake not implemented |
JonFreeman | 4:67478861c670 | 275 | if (mode == HANDBRAKE_SLIPPING) slider.handbrake_slipping = true; |
JonFreeman | 4:67478861c670 | 276 | else slider.handbrake_slipping = false; |
JonFreeman | 4:67478861c670 | 277 | switch (mode) { |
JonFreeman | 4:67478861c670 | 278 | // STATES, INACTIVE, RUN, NEUTRAL_DRIFT, REGEN_BRAKE, PARK}; |
JonFreeman | 4:67478861c670 | 279 | // case HANDBRAKE_SLIPPING: |
JonFreeman | 4:67478861c670 | 280 | // break; |
JonFreeman | 4:67478861c670 | 281 | case PARK: // PARKED new rom code IS now finished. |
JonFreeman | 5:21a8ac83142c | 282 | // forward_pin = 0; |
JonFreeman | 5:21a8ac83142c | 283 | // reverse_pin = 0; |
JonFreeman | 4:67478861c670 | 284 | slider.state = mode; |
JonFreeman | 4:67478861c670 | 285 | set_V_limit (0.075); // was 0.1 |
JonFreeman | 4:67478861c670 | 286 | set_I_limit (slider.handbrake_effort); |
JonFreeman | 5:21a8ac83142c | 287 | // char tmp[16]; |
JonFreeman | 5:21a8ac83142c | 288 | // sprintf (tmp, "vi7 %d\r", (int)(slider.handbrake_effort * 99.0)); |
JonFreeman | 5:21a8ac83142c | 289 | // com.printf ("%s", tmp); |
JonFreeman | 4:67478861c670 | 290 | break; |
JonFreeman | 4:67478861c670 | 291 | case REGEN_BRAKE: // BRAKING, pwm affects degree |
JonFreeman | 5:21a8ac83142c | 292 | com.printf ("rb\r"); |
JonFreeman | 5:21a8ac83142c | 293 | // forward_pin = 1; |
JonFreeman | 5:21a8ac83142c | 294 | // reverse_pin = 1; |
JonFreeman | 4:67478861c670 | 295 | slider.state = mode; |
JonFreeman | 4:67478861c670 | 296 | break; |
JonFreeman | 4:67478861c670 | 297 | case NEUTRAL_DRIFT: |
JonFreeman | 4:67478861c670 | 298 | slider.state = mode; |
JonFreeman | 4:67478861c670 | 299 | set_I_limit (0.0); // added after first test runs, looking for cause of mechanical startup snatch |
JonFreeman | 4:67478861c670 | 300 | set_V_limit (0.0); // added after first test runs, looking for cause of mechanical startup snatch |
JonFreeman | 4:67478861c670 | 301 | break; |
JonFreeman | 4:67478861c670 | 302 | case RUN: |
JonFreeman | 4:67478861c670 | 303 | if (slider.direction) { |
JonFreeman | 5:21a8ac83142c | 304 | com.printf ("fw\r"); |
JonFreeman | 5:21a8ac83142c | 305 | // forward_pin = 0; |
JonFreeman | 5:21a8ac83142c | 306 | // reverse_pin = 1; |
JonFreeman | 4:67478861c670 | 307 | } else { |
JonFreeman | 5:21a8ac83142c | 308 | com.printf ("re\r"); |
JonFreeman | 5:21a8ac83142c | 309 | // forward_pin = 1; |
JonFreeman | 5:21a8ac83142c | 310 | // reverse_pin = 0; |
JonFreeman | 4:67478861c670 | 311 | } |
JonFreeman | 4:67478861c670 | 312 | slider.state = mode; |
JonFreeman | 4:67478861c670 | 313 | break; |
JonFreeman | 4:67478861c670 | 314 | default: |
JonFreeman | 4:67478861c670 | 315 | break; |
JonFreeman | 4:67478861c670 | 316 | } |
JonFreeman | 4:67478861c670 | 317 | } |
JonFreeman | 4:67478861c670 | 318 | |
JonFreeman | 4:67478861c670 | 319 | |
JonFreeman | 5:21a8ac83142c | 320 | void throttle (double p) { // New Apr 2018 ; servo adjusts throttle lever on Honda GX120 |
JonFreeman | 5:21a8ac83142c | 321 | const double THR_MAX = 0.92; |
JonFreeman | 5:21a8ac83142c | 322 | const double THR_MIN = 0.09; |
JonFreeman | 5:21a8ac83142c | 323 | const double RANGE = THR_MAX - THR_MIN; |
JonFreeman | 5:21a8ac83142c | 324 | if (p > 1.0) |
JonFreeman | 5:21a8ac83142c | 325 | p = 1.0; |
JonFreeman | 5:21a8ac83142c | 326 | if (p < 0.0) |
JonFreeman | 5:21a8ac83142c | 327 | p = 0.0; |
JonFreeman | 5:21a8ac83142c | 328 | // p = 1.0 - p; // if direction needs swapping |
JonFreeman | 5:21a8ac83142c | 329 | p *= RANGE; |
JonFreeman | 5:21a8ac83142c | 330 | p += THR_MIN; |
JonFreeman | 5:21a8ac83142c | 331 | servo1 = p; |
adustm | 0:99e26e18b424 | 332 | } |
adustm | 0:99e26e18b424 | 333 | |
JonFreeman | 5:21a8ac83142c | 334 | |
JonFreeman | 7:3b1f44cd4735 | 335 | void lights (int onoff) { |
JonFreeman | 7:3b1f44cd4735 | 336 | I_sink2 = onoff; // lamp right |
JonFreeman | 7:3b1f44cd4735 | 337 | I_sink3 = onoff; // lamp left |
JonFreeman | 7:3b1f44cd4735 | 338 | } |
JonFreeman | 4:67478861c670 | 339 | |
JonFreeman | 4:67478861c670 | 340 | int main() |
JonFreeman | 4:67478861c670 | 341 | { |
JonFreeman | 7:3b1f44cd4735 | 342 | errno = 0; |
JonFreeman | 7:3b1f44cd4735 | 343 | int qtr_sec = 0, seconds = 0, minutes = 0; |
JonFreeman | 7:3b1f44cd4735 | 344 | double electrical_power_Watt = 0.0; |
JonFreeman | 7:3b1f44cd4735 | 345 | ky_bd kybd_a, kybd_b; |
JonFreeman | 7:3b1f44cd4735 | 346 | memset (&kybd_a, 0, sizeof(kybd_a)); |
JonFreeman | 7:3b1f44cd4735 | 347 | memset (&kybd_b, 0, sizeof(kybd_b)); |
JonFreeman | 7:3b1f44cd4735 | 348 | pc.baud (9600); |
JonFreeman | 7:3b1f44cd4735 | 349 | com.baud (19200); |
JonFreeman | 7:3b1f44cd4735 | 350 | pc.printf ("\r\n\n\nLoco_TS_2018 Loco Controller starting, testing qspi mem, errno %d\r\n", errno); |
JonFreeman | 7:3b1f44cd4735 | 351 | // ir.baud (1200); |
JonFreeman | 7:3b1f44cd4735 | 352 | pc.printf ("Ln 352 errno %d\r\n", errno); |
JonFreeman | 7:3b1f44cd4735 | 353 | |
JonFreeman | 7:3b1f44cd4735 | 354 | I_sink1 = 0; // turn outputs off |
JonFreeman | 7:3b1f44cd4735 | 355 | I_sink2 = 0; // lamp right |
JonFreeman | 7:3b1f44cd4735 | 356 | pc.printf ("Ln 355 errno %d\r\n", errno); |
JonFreeman | 7:3b1f44cd4735 | 357 | I_sink3 = 0; // lamp left |
JonFreeman | 7:3b1f44cd4735 | 358 | I_sink4 = 0; |
JonFreeman | 7:3b1f44cd4735 | 359 | I_sink5 = 0; |
JonFreeman | 7:3b1f44cd4735 | 360 | pc.printf ("Ln 358 errno %d\r\n", errno); |
JonFreeman | 7:3b1f44cd4735 | 361 | // spareio_d8.mode (PullUp); now output driving throttle servo |
JonFreeman | 7:3b1f44cd4735 | 362 | // spareio_d9.mode (PullUp); |
JonFreeman | 7:3b1f44cd4735 | 363 | spareio_d10.mode(PullUp); |
JonFreeman | 7:3b1f44cd4735 | 364 | |
JonFreeman | 7:3b1f44cd4735 | 365 | Ticker tick250us; |
JonFreeman | 7:3b1f44cd4735 | 366 | |
JonFreeman | 7:3b1f44cd4735 | 367 | pc.printf ("Ln 365 errno %d\r\n", errno); |
JonFreeman | 7:3b1f44cd4735 | 368 | // Setup User Interrupt Vectors |
JonFreeman | 7:3b1f44cd4735 | 369 | tick250us.attach_us (&ISR_current_reader, 250); // count 125 of these to trig 31.25ms |
JonFreeman | 7:3b1f44cd4735 | 370 | // tick32ms.attach_us (&ISR_tick_32ms, 32001); |
JonFreeman | 7:3b1f44cd4735 | 371 | // tick32ms.attach_us (&ISR_tick_32ms, 31250); // then count 8 pulses per 250ms |
JonFreeman | 7:3b1f44cd4735 | 372 | // tick250ms.attach_us (&ISR_tick_250ms, 250002); |
JonFreeman | 4:67478861c670 | 373 | #ifdef QSPI |
JonFreeman | 4:67478861c670 | 374 | |
JonFreeman | 4:67478861c670 | 375 | extern int qspifindfree (uint8_t* dest, uint32_t addr) ; |
JonFreeman | 4:67478861c670 | 376 | extern int ask_QSPI_OK () ; |
JonFreeman | 4:67478861c670 | 377 | extern bool qspimemcheck () ; |
JonFreeman | 4:67478861c670 | 378 | extern int qspiinit () ; |
JonFreeman | 7:3b1f44cd4735 | 379 | pc.printf ("Before ask_QSPI_OK errno %d\r\n", errno); |
JonFreeman | 4:67478861c670 | 380 | int qspi_ok = ask_QSPI_OK (); |
JonFreeman | 7:3b1f44cd4735 | 381 | pc.printf ("After ask_QSPI_OK errno %d\r\n", errno); |
JonFreeman | 4:67478861c670 | 382 | //extern int qspieraseblock (uint32_t addr) ; |
JonFreeman | 4:67478861c670 | 383 | //extern int qspiwr (uint8_t* src, uint32_t addr) ; |
JonFreeman | 4:67478861c670 | 384 | //extern int qspiwr (uint8_t* src, uint32_t addr, uint32_t len) ; |
JonFreeman | 4:67478861c670 | 385 | //extern int qspird (uint8_t* dest, uint32_t addr, uint32_t len) ; |
JonFreeman | 4:67478861c670 | 386 | |
JonFreeman | 4:67478861c670 | 387 | //#define BUFFER_SIZE ((uint32_t)32) |
JonFreeman | 4:67478861c670 | 388 | //#define QSPI_BUFFER_SIZE ((uint32_t)4270) // Big enough for 4096 byte block |
JonFreeman | 4:67478861c670 | 389 | //#define WRITE_READ_ADDR ((uint32_t)0x0050) |
JonFreeman | 4:67478861c670 | 390 | //#define WRITE_READ_ADDR ((uint32_t)0x0010) |
JonFreeman | 4:67478861c670 | 391 | //#define WRITE_READ_ADDR2 ((uint32_t)0x0020) |
JonFreeman | 4:67478861c670 | 392 | //#define WRITE_READ_ADDR3 ((uint32_t)0x4030) |
JonFreeman | 4:67478861c670 | 393 | //#define QSPI_BASE_ADDR ((uint32_t)0x90000000) |
JonFreeman | 4:67478861c670 | 394 | |
JonFreeman | 4:67478861c670 | 395 | // 123456789012345 |
JonFreeman | 4:67478861c670 | 396 | // uint8_t WriteBuffer[QSPI_BUFFER_SIZE] = "Hello World !!!\0"; |
JonFreeman | 4:67478861c670 | 397 | // uint8_t ReadBuffer[QSPI_BUFFER_SIZE]; |
JonFreeman | 4:67478861c670 | 398 | // const uint8_t MemInitString[] = "Electric Locomotive Controller - Jon Freeman B. Eng. Hons - November 2017\0"; |
JonFreeman | 4:67478861c670 | 399 | // const uint8_t Ifound_String[] = "I found the man sir, god I wish I hadn't!\0"; |
JonFreeman | 4:67478861c670 | 400 | |
JonFreeman | 4:67478861c670 | 401 | // pc.printf ("[%s]\r\n", MemInitString); |
JonFreeman | 4:67478861c670 | 402 | // pc.printf ("[%s]\r\n", Ifound_String); |
JonFreeman | 4:67478861c670 | 403 | // pc.printf("\n\nQSPI demo started\r\n"); |
JonFreeman | 4:67478861c670 | 404 | |
JonFreeman | 4:67478861c670 | 405 | // Check initialization |
JonFreeman | 7:3b1f44cd4735 | 406 | pc.printf ("errno %d, qspi mem ", errno); |
JonFreeman | 4:67478861c670 | 407 | if (qspiinit() != qspi_ok) |
JonFreeman | 4:67478861c670 | 408 | error("Initialization FAILED\r\n"); |
JonFreeman | 4:67478861c670 | 409 | else |
JonFreeman | 4:67478861c670 | 410 | pc.printf("Initialization PASSED\r\n"); |
JonFreeman | 4:67478861c670 | 411 | |
JonFreeman | 4:67478861c670 | 412 | // Check memory informations |
JonFreeman | 4:67478861c670 | 413 | if (!qspimemcheck ()) |
JonFreeman | 4:67478861c670 | 414 | pc.printf ("Problem with qspimemcheck\r\n"); |
JonFreeman | 4:67478861c670 | 415 | /* // Erase memory |
JonFreeman | 4:67478861c670 | 416 | qspieraseblock (WRITE_READ_ADDR); |
JonFreeman | 4:67478861c670 | 417 | qspieraseblock (WRITE_READ_ADDR2); |
JonFreeman | 4:67478861c670 | 418 | qspieraseblock (WRITE_READ_ADDR3); |
JonFreeman | 4:67478861c670 | 419 | qspieraseblock (0x02000); |
JonFreeman | 4:67478861c670 | 420 | // Write memory |
JonFreeman | 4:67478861c670 | 421 | qspiwr(WriteBuffer, WRITE_READ_ADDR); |
JonFreeman | 4:67478861c670 | 422 | qspird(ReadBuffer, WRITE_READ_ADDR, 20); |
JonFreeman | 4:67478861c670 | 423 | qspiwr((uint8_t*)"Oh what a joy it is.", 0x02000); |
JonFreeman | 4:67478861c670 | 424 | qspird(ReadBuffer, 0x02000, 20); |
JonFreeman | 4:67478861c670 | 425 | qspieraseblock (0x02000); |
JonFreeman | 4:67478861c670 | 426 | */ // Read memory |
JonFreeman | 4:67478861c670 | 427 | // if (qspi.Read(ReadBuffer, WRITE_READ_ADDR, 11) != QSPI_OK) |
JonFreeman | 4:67478861c670 | 428 | /* qspird(ReadBuffer, WRITE_READ_ADDR, 256); |
JonFreeman | 4:67478861c670 | 429 | qspird(ReadBuffer, WRITE_READ_ADDR + 1, 256); |
JonFreeman | 4:67478861c670 | 430 | qspird(ReadBuffer, 0, 256); |
JonFreeman | 4:67478861c670 | 431 | |
JonFreeman | 4:67478861c670 | 432 | // Jon's play with Write memory |
JonFreeman | 4:67478861c670 | 433 | qspiwr ((uint8_t*)MemInitString, WRITE_READ_ADDR2); |
JonFreeman | 4:67478861c670 | 434 | qspiwr ((uint8_t*)Ifound_String, WRITE_READ_ADDR3); |
JonFreeman | 4:67478861c670 | 435 | |
JonFreeman | 4:67478861c670 | 436 | qspird(ReadBuffer, 0, 256); // shows correct write of "Electric Locomotive Controller" after "Hello World !!!" |
JonFreeman | 4:67478861c670 | 437 | qspird(ReadBuffer, WRITE_READ_ADDR2, 250); |
JonFreeman | 4:67478861c670 | 438 | |
JonFreeman | 4:67478861c670 | 439 | qspird(ReadBuffer, WRITE_READ_ADDR3, 250); |
JonFreeman | 4:67478861c670 | 440 | pc.printf ("\r\r\r\n"); |
JonFreeman | 4:67478861c670 | 441 | qspiwr ((uint8_t*)"Today I have to pack the car full of all sorts of stuff including 7.25 gauge loco and take it up to Begbrook to show members of Bristol Society of Model and Experimental Engineers!", 2000); |
JonFreeman | 4:67478861c670 | 442 | qspird(ReadBuffer, 0, 4096); |
JonFreeman | 4:67478861c670 | 443 | |
JonFreeman | 4:67478861c670 | 444 | int pos = qspifindfree (ReadBuffer, 0); |
JonFreeman | 4:67478861c670 | 445 | pc.printf ("qspifindfree reports %d\r\n", pos); |
JonFreeman | 4:67478861c670 | 446 | */ |
JonFreeman | 4:67478861c670 | 447 | //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 | 448 | |
JonFreeman | 7:3b1f44cd4735 | 449 | pc.printf ("End of qspi setup, errno %d\r\n", errno); |
JonFreeman | 4:67478861c670 | 450 | #endif |
JonFreeman | 4:67478861c670 | 451 | |
JonFreeman | 7:3b1f44cd4735 | 452 | if (f_r_switch) { |
JonFreeman | 4:67478861c670 | 453 | slider.direction = FWD; // make decision from key switch position here |
JonFreeman | 7:3b1f44cd4735 | 454 | com.printf ("fw\r"); |
JonFreeman | 7:3b1f44cd4735 | 455 | } |
JonFreeman | 7:3b1f44cd4735 | 456 | else { |
JonFreeman | 4:67478861c670 | 457 | slider.direction = REV; // make decision from key switch position here |
JonFreeman | 7:3b1f44cd4735 | 458 | com.printf ("re\r"); |
JonFreeman | 7:3b1f44cd4735 | 459 | } |
JonFreeman | 4:67478861c670 | 460 | // max_pwm_ticks = SystemCoreClock / (2 * PWM_HZ); // prescaler min value is 2, or so it would seem. SystemCoreClock returns 216000000 on F746NG board |
JonFreeman | 5:21a8ac83142c | 461 | // maxv.period_ticks (MAX_PWM_TICKS + 1); // around 18 kHz |
JonFreeman | 5:21a8ac83142c | 462 | // maxi.period_ticks (MAX_PWM_TICKS + 1); |
JonFreeman | 4:67478861c670 | 463 | set_I_limit (0.0); |
JonFreeman | 4:67478861c670 | 464 | set_V_limit (0.0); |
JonFreeman | 5:21a8ac83142c | 465 | throttle (0.0); // Set revs to idle. Start engine and warm up before powering up control |
JonFreeman | 5:21a8ac83142c | 466 | setup_pccom (); |
JonFreeman | 5:21a8ac83142c | 467 | setup_lococom (); |
JonFreeman | 5:21a8ac83142c | 468 | pc.printf ("Jon's Touch Screen Loco 2018 sytem starting up %s\r\n", slider.direction ? "Forward":"Reverse"); |
JonFreeman | 4:67478861c670 | 469 | uint8_t lcd_status = touch_screen.Init(lcd.GetXSize(), lcd.GetYSize()); |
JonFreeman | 4:67478861c670 | 470 | if (lcd_status != TS_OK) { |
JonFreeman | 4:67478861c670 | 471 | lcd.Clear(LCD_COLOR_RED); |
JonFreeman | 4:67478861c670 | 472 | lcd.SetBackColor(LCD_COLOR_RED); |
JonFreeman | 4:67478861c670 | 473 | lcd.SetTextColor(LCD_COLOR_WHITE); |
JonFreeman | 4:67478861c670 | 474 | lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT FAIL", CENTER_MODE); |
JonFreeman | 4:67478861c670 | 475 | wait (20); |
JonFreeman | 4:67478861c670 | 476 | } else { |
JonFreeman | 4:67478861c670 | 477 | lcd.Clear(LCD_COLOR_DARKBLUE); |
JonFreeman | 4:67478861c670 | 478 | lcd.SetBackColor(LCD_COLOR_GREEN); |
JonFreeman | 4:67478861c670 | 479 | lcd.SetTextColor(LCD_COLOR_WHITE); |
JonFreeman | 4:67478861c670 | 480 | lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT OK", CENTER_MODE); |
JonFreeman | 4:67478861c670 | 481 | } |
JonFreeman | 4:67478861c670 | 482 | |
JonFreeman | 4:67478861c670 | 483 | lcd.SetFont(&Font16); |
JonFreeman | 4:67478861c670 | 484 | lcd.Clear(LCD_COLOR_LIGHTGRAY); |
JonFreeman | 4:67478861c670 | 485 | setup_buttons(); // draws buttons |
JonFreeman | 4:67478861c670 | 486 | |
JonFreeman | 4:67478861c670 | 487 | slider.oldpos = 0; |
JonFreeman | 4:67478861c670 | 488 | slider.loco_speed = 0.0; |
JonFreeman | 4:67478861c670 | 489 | slider.handbrake_effort = 0.1; |
JonFreeman | 4:67478861c670 | 490 | slider.position = MAX_POS - 2; // Low down in REGEN_BRAKE position - NOT to power-up in PARK |
JonFreeman | 4:67478861c670 | 491 | SliderGraphic (slider); // sets slider.state to value determined by slider.position |
JonFreeman | 4:67478861c670 | 492 | set_run_mode (REGEN_BRAKE); // sets slider.mode |
JonFreeman | 4:67478861c670 | 493 | |
JonFreeman | 4:67478861c670 | 494 | lcd.SetBackColor(LCD_COLOR_DARKBLUE); |
JonFreeman | 4:67478861c670 | 495 | |
JonFreeman | 4:67478861c670 | 496 | vm_set(); // Draw 3 analogue meter movements, speedo, voltmeter, ammeter |
JonFreeman | 4:67478861c670 | 497 | |
JonFreeman | 7:3b1f44cd4735 | 498 | // if (odometer_zero ()) |
JonFreeman | 7:3b1f44cd4735 | 499 | // pc.printf ("TRUE from odometer_zero\r\n"); |
JonFreeman | 7:3b1f44cd4735 | 500 | // else |
JonFreeman | 7:3b1f44cd4735 | 501 | // pc.printf ("FALSE from odometer_zero\r\n"); |
JonFreeman | 4:67478861c670 | 502 | double torque_req = 0.0; |
JonFreeman | 4:67478861c670 | 503 | bool toggle32ms = false; |
JonFreeman | 4:67478861c670 | 504 | // Main loop |
JonFreeman | 5:21a8ac83142c | 505 | |
JonFreeman | 7:3b1f44cd4735 | 506 | uint32_t boards_fitted[8], bfptr = 0; |
JonFreeman | 5:21a8ac83142c | 507 | for (int i = 0; i < 8; i++) |
JonFreeman | 5:21a8ac83142c | 508 | boards_fitted[i] = 0; |
JonFreeman | 5:21a8ac83142c | 509 | sys_timer_32Hz = 0; |
JonFreeman | 5:21a8ac83142c | 510 | |
JonFreeman | 5:21a8ac83142c | 511 | int last_digit = 0, board_cnt = 0, ch; |
JonFreeman | 5:21a8ac83142c | 512 | while (sys_timer_32Hz < 12) { // Sniff out system, discover motor controllers connected |
JonFreeman | 5:21a8ac83142c | 513 | while (!trigger_32ms) |
JonFreeman | 5:21a8ac83142c | 514 | // command_line_interpreter (); |
JonFreeman | 5:21a8ac83142c | 515 | clicore (pccom); |
JonFreeman | 5:21a8ac83142c | 516 | trigger_32ms = false; |
JonFreeman | 5:21a8ac83142c | 517 | if (sys_timer_32Hz < 11) { // issue "0who\r", "1who\r" ... "9who\r" |
JonFreeman | 5:21a8ac83142c | 518 | com.putc ((sys_timer_32Hz - 1) | '0'); |
JonFreeman | 5:21a8ac83142c | 519 | com.printf ("who\r"); |
JonFreeman | 5:21a8ac83142c | 520 | } |
JonFreeman | 5:21a8ac83142c | 521 | while (com.readable()) { |
JonFreeman | 5:21a8ac83142c | 522 | ch = com.getc(); |
JonFreeman | 5:21a8ac83142c | 523 | if (ch != '\r') { |
JonFreeman | 5:21a8ac83142c | 524 | if (isdigit(ch)) |
JonFreeman | 5:21a8ac83142c | 525 | last_digit = ch; |
JonFreeman | 5:21a8ac83142c | 526 | } |
JonFreeman | 5:21a8ac83142c | 527 | else { // got '\r' at end of line |
JonFreeman | 5:21a8ac83142c | 528 | if (isdigit(last_digit)) |
JonFreeman | 5:21a8ac83142c | 529 | boards_fitted[board_cnt++] = last_digit; |
JonFreeman | 5:21a8ac83142c | 530 | last_digit = 0; |
JonFreeman | 5:21a8ac83142c | 531 | } |
JonFreeman | 5:21a8ac83142c | 532 | } |
JonFreeman | 5:21a8ac83142c | 533 | } |
JonFreeman | 7:3b1f44cd4735 | 534 | |
JonFreeman | 7:3b1f44cd4735 | 535 | // boards_fitted[0] = '4'; |
JonFreeman | 7:3b1f44cd4735 | 536 | // boards_fitted[1] = '5'; |
JonFreeman | 7:3b1f44cd4735 | 537 | |
JonFreeman | 5:21a8ac83142c | 538 | while (boards_fitted[bfptr]) { // This works, identified BLDC Motor Controller board ID chars '0' to '9' listed in boards_fitted[] |
JonFreeman | 5:21a8ac83142c | 539 | pc.printf ("Board %c found\r\n", boards_fitted[bfptr++]); |
JonFreeman | 5:21a8ac83142c | 540 | } |
JonFreeman | 7:3b1f44cd4735 | 541 | speed.set_board_IDs (boards_fitted); // store number and IDs of Dual BLDC boards identified |
JonFreeman | 7:3b1f44cd4735 | 542 | bfptr = 0; |
JonFreeman | 5:21a8ac83142c | 543 | clicore (pccom); |
JonFreeman | 5:21a8ac83142c | 544 | pc.printf ("pcmenuitems %d, commenuitems %d\r\n", pccom.numof_menu_items, lococom.numof_menu_items); |
JonFreeman | 7:3b1f44cd4735 | 545 | // perror (strerror(errno)); |
JonFreeman | 5:21a8ac83142c | 546 | // Done setup, time to roll ! |
JonFreeman | 4:67478861c670 | 547 | |
JonFreeman | 7:3b1f44cd4735 | 548 | lights (1); // Headlights ON! |
JonFreeman | 7:3b1f44cd4735 | 549 | |
JonFreeman | 4:67478861c670 | 550 | while (1) { |
JonFreeman | 4:67478861c670 | 551 | |
JonFreeman | 4:67478861c670 | 552 | struct ky_bd * present_kybd, * previous_kybd; |
JonFreeman | 4:67478861c670 | 553 | bool sliderpress = false; |
JonFreeman | 5:21a8ac83142c | 554 | // command_line_interpreter () ; // Do any actions from command line via usb link |
JonFreeman | 5:21a8ac83142c | 555 | clicore (pccom); |
JonFreeman | 5:21a8ac83142c | 556 | |
JonFreeman | 4:67478861c670 | 557 | stuff_to_do_every_250us () ; |
JonFreeman | 4:67478861c670 | 558 | |
JonFreeman | 4:67478861c670 | 559 | if (trigger_32ms == true) { // Stuff to do every 32 milli secs |
JonFreeman | 4:67478861c670 | 560 | trigger_32ms = false; |
JonFreeman | 7:3b1f44cd4735 | 561 | clicore (lococom); |
JonFreeman | 4:67478861c670 | 562 | toggle32ms = !toggle32ms; |
JonFreeman | 4:67478861c670 | 563 | if (toggle32ms) { |
JonFreeman | 4:67478861c670 | 564 | present_kybd = &kybd_a; |
JonFreeman | 4:67478861c670 | 565 | previous_kybd = &kybd_b; |
JonFreeman | 4:67478861c670 | 566 | } else { |
JonFreeman | 4:67478861c670 | 567 | present_kybd = &kybd_b; |
JonFreeman | 4:67478861c670 | 568 | previous_kybd = &kybd_a; |
JonFreeman | 4:67478861c670 | 569 | } |
JonFreeman | 4:67478861c670 | 570 | read_keypresses (*present_kybd); |
JonFreeman | 4:67478861c670 | 571 | sliderpress = false; |
JonFreeman | 4:67478861c670 | 572 | slider.recalc_run = false; |
JonFreeman | 4:67478861c670 | 573 | int j = 0; |
JonFreeman | 4:67478861c670 | 574 | // if (present2->count > previous_kybd->count) pc.printf ("More presses\r\n"); |
JonFreeman | 4:67478861c670 | 575 | // if (present2->count < previous_kybd->count) pc.printf ("Fewer presses\r\n"); |
JonFreeman | 4:67478861c670 | 576 | if (present_kybd->count || previous_kybd->count) { // at least one key pressed this time or last time |
JonFreeman | 4:67478861c670 | 577 | int k; |
JonFreeman | 4:67478861c670 | 578 | double dbl; |
JonFreeman | 4:67478861c670 | 579 | // pc.printf ("Keys action may be required"); |
JonFreeman | 4:67478861c670 | 580 | // if key in present and ! in previous, found new key press to handle |
JonFreeman | 4:67478861c670 | 581 | // if key ! in present and in previous, found new key release to handle |
JonFreeman | 4:67478861c670 | 582 | if (inlist(*present_kybd, SLIDER)) { // Finger is on slider, so Update slider graphic here |
JonFreeman | 4:67478861c670 | 583 | sliderpress = true; |
JonFreeman | 4:67478861c670 | 584 | k = present_kybd->slider_y; // get position of finger on slider |
JonFreeman | 4:67478861c670 | 585 | if (slider.state == RUN && k != slider.position) // Finger has moved within RUN range |
JonFreeman | 4:67478861c670 | 586 | slider.recalc_run = true; |
JonFreeman | 5:21a8ac83142c | 587 | if (slider.state == RUN && k >= NEUTRAL_VAL) { // Finger has moved from RUN to BRAKE range |
JonFreeman | 4:67478861c670 | 588 | slider.position = k = NEUTRAL_VAL; // kill drive for rapid reaction to braking |
JonFreeman | 5:21a8ac83142c | 589 | throttle (0.0); |
JonFreeman | 5:21a8ac83142c | 590 | } |
JonFreeman | 4:67478861c670 | 591 | |
JonFreeman | 4:67478861c670 | 592 | else { // nice slow non-jerky glidey movement required |
JonFreeman | 4:67478861c670 | 593 | dbl = (double)(k - slider.position); |
JonFreeman | 4:67478861c670 | 594 | dbl /= 13.179; // Where did 13.179 come from ? |
JonFreeman | 4:67478861c670 | 595 | if (dbl < 0.0) |
JonFreeman | 4:67478861c670 | 596 | dbl -= 1.0; |
JonFreeman | 4:67478861c670 | 597 | if (dbl > 0.0) |
JonFreeman | 4:67478861c670 | 598 | dbl += 1.0; |
JonFreeman | 4:67478861c670 | 599 | slider.position += (int)dbl; |
JonFreeman | 4:67478861c670 | 600 | } |
JonFreeman | 4:67478861c670 | 601 | SliderGraphic (slider); // sets slider.state to value determined by slider.position |
JonFreeman | 4:67478861c670 | 602 | set_run_mode (slider.state); |
JonFreeman | 4:67478861c670 | 603 | draw_button_hilight (SLIDER, LCD_COLOR_YELLOW) ; |
JonFreeman | 4:67478861c670 | 604 | |
JonFreeman | 4:67478861c670 | 605 | if (slider.state == REGEN_BRAKE) { |
JonFreeman | 4:67478861c670 | 606 | double brake_effort = ((double)(slider.position - NEUTRAL_VAL) |
JonFreeman | 4:67478861c670 | 607 | / (double)(MAX_POS - NEUTRAL_VAL)); |
JonFreeman | 4:67478861c670 | 608 | // brake_effort normalised to range 0.0 to 1.0 |
JonFreeman | 4:67478861c670 | 609 | brake_effort *= 0.97; // upper limit to braking effort, observed effect before was quite fierce |
JonFreeman | 4:67478861c670 | 610 | pc.printf ("Brake effort %.2f\r\n", brake_effort); |
JonFreeman | 4:67478861c670 | 611 | /* set_pwm (brake_effort); */ |
JonFreeman | 4:67478861c670 | 612 | set_V_limit (sqrt(brake_effort)); // sqrt gives more linear feel to control |
JonFreeman | 4:67478861c670 | 613 | set_I_limit (1.0); |
JonFreeman | 5:21a8ac83142c | 614 | throttle (0.0); |
JonFreeman | 4:67478861c670 | 615 | } |
JonFreeman | 4:67478861c670 | 616 | } else { // pc.printf ("Slider not touched\r\n"); |
JonFreeman | 4:67478861c670 | 617 | } |
JonFreeman | 4:67478861c670 | 618 | |
JonFreeman | 4:67478861c670 | 619 | j = 0; |
JonFreeman | 4:67478861c670 | 620 | while (j < present_kybd->count) { // handle new key presses |
JonFreeman | 4:67478861c670 | 621 | k = present_kybd->ky[j++].keynum; |
JonFreeman | 4:67478861c670 | 622 | if (inlist(*present_kybd, k)) { |
JonFreeman | 4:67478861c670 | 623 | switch (k) { // Here for auto-repeat type key behaviour |
JonFreeman | 4:67478861c670 | 624 | case 21: // key is 'voltmeter' |
JonFreeman | 5:21a8ac83142c | 625 | // set_V_limit (last_V * 1.002 + 0.001); |
JonFreeman | 4:67478861c670 | 626 | break; |
JonFreeman | 4:67478861c670 | 627 | case 22: // key is 'ammeter' |
JonFreeman | 5:21a8ac83142c | 628 | // set_V_limit (last_V * 0.99); |
JonFreeman | 4:67478861c670 | 629 | break; |
JonFreeman | 4:67478861c670 | 630 | } // endof switch (k) |
JonFreeman | 4:67478861c670 | 631 | } // endof if (inlist(*present2, k)) { |
JonFreeman | 7:3b1f44cd4735 | 632 | if (inlist(*present_kybd, k) && !inlist(*previous_kybd, k)) { // New key press detected |
JonFreeman | 4:67478861c670 | 633 | pc.printf ("Handle Press %d\r\n", k); |
JonFreeman | 4:67478861c670 | 634 | draw_button_hilight (k, LCD_COLOR_YELLOW) ; |
JonFreeman | 4:67478861c670 | 635 | switch (k) { // Handle new touch screen button presses here - single action per press, not autorepeat |
JonFreeman | 4:67478861c670 | 636 | case SPEEDO_BUT: // |
JonFreeman | 4:67478861c670 | 637 | pc.printf ("Speedometer key pressed %d\r\n", k); |
JonFreeman | 4:67478861c670 | 638 | break; |
JonFreeman | 4:67478861c670 | 639 | case VMETER_BUT: // |
JonFreeman | 7:3b1f44cd4735 | 640 | // pc.printf ("Voltmeter key pressed %d\r\n", k); |
JonFreeman | 7:3b1f44cd4735 | 641 | I_sink5 = 1; // Turn on hi-horn |
JonFreeman | 4:67478861c670 | 642 | break; |
JonFreeman | 4:67478861c670 | 643 | case AMETER_BUT: // |
JonFreeman | 7:3b1f44cd4735 | 644 | // pc.printf ("Ammeter key pressed %d\r\n", k); |
JonFreeman | 7:3b1f44cd4735 | 645 | I_sink4 = 1; // Turn on lo-horn |
JonFreeman | 4:67478861c670 | 646 | break; |
JonFreeman | 4:67478861c670 | 647 | default: |
JonFreeman | 4:67478861c670 | 648 | pc.printf ("Unhandled keypress %d\r\n", k); |
JonFreeman | 4:67478861c670 | 649 | break; |
JonFreeman | 4:67478861c670 | 650 | } // endof switch (button) |
JonFreeman | 4:67478861c670 | 651 | } |
JonFreeman | 4:67478861c670 | 652 | } // endof while - handle new key presses |
JonFreeman | 4:67478861c670 | 653 | j = 0; |
JonFreeman | 4:67478861c670 | 654 | while (j < previous_kybd->count) { // handle new key releases |
JonFreeman | 4:67478861c670 | 655 | k = previous_kybd->ky[j++].keynum; |
JonFreeman | 4:67478861c670 | 656 | if (inlist(*previous_kybd, k) && !inlist(*present_kybd, k)) { |
JonFreeman | 4:67478861c670 | 657 | pc.printf ("Handle Release %d\r\n", k); |
JonFreeman | 4:67478861c670 | 658 | draw_button_hilight (k, LCD_COLOR_DARKBLUE) ; |
JonFreeman | 7:3b1f44cd4735 | 659 | switch (k) { // Handle new touch screen button RELEASes here - single action per press, not autorepeat |
JonFreeman | 7:3b1f44cd4735 | 660 | case SPEEDO_BUT: // |
JonFreeman | 7:3b1f44cd4735 | 661 | pc.printf ("Speedometer key released %d\r\n", k); |
JonFreeman | 7:3b1f44cd4735 | 662 | break; |
JonFreeman | 7:3b1f44cd4735 | 663 | case VMETER_BUT: // |
JonFreeman | 7:3b1f44cd4735 | 664 | I_sink5 = 0; // Turn hi-tone horn off |
JonFreeman | 7:3b1f44cd4735 | 665 | // pc.printf ("Voltmeter key released %d\r\n", k); |
JonFreeman | 7:3b1f44cd4735 | 666 | break; |
JonFreeman | 7:3b1f44cd4735 | 667 | case AMETER_BUT: // |
JonFreeman | 7:3b1f44cd4735 | 668 | I_sink4 = 0; // Turn lo-tone horn off |
JonFreeman | 7:3b1f44cd4735 | 669 | // pc.printf ("Ammeter key released %d\r\n", k); |
JonFreeman | 7:3b1f44cd4735 | 670 | break; |
JonFreeman | 7:3b1f44cd4735 | 671 | default: |
JonFreeman | 7:3b1f44cd4735 | 672 | pc.printf ("Unhandled keyreleas %d\r\n", k); |
JonFreeman | 7:3b1f44cd4735 | 673 | break; |
JonFreeman | 7:3b1f44cd4735 | 674 | } // endof switch (button) |
JonFreeman | 4:67478861c670 | 675 | } |
JonFreeman | 4:67478861c670 | 676 | } // endof while - handle new key releases |
JonFreeman | 4:67478861c670 | 677 | } // endof at least one key pressed this time or last time |
JonFreeman | 4:67478861c670 | 678 | |
JonFreeman | 4:67478861c670 | 679 | if (sliderpress == false) { // need to glide dead-mans function towards neutral here |
JonFreeman | 4:67478861c670 | 680 | if (slider.position < NEUTRAL_VAL) { |
JonFreeman | 4:67478861c670 | 681 | slider.position += 1 + (NEUTRAL_VAL - slider.position) / DAMPER_DECAY; |
JonFreeman | 4:67478861c670 | 682 | SliderGraphic (slider); |
JonFreeman | 4:67478861c670 | 683 | slider.recalc_run = true; |
JonFreeman | 4:67478861c670 | 684 | } |
JonFreeman | 4:67478861c670 | 685 | } |
JonFreeman | 4:67478861c670 | 686 | |
JonFreeman | 4:67478861c670 | 687 | if (slider.recalc_run) { // range of slider.position in RUN mode is min_pos_() to NEUTRAL_VAL - 1 |
JonFreeman | 4:67478861c670 | 688 | slider.recalc_run = false; // All RUN power and pwm calcs done here |
JonFreeman | 4:67478861c670 | 689 | int b = slider.position; |
JonFreeman | 4:67478861c670 | 690 | if (b > NEUTRAL_VAL) |
JonFreeman | 4:67478861c670 | 691 | b = NEUTRAL_VAL; |
JonFreeman | 4:67478861c670 | 692 | if (b < MIN_POS) // if finger position is above top of slider limit |
JonFreeman | 4:67478861c670 | 693 | b = MIN_POS; |
JonFreeman | 4:67478861c670 | 694 | b = NEUTRAL_VAL - b; // now got integer going positive for increasing power demand |
JonFreeman | 4:67478861c670 | 695 | torque_req = (double) b; |
JonFreeman | 4:67478861c670 | 696 | torque_req /= (NEUTRAL_VAL - MIN_POS); // in range 0.0 to 1.0 |
JonFreeman | 5:21a8ac83142c | 697 | pc.printf ("torque_rec = %.3f, last_V = %.3f\r\n", torque_req, last_V); |
JonFreeman | 4:67478861c670 | 698 | set_I_limit (torque_req); |
JonFreeman | 7:3b1f44cd4735 | 699 | if (torque_req < 0.05) { |
JonFreeman | 5:21a8ac83142c | 700 | set_V_limit (last_V / 2.0); |
JonFreeman | 7:3b1f44cd4735 | 701 | throttle (torque_req * 6.0); |
JonFreeman | 7:3b1f44cd4735 | 702 | } |
JonFreeman | 4:67478861c670 | 703 | else { |
JonFreeman | 7:3b1f44cd4735 | 704 | throttle (0.3 + (torque_req / 2.0)); |
JonFreeman | 5:21a8ac83142c | 705 | if (last_V < 0.99) |
JonFreeman | 5:21a8ac83142c | 706 | set_V_limit (last_V + 0.05); // ramp voltage up rather than slam to max |
JonFreeman | 4:67478861c670 | 707 | } |
JonFreeman | 4:67478861c670 | 708 | } |
JonFreeman | 4:67478861c670 | 709 | } // endof doing 32ms stuff |
JonFreeman | 4:67478861c670 | 710 | |
JonFreeman | 4:67478861c670 | 711 | if (qtrsec_trig == true) { // do every quarter second stuff here |
JonFreeman | 4:67478861c670 | 712 | qtrsec_trig = false; |
JonFreeman | 7:3b1f44cd4735 | 713 | double speedmph = speed.mph(), amps = read_ammeter(), volts = read_voltmeter(); |
JonFreeman | 4:67478861c670 | 714 | slider.loco_speed = speedmph; |
JonFreeman | 4:67478861c670 | 715 | electrical_power_Watt = volts * amps; // visible throughout main |
JonFreeman | 4:67478861c670 | 716 | update_meters (speedmph, electrical_power_Watt, volts) ; // displays speed, volts and power (volts times amps) |
JonFreeman | 4:67478861c670 | 717 | led_grn = !led_grn; |
JonFreeman | 4:67478861c670 | 718 | if (slider.state == PARK) { |
JonFreeman | 4:67478861c670 | 719 | if (speedmph > LOCO_HANDBRAKE_ESCAPE_SPEED / 4.0) { |
JonFreeman | 4:67478861c670 | 720 | slider.handbrake_effort *= 1.1; |
JonFreeman | 4:67478861c670 | 721 | if (slider.handbrake_effort > 0.55) slider.handbrake_effort = 0.55; |
JonFreeman | 4:67478861c670 | 722 | set_run_mode (PARK); |
JonFreeman | 4:67478861c670 | 723 | pc.printf ("Handbrake slipping, effort %.2f\r\n", slider.handbrake_effort); |
JonFreeman | 4:67478861c670 | 724 | } |
JonFreeman | 4:67478861c670 | 725 | if (speedmph < 0.02) { |
JonFreeman | 4:67478861c670 | 726 | slider.handbrake_effort *= 0.9; |
JonFreeman | 4:67478861c670 | 727 | if (slider.handbrake_effort < 0.05) slider.handbrake_effort = 0.05; |
JonFreeman | 4:67478861c670 | 728 | set_run_mode (PARK); |
JonFreeman | 4:67478861c670 | 729 | pc.printf ("Handbrake not slipping, effort %.2f\r\n", slider.handbrake_effort); |
JonFreeman | 4:67478861c670 | 730 | } |
JonFreeman | 4:67478861c670 | 731 | } |
JonFreeman | 7:3b1f44cd4735 | 732 | speed.request_rpm (); // issues "'n'rpm\r", takes care of cycling through available boards in sequence |
JonFreeman | 7:3b1f44cd4735 | 733 | // switch (qtr_sec) { // Can do sequential stuff quarter second apart here |
JonFreeman | 7:3b1f44cd4735 | 734 | // } // End of switch qtr_sec |
JonFreeman | 4:67478861c670 | 735 | qtr_sec++; |
JonFreeman | 4:67478861c670 | 736 | // Can do stuff once per second here |
JonFreeman | 4:67478861c670 | 737 | if(qtr_sec > 3) { |
JonFreeman | 4:67478861c670 | 738 | qtr_sec = 0; |
JonFreeman | 4:67478861c670 | 739 | seconds++; |
JonFreeman | 5:21a8ac83142c | 740 | com.printf ("kd\r"); // Kick the WatchDog timers in the Twin BLDC drive boards |
JonFreeman | 4:67478861c670 | 741 | if (seconds > 59) { |
JonFreeman | 4:67478861c670 | 742 | seconds = 0; |
JonFreeman | 4:67478861c670 | 743 | minutes++; |
JonFreeman | 4:67478861c670 | 744 | // do once per minute stuff here |
JonFreeman | 4:67478861c670 | 745 | } // fall back into once per second |
JonFreeman | 4:67478861c670 | 746 | #ifdef QSPI |
JonFreeman | 7:3b1f44cd4735 | 747 | |
JonFreeman | 7:3b1f44cd4735 | 748 | // recent_distance += 300; |
JonFreeman | 7:3b1f44cd4735 | 749 | |
JonFreeman | 7:3b1f44cd4735 | 750 | recent_distance += (speedmph * (111.76 * 4.0)); // Convert mph to distance mm travelled in one second |
JonFreeman | 7:3b1f44cd4735 | 751 | uint32_t new_metres = ((uint32_t)recent_distance) / 1000; |
JonFreeman | 7:3b1f44cd4735 | 752 | recent_distance -= (double)(new_metres * 1000); |
JonFreeman | 7:3b1f44cd4735 | 753 | if (!odometer_update (new_metres, (uint16_t)electrical_power_Watt, (uint16_t)(volts * 500.0))) |
JonFreeman | 7:3b1f44cd4735 | 754 | pc.printf ("Probs with odometer_update"); |
JonFreeman | 7:3b1f44cd4735 | 755 | char dist[20]; |
JonFreeman | 7:3b1f44cd4735 | 756 | sprintf (dist, "%05d m", odometer_out()); |
JonFreeman | 7:3b1f44cd4735 | 757 | displaytext (236, 226, 2, dist); |
JonFreeman | 7:3b1f44cd4735 | 758 | |
JonFreeman | 5:21a8ac83142c | 759 | /* |
JonFreeman | 5:21a8ac83142c | 760 | Odometer Update stuff now needs fixing to take updagte in form of mm travelled in previous period |
JonFreeman | 5:21a8ac83142c | 761 | |
JonFreeman | 4:67478861c670 | 762 | //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 | 7:3b1f44cd4735 | 763 | bool distance_measurement::update (uint32_t new_metres_travelled, uint16_t powr, uint16_t volt) { |
JonFreeman | 4:67478861c670 | 764 | if (!odometer_update (historic_distance, (uint16_t)electrical_power_Watt, (uint16_t)(volts * 500.0))) |
JonFreeman | 4:67478861c670 | 765 | pc.printf ("Probs with odometer_update"); |
JonFreeman | 4:67478861c670 | 766 | char dist[20]; |
JonFreeman | 5:21a8ac83142c | 767 | // sprintf (dist, "%05d m", speed.metres_travelled()); |
JonFreeman | 4:67478861c670 | 768 | displaytext (236, 226, 2, dist); |
JonFreeman | 5:21a8ac83142c | 769 | */ |
JonFreeman | 4:67478861c670 | 770 | #endif |
JonFreeman | 4:67478861c670 | 771 | // calc_motor_amps( mva); |
JonFreeman | 4:67478861c670 | 772 | } // endof if(qtr_sec > 3 |
JonFreeman | 4:67478861c670 | 773 | } // endof if (qtrsec_trig == true) { |
JonFreeman | 4:67478861c670 | 774 | } // endof while(1) main programme loop |
JonFreeman | 4:67478861c670 | 775 | } |
JonFreeman | 4:67478861c670 | 776 | |
JonFreeman | 4:67478861c670 | 777 | |
JonFreeman | 4:67478861c670 | 778 |