VR FabLab - RoboVal / Mbed 2 deprecated Chronometer_V2

Dependencies:   mbed keypadLib TextLCD

Committer:
peps
Date:
Sun May 20 23:19:17 2018 +0000
Revision:
3:fd1353986910
Parent:
2:bd0c735e81d6
Child:
4:23472c2b246b
Versione funzionante in doppia modalit?, selezionata tramite USER button.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ghiri 0:1a92e4a37697 1 //##############################################################
Ghiri 0:1a92e4a37697 2 //##
Ghiri 0:1a92e4a37697 3 //## Event: RoboVal - Robot Race
Ghiri 0:1a92e4a37697 4 //##
Ghiri 0:1a92e4a37697 5 //## Chronometer double use
Ghiri 0:1a92e4a37697 6 //##
Ghiri 0:1a92e4a37697 7 //## Version 1.99A
Ghiri 0:1a92e4a37697 8 //##
Ghiri 0:1a92e4a37697 9 //## Hardware platform used: ST NUCLEO-F401RE
Ghiri 0:1a92e4a37697 10 //##
Ghiri 0:1a92e4a37697 11 //## Software IDE used: mbed online version
Ghiri 0:1a92e4a37697 12 //##
Ghiri 0:1a92e4a37697 13 //## Organizzation: Verona FabLab
Ghiri 0:1a92e4a37697 14 //##
Ghiri 0:1a92e4a37697 15 //## Date creation: 2018.01.01
Ghiri 0:1a92e4a37697 16 //##
Ghiri 0:1a92e4a37697 17 //## Software developpers: FdF,GV, AG
Ghiri 0:1a92e4a37697 18 //##
Ghiri 0:1a92e4a37697 19 //## Base on original version of by FdF
Ghiri 0:1a92e4a37697 20 //##
Ghiri 0:1a92e4a37697 21 //##############################################################
Ghiri 0:1a92e4a37697 22
Ghiri 0:1a92e4a37697 23 #include <stdlib.h>
Ghiri 0:1a92e4a37697 24 #include "mbed.h"
Ghiri 0:1a92e4a37697 25 #include "TextLCD.h"
peps 2:bd0c735e81d6 26 #include "keypad.h"
peps 2:bd0c735e81d6 27
Ghiri 0:1a92e4a37697 28 // Default Number Lap
Ghiri 0:1a92e4a37697 29 #define NUM_LAP 3
Ghiri 0:1a92e4a37697 30
Ghiri 0:1a92e4a37697 31 // Reference for Low/Min Voltage battery
Ghiri 0:1a92e4a37697 32 #define VBAT_MIN 7.2
peps 2:bd0c735e81d6 33
peps 3:fd1353986910 34 // Different function modes
peps 3:fd1353986910 35 // Switch among them using the USER button
peps 3:fd1353986910 36 // (waiting for the keypad to work properly)
peps 2:bd0c735e81d6 37 enum modes {
peps 2:bd0c735e81d6 38 LABYRINTH,
peps 2:bd0c735e81d6 39 SPEED
peps 2:bd0c735e81d6 40 } mode = SPEED;
peps 2:bd0c735e81d6 41
peps 3:fd1353986910 42 // Human-readable time helper
peps 2:bd0c735e81d6 43 typedef struct time_screen {
peps 2:bd0c735e81d6 44 int cents;
peps 2:bd0c735e81d6 45 int seconds;
peps 2:bd0c735e81d6 46 int minutes;
peps 2:bd0c735e81d6 47 } measured_time;
peps 2:bd0c735e81d6 48
peps 2:bd0c735e81d6 49
peps 3:fd1353986910 50 // Keypad connection (4 columns, 4 rows)
peps 3:fd1353986910 51 Keypad keypad(PA_0 , PA_1 , PA_4 , PB_0, PA_13 , PA_14 , PC_2 , PC_3 );
Ghiri 1:26bcd89c18e5 52
Ghiri 1:26bcd89c18e5 53 // Configures the serial port
Ghiri 1:26bcd89c18e5 54 Serial pc( USBTX , USBRX );
Ghiri 1:26bcd89c18e5 55
peps 3:fd1353986910 56 // Heartbeat LED
Ghiri 0:1a92e4a37697 57 DigitalOut heartbeat(LED1);
Ghiri 0:1a92e4a37697 58
Ghiri 0:1a92e4a37697 59 // read Voltage battery, analog pin used PC_3 (Pin 37 of Morpho layout)
Ghiri 1:26bcd89c18e5 60 //AnalogIn vbat(PC_3);
Ghiri 0:1a92e4a37697 61
Ghiri 0:1a92e4a37697 62 // User button pressure
Ghiri 0:1a92e4a37697 63 InterruptIn user_button(USER_BUTTON);
Ghiri 0:1a92e4a37697 64
peps 3:fd1353986910 65 // Gates connected to digital input PA_15 and PB_7
peps 3:fd1353986910 66 InterruptIn gateStart(PA_15), gateEnd(PB_7);
Ghiri 0:1a92e4a37697 67
Ghiri 0:1a92e4a37697 68 // LCD Display (RS, E, D4, D5, D6, D7);
Ghiri 0:1a92e4a37697 69 TextLCD lcd(D2,D3,D4,D5,D6,D7);
peps 2:bd0c735e81d6 70
peps 3:fd1353986910 71 // Timer for the chrono function
peps 2:bd0c735e81d6 72 Timer t;
Ghiri 0:1a92e4a37697 73
peps 3:fd1353986910 74 // Number of laps
peps 3:fd1353986910 75 int lap = -1;
peps 3:fd1353986910 76 // Best lap
peps 3:fd1353986910 77 int best_lap = 0;
peps 3:fd1353986910 78 // Last time read
peps 2:bd0c735e81d6 79 int last_read = 0;
peps 3:fd1353986910 80 // Last lap time
peps 2:bd0c735e81d6 81 int lap_time = 0;
peps 3:fd1353986910 82 // Best lap time
peps 3:fd1353986910 83 int best_time = -1;
peps 3:fd1353986910 84 // Pointer to the loop function (depending on the selected mode)
peps 2:bd0c735e81d6 85 void (*loopMethod)(void);
peps 2:bd0c735e81d6 86
peps 2:bd0c735e81d6 87 //Conversione da millisecondi a mm:ss:cc
peps 2:bd0c735e81d6 88 measured_time human_read(int ms){
peps 2:bd0c735e81d6 89 measured_time read;
peps 2:bd0c735e81d6 90 div_t qr = div(ms,1000);
peps 2:bd0c735e81d6 91
peps 2:bd0c735e81d6 92 read.cents = qr.rem % 100;
peps 2:bd0c735e81d6 93
peps 2:bd0c735e81d6 94 qr = div(qr.quot,60);
peps 2:bd0c735e81d6 95 read.seconds = qr.rem;
peps 2:bd0c735e81d6 96
peps 2:bd0c735e81d6 97 qr = div(qr.quot,60);
peps 2:bd0c735e81d6 98 read.minutes = qr.rem;
peps 2:bd0c735e81d6 99
peps 2:bd0c735e81d6 100 return read;
peps 2:bd0c735e81d6 101 }
peps 2:bd0c735e81d6 102
peps 3:fd1353986910 103 // Invoked when startGate triggered.
peps 3:fd1353986910 104 // Start the timer or read the timer and store lap and best time
peps 3:fd1353986910 105 void measure_time() {
peps 2:bd0c735e81d6 106 int read = t.read_ms();
peps 3:fd1353986910 107
peps 3:fd1353986910 108 if(lap == -1){
peps 2:bd0c735e81d6 109 t.start();
peps 2:bd0c735e81d6 110 lap++;
peps 2:bd0c735e81d6 111 }else{
peps 2:bd0c735e81d6 112 //Dabouncing per evitare problemi
peps 2:bd0c735e81d6 113 if(read - last_read > 1000){
peps 2:bd0c735e81d6 114
peps 3:fd1353986910 115 lap++;
peps 2:bd0c735e81d6 116 lap_time = read - last_read;
peps 3:fd1353986910 117 if (best_time < 0 || lap_time < best_time) {
peps 3:fd1353986910 118 best_time = lap_time;
peps 3:fd1353986910 119 best_lap = lap;
peps 3:fd1353986910 120 }
peps 2:bd0c735e81d6 121
peps 3:fd1353986910 122 if(lap >= NUM_LAP) {
peps 2:bd0c735e81d6 123 t.stop();
peps 2:bd0c735e81d6 124 }
peps 2:bd0c735e81d6 125
peps 2:bd0c735e81d6 126 last_read = read;
peps 2:bd0c735e81d6 127 }
peps 3:fd1353986910 128 }
peps 2:bd0c735e81d6 129 }
peps 2:bd0c735e81d6 130
Ghiri 0:1a92e4a37697 131
peps 2:bd0c735e81d6 132 void speedLoop() {
peps 2:bd0c735e81d6 133 int read = t.read_ms();
peps 2:bd0c735e81d6 134
peps 2:bd0c735e81d6 135 measured_time time = human_read(read);
peps 2:bd0c735e81d6 136
peps 2:bd0c735e81d6 137 lcd.locate(0,0);
peps 2:bd0c735e81d6 138 lcd.printf("Totale %02d:%02d:%02d",time.minutes,time.seconds,time.cents);
peps 2:bd0c735e81d6 139
peps 2:bd0c735e81d6 140 //Gestione dei parziali
peps 3:fd1353986910 141 if(lap > 0) {
peps 2:bd0c735e81d6 142 time = human_read(lap_time);
peps 2:bd0c735e81d6 143 lcd.locate(0,1);
peps 3:fd1353986910 144 lcd.printf("Giro %d %02d:%02d:%02d",lap,time.minutes,time.seconds,time.cents);
peps 3:fd1353986910 145 }
peps 3:fd1353986910 146 if (lap >= NUM_LAP) {
peps 3:fd1353986910 147 time = human_read(best_time);
peps 3:fd1353986910 148 lcd.locate(0,1);
peps 3:fd1353986910 149 wait(1);
peps 3:fd1353986910 150 lcd.printf("Best %d %02d:%02d:%02d",best_lap,time.minutes,time.seconds,time.cents);
peps 3:fd1353986910 151 wait(1);
peps 2:bd0c735e81d6 152 }
peps 2:bd0c735e81d6 153 }
peps 2:bd0c735e81d6 154
peps 2:bd0c735e81d6 155 void start_time() {
peps 2:bd0c735e81d6 156 lap = 0;
peps 2:bd0c735e81d6 157 t.start();
peps 2:bd0c735e81d6 158 }
peps 2:bd0c735e81d6 159
peps 2:bd0c735e81d6 160 void stop_time() {
peps 2:bd0c735e81d6 161 lap = 1;
peps 2:bd0c735e81d6 162 t.stop();
peps 2:bd0c735e81d6 163 int read = t.read_ms();
peps 2:bd0c735e81d6 164
peps 2:bd0c735e81d6 165 measured_time time = human_read(read);
peps 2:bd0c735e81d6 166
peps 3:fd1353986910 167 lcd.cls();
peps 3:fd1353986910 168 lcd.locate(0,0);
peps 3:fd1353986910 169 lcd.printf("Ended.");
peps 2:bd0c735e81d6 170 lcd.locate(0,1);
peps 2:bd0c735e81d6 171 lcd.printf("Totale %02d:%02d:%02d",time.minutes,time.seconds,time.cents);
peps 2:bd0c735e81d6 172 }
peps 2:bd0c735e81d6 173
peps 2:bd0c735e81d6 174 void labyrinthLoop() {
peps 3:fd1353986910 175 if (lap == 0) {
peps 2:bd0c735e81d6 176 int read = t.read_ms();
peps 2:bd0c735e81d6 177
peps 2:bd0c735e81d6 178 measured_time time = human_read(read);
peps 2:bd0c735e81d6 179
peps 2:bd0c735e81d6 180 lcd.locate(0,1);
peps 2:bd0c735e81d6 181 lcd.printf("Elapsed %02d:%02d:%02d",time.minutes,time.seconds,time.cents);
peps 2:bd0c735e81d6 182 }
peps 2:bd0c735e81d6 183 }
peps 2:bd0c735e81d6 184
peps 2:bd0c735e81d6 185 void configMode() {
peps 2:bd0c735e81d6 186 switch(mode) {
peps 2:bd0c735e81d6 187 case LABYRINTH:
peps 2:bd0c735e81d6 188 gateStart.rise(&start_time);
peps 3:fd1353986910 189 gateEnd.enable_irq();
peps 2:bd0c735e81d6 190 gateEnd.rise(&stop_time);
peps 2:bd0c735e81d6 191 loopMethod = &labyrinthLoop;
peps 3:fd1353986910 192 lcd.cls();
peps 3:fd1353986910 193 lcd.locate(0,0);
peps 3:fd1353986910 194 lcd.printf("Mode: LABYRINTH ");
peps 3:fd1353986910 195 wait(1);
peps 3:fd1353986910 196 lcd.cls();
peps 2:bd0c735e81d6 197 break;
peps 2:bd0c735e81d6 198
peps 2:bd0c735e81d6 199 case SPEED:
peps 2:bd0c735e81d6 200 default:
peps 2:bd0c735e81d6 201 gateStart.rise(&measure_time);
peps 3:fd1353986910 202 gateEnd.disable_irq();
peps 2:bd0c735e81d6 203 loopMethod = &speedLoop;
peps 3:fd1353986910 204 lcd.cls();
peps 3:fd1353986910 205 lcd.locate(0,0);
peps 3:fd1353986910 206 lcd.printf("Mode: SPEED ");
peps 3:fd1353986910 207 wait(1);
peps 3:fd1353986910 208 lcd.cls();
peps 2:bd0c735e81d6 209 break;
peps 2:bd0c735e81d6 210 }
peps 2:bd0c735e81d6 211 }
peps 2:bd0c735e81d6 212
peps 3:fd1353986910 213 void reset_measure(){
peps 3:fd1353986910 214 t.stop();
peps 3:fd1353986910 215 t.reset();
peps 3:fd1353986910 216 lap = -1;
peps 3:fd1353986910 217 last_read = 0;
peps 3:fd1353986910 218 best_lap = 0;
peps 3:fd1353986910 219 best_time = -1;
peps 3:fd1353986910 220 lcd.cls();
peps 3:fd1353986910 221 }
peps 3:fd1353986910 222
peps 3:fd1353986910 223 void switchMode() {
peps 3:fd1353986910 224 mode = mode == SPEED ? LABYRINTH : SPEED;
peps 3:fd1353986910 225 reset_measure();
peps 3:fd1353986910 226 configMode();
peps 3:fd1353986910 227
peps 3:fd1353986910 228 }
peps 3:fd1353986910 229
Ghiri 0:1a92e4a37697 230 //------------------------------------------------------------
Ghiri 0:1a92e4a37697 231 //
Ghiri 0:1a92e4a37697 232 // Main body
Ghiri 0:1a92e4a37697 233 //
Ghiri 0:1a92e4a37697 234 //------------------------------------------------------------
Ghiri 0:1a92e4a37697 235 int main() {
peps 2:bd0c735e81d6 236 char key;
peps 3:fd1353986910 237 user_button.fall(&switchMode);
peps 2:bd0c735e81d6 238
peps 2:bd0c735e81d6 239 gateStart.mode(PullDown);
peps 2:bd0c735e81d6 240 gateEnd.mode(PullDown);
peps 2:bd0c735e81d6 241
peps 2:bd0c735e81d6 242 configMode();
peps 2:bd0c735e81d6 243
peps 2:bd0c735e81d6 244 while(true) {
Ghiri 0:1a92e4a37697 245 heartbeat = !heartbeat;
peps 2:bd0c735e81d6 246 loopMethod();
peps 2:bd0c735e81d6 247 wait(0.1);
peps 3:fd1353986910 248 /*
peps 2:bd0c735e81d6 249 key = keypad.getKey();
peps 2:bd0c735e81d6 250 if (key != KEY_RELEASED) {
peps 2:bd0c735e81d6 251 if(key == 'A') {
peps 2:bd0c735e81d6 252 mode = LABYRINTH;
peps 2:bd0c735e81d6 253 configMode();
peps 2:bd0c735e81d6 254 } else if(key == 'B') {
peps 2:bd0c735e81d6 255 mode = SPEED;
peps 2:bd0c735e81d6 256 configMode();
peps 2:bd0c735e81d6 257 } else if(key == '*') {
peps 2:bd0c735e81d6 258 reset_measure();
peps 2:bd0c735e81d6 259 }
Ghiri 0:1a92e4a37697 260 }
peps 3:fd1353986910 261 */
Ghiri 0:1a92e4a37697 262 }
Ghiri 0:1a92e4a37697 263 }
Ghiri 0:1a92e4a37697 264