Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Committer:
elmbed
Date:
Mon Dec 14 14:24:10 2015 +0000
Revision:
23:26f27c462976
Parent:
19:afcbb425b3cf
Child:
26:40a0c775ff27
Radio sort of works but still has many bugs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elmbed 17:d8b901d791fd 1 #include <TA.h>
elmbed 17:d8b901d791fd 2 #include <types.h>
elmbed 17:d8b901d791fd 3
elmbed 17:d8b901d791fd 4 #define RED p3
elmbed 17:d8b901d791fd 5 #define GREEN p5
elmbed 17:d8b901d791fd 6 #define BLUE p6
elmbed 17:d8b901d791fd 7
elmbed 17:d8b901d791fd 8 #define ENABLE_1 p4
elmbed 17:d8b901d791fd 9 #define ENABLE_2 p7
elmbed 17:d8b901d791fd 10 #define ENABLE_3 p8
elmbed 17:d8b901d791fd 11
elmbed 17:d8b901d791fd 12 #define DEBUG_BAUD 57600 //57600
elmbed 17:d8b901d791fd 13 #define MAX_LEN 24 // buffer input commands up to this length
elmbed 23:26f27c462976 14 #define NUM_CONES 2
elmbed 17:d8b901d791fd 15 #define STATIONS 20 // max length of a pattern
elmbed 17:d8b901d791fd 16 #define SEQUENCES 9 // number of patterns to store
elmbed 17:d8b901d791fd 17
elmbed 17:d8b901d791fd 18 #define TRILAT_CONE 99
elmbed 17:d8b901d791fd 19
elmbed 17:d8b901d791fd 20 #define DEBOUNCE_MS 100
elmbed 17:d8b901d791fd 21 #define LIGHTS 0x07
elmbed 17:d8b901d791fd 22 #define FAKEOUT 0x08
elmbed 17:d8b901d791fd 23 #define FAIL_QUICK 0x10
elmbed 17:d8b901d791fd 24 #define SILENT 0x20
elmbed 17:d8b901d791fd 25 #define GRACE_PERIOD 3000
elmbed 17:d8b901d791fd 26
elmbed 17:d8b901d791fd 27 #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need //////////////////////DEBUG messages on the console;
elmbed 17:d8b901d791fd 28 * it will have an impact on code-size and power consumption. */
elmbed 17:d8b901d791fd 29
elmbed 17:d8b901d791fd 30 #define LOOPBACK_MODE 0 // Loopback mode
elmbed 17:d8b901d791fd 31
elmbed 17:d8b901d791fd 32 #if NEED_CONSOLE_OUTPUT
elmbed 17:d8b901d791fd 33 #define DEBUG(...) { printf(__VA_ARGS__); }
elmbed 17:d8b901d791fd 34 #else
elmbed 17:d8b901d791fd 35 #define DEBUG(...) /* nothing */
elmbed 17:d8b901d791fd 36 #endif /* #if NEED_CONSOLE_OUTPUT */
elmbed 17:d8b901d791fd 37
elmbed 18:affef3a7db2a 38 #if 1
elmbed 17:d8b901d791fd 39 extern int random(int numberone, int numbertwo);
elmbed 17:d8b901d791fd 40
elmbed 17:d8b901d791fd 41 unsigned long millis();
elmbed 17:d8b901d791fd 42 unsigned long micros();
elmbed 17:d8b901d791fd 43
elmbed 17:d8b901d791fd 44 TA ta;
elmbed 17:d8b901d791fd 45
elmbed 18:affef3a7db2a 46 static bool active_cones[NUM_CONES + 1]; // + 1 so we can be 1 based like the cone numbers are
elmbed 17:d8b901d791fd 47
elmbed 23:26f27c462976 48 #ifdef MASTER
elmbed 18:affef3a7db2a 49 static Mode_t mode = PATTERN;
elmbed 18:affef3a7db2a 50 static patternState_t state_p = IDLE_P;
elmbed 18:affef3a7db2a 51 static inputState_t state_i = IDLE_I;
elmbed 23:26f27c462976 52 #define ADDRESS 1
elmbed 23:26f27c462976 53 #else
elmbed 23:26f27c462976 54 State_t state = IDLE;
elmbed 23:26f27c462976 55 #define CONTROL_CONE 1
elmbed 23:26f27c462976 56 #define ADDRESS 2
elmbed 23:26f27c462976 57 #endif
elmbed 17:d8b901d791fd 58
elmbed 18:affef3a7db2a 59 static Message m1 = { 'm',0,2 };
elmbed 17:d8b901d791fd 60
elmbed 18:affef3a7db2a 61 static Message *m = &m1;
elmbed 18:affef3a7db2a 62 static Message m2 = { 'm',0,2 };
elmbed 18:affef3a7db2a 63 static Message *m_in = &m2;
elmbed 17:d8b901d791fd 64
elmbed 18:affef3a7db2a 65 static uint8_t active_cone = 0;
elmbed 18:affef3a7db2a 66 static unsigned long timeout = 0;
elmbed 18:affef3a7db2a 67 static uint8_t mask = 0x07;
elmbed 18:affef3a7db2a 68 static uint8_t fakeout = 0;
elmbed 18:affef3a7db2a 69 static uint8_t fail_quick = 0;
elmbed 18:affef3a7db2a 70 static uint8_t index = 0;
elmbed 18:affef3a7db2a 71 static bool new_state = false;
elmbed 18:affef3a7db2a 72 static bool tag_start = false; // flag to indicate we should wait for the user to activate the first station before going through the sequence
elmbed 18:affef3a7db2a 73
elmbed 17:d8b901d791fd 74 static bool in_menu = false;
elmbed 17:d8b901d791fd 75 static bool warning = false;
elmbed 17:d8b901d791fd 76 static bool penalty = false;
elmbed 17:d8b901d791fd 77 static bool logging = false;
elmbed 17:d8b901d791fd 78
elmbed 17:d8b901d791fd 79 // course setup (probably should make some of these persistant settings)
elmbed 18:affef3a7db2a 80 static uint8_t active_sequence = 0;
elmbed 18:affef3a7db2a 81 static uint8_t station = 1;
elmbed 18:affef3a7db2a 82 static uint8_t cone = 0;
elmbed 18:affef3a7db2a 83 static uint16_t ltime = 0;
elmbed 17:d8b901d791fd 84
elmbed 17:d8b901d791fd 85 volatile bool triggered;
elmbed 17:d8b901d791fd 86 volatile bool pin;
elmbed 17:d8b901d791fd 87 volatile bool ping = false;
elmbed 18:affef3a7db2a 88
elmbed 17:d8b901d791fd 89 static volatile bool captured = false;
elmbed 17:d8b901d791fd 90 static volatile unsigned long ping_timer = 0;
elmbed 17:d8b901d791fd 91 static volatile unsigned long dist_timeout = 0;
elmbed 17:d8b901d791fd 92
elmbed 17:d8b901d791fd 93 // all sequence data
elmbed 17:d8b901d791fd 94 uint8_t cone_table[STATIONS * SEQUENCES];
elmbed 17:d8b901d791fd 95 uint8_t mask_table[STATIONS * SEQUENCES];
elmbed 17:d8b901d791fd 96 uint16_t time_table[STATIONS * SEQUENCES];
elmbed 17:d8b901d791fd 97
elmbed 17:d8b901d791fd 98 // pointer to active table
elmbed 17:d8b901d791fd 99 uint8_t *cones = (uint8_t*)cone_table;
elmbed 17:d8b901d791fd 100 uint8_t *masks = (uint8_t*)mask_table;
elmbed 17:d8b901d791fd 101 uint16_t *times = (uint16_t*)time_table;
elmbed 17:d8b901d791fd 102
elmbed 17:d8b901d791fd 103 static bool lonely = false;
elmbed 17:d8b901d791fd 104
elmbed 17:d8b901d791fd 105 // Function prototypes
elmbed 23:26f27c462976 106 #ifdef MASTER
elmbed 17:d8b901d791fd 107 void spin();
elmbed 17:d8b901d791fd 108 patternState_t stateFromCone(uint8_t cone);
elmbed 17:d8b901d791fd 109 void printSplit(unsigned long timer);
elmbed 17:d8b901d791fd 110 uint8_t getRandomCone(void);
elmbed 17:d8b901d791fd 111 void clearCones(void);
elmbed 17:d8b901d791fd 112 void powerupCones(uint8_t sound);
elmbed 17:d8b901d791fd 113 void failCones(void);
elmbed 17:d8b901d791fd 114 void resetSensors(void);
elmbed 17:d8b901d791fd 115 void successCones(void);
elmbed 17:d8b901d791fd 116 void find_cones(void);
elmbed 17:d8b901d791fd 117 void printMsAsSeconds(unsigned long number);
elmbed 17:d8b901d791fd 118 void spinButtons(void);
elmbed 17:d8b901d791fd 119 uint8_t checkButtons(void);
elmbed 17:d8b901d791fd 120 Event getInputEvent(void);
elmbed 17:d8b901d791fd 121 void getRadioInput(char *ibuffer, int size);
elmbed 17:d8b901d791fd 122 void interpret(char parameter, int value);
elmbed 23:26f27c462976 123 #endif
elmbed 23:26f27c462976 124
elmbed 23:26f27c462976 125 extern "C" void writeToPhone(char *format, ...);
elmbed 17:d8b901d791fd 126
elmbed 17:d8b901d791fd 127 char local_input[50] = {0};
elmbed 17:d8b901d791fd 128
elmbed 17:d8b901d791fd 129 //DigitalOut red(RED);
elmbed 17:d8b901d791fd 130 //DigitalOut enable1(ENABLE_1);
elmbed 17:d8b901d791fd 131 //DigitalOut green(GREEN);
elmbed 17:d8b901d791fd 132 //DigitalOut blue(BLUE);
elmbed 17:d8b901d791fd 133 //DigitalOut enable2(ENABLE_2);
elmbed 17:d8b901d791fd 134 //DigitalOut enable3(ENABLE_3);
elmbed 17:d8b901d791fd 135
elmbed 23:26f27c462976 136 #ifdef MASTER
elmbed 23:26f27c462976 137 static void master_setup()
elmbed 17:d8b901d791fd 138 {
elmbed 17:d8b901d791fd 139 ta.initialize(ADDRESS);
elmbed 17:d8b901d791fd 140
elmbed 17:d8b901d791fd 141 uint16_t sent = 0;
elmbed 17:d8b901d791fd 142 uint16_t lost = 0;
elmbed 17:d8b901d791fd 143 unsigned long start = micros();
elmbed 17:d8b901d791fd 144 //while (millis() - now <= ACK_TIME){
elmbed 17:d8b901d791fd 145 m->command = 'p';
elmbed 17:d8b901d791fd 146 m->value = 0;
elmbed 17:d8b901d791fd 147 m->cone = 0;
elmbed 17:d8b901d791fd 148
elmbed 23:26f27c462976 149
elmbed 23:26f27c462976 150 //find_cones(); // this causes the beep to be interrupted
elmbed 23:26f27c462976 151 //ta.beep(100);
elmbed 17:d8b901d791fd 152 int i;
elmbed 23:26f27c462976 153
elmbed 23:26f27c462976 154 //for(i=3;i<=3;i++)active_cones[i] = true;
elmbed 17:d8b901d791fd 155 for(i=1;i<NUM_CONES+1;i++)active_cones[i] = true;
elmbed 17:d8b901d791fd 156
elmbed 17:d8b901d791fd 157 unsigned long time = 0;
elmbed 17:d8b901d791fd 158
elmbed 17:d8b901d791fd 159 // pull course sequences from non-volatile memory
elmbed 17:d8b901d791fd 160 for(uint8_t i=0;i<STATIONS * SEQUENCES;i++){
elmbed 17:d8b901d791fd 161 cone_table[i] = i+1;
elmbed 17:d8b901d791fd 162 mask_table[i] = 1;
elmbed 17:d8b901d791fd 163 time_table[i] = 1000;
elmbed 17:d8b901d791fd 164 }
elmbed 18:affef3a7db2a 165
elmbed 18:affef3a7db2a 166 ta.post_color(0xFF0000);
elmbed 17:d8b901d791fd 167 }
elmbed 23:26f27c462976 168 #else
elmbed 23:26f27c462976 169 static void slave_setup()
elmbed 23:26f27c462976 170 {
elmbed 23:26f27c462976 171 ta.initialize(ADDRESS);
elmbed 23:26f27c462976 172 ta.beep(250);
elmbed 23:26f27c462976 173 }
elmbed 23:26f27c462976 174 #endif
elmbed 23:26f27c462976 175
elmbed 23:26f27c462976 176 void setup()
elmbed 23:26f27c462976 177 {
elmbed 23:26f27c462976 178 #ifdef MASTER
elmbed 23:26f27c462976 179 master_setup();
elmbed 23:26f27c462976 180 #else
elmbed 23:26f27c462976 181 slave_setup();
elmbed 23:26f27c462976 182 #endif
elmbed 23:26f27c462976 183 }
elmbed 23:26f27c462976 184
elmbed 23:26f27c462976 185 #ifdef SLAVE
elmbed 23:26f27c462976 186 static void slave_loop()
elmbed 23:26f27c462976 187 {
elmbed 23:26f27c462976 188 static unsigned long start = 0;
elmbed 23:26f27c462976 189 static unsigned long timeout;
elmbed 23:26f27c462976 190 static bool process_next_as_time = false;
elmbed 23:26f27c462976 191 static bool process_next_as_mask = false;
elmbed 23:26f27c462976 192 static unsigned long timer;
elmbed 23:26f27c462976 193 static State_t last_state = IDLE;
elmbed 23:26f27c462976 194
elmbed 23:26f27c462976 195 if(last_state != state)
elmbed 23:26f27c462976 196 {
elmbed 23:26f27c462976 197 if(state == ACTIVE_TARGET)
elmbed 23:26f27c462976 198 writeToPhone("State is ACTIVE_TARGET\n");
elmbed 23:26f27c462976 199 if(state == IDLE)
elmbed 23:26f27c462976 200 writeToPhone("State is IDLE");
elmbed 23:26f27c462976 201 if(state == FAIL)
elmbed 23:26f27c462976 202 writeToPhone("State is FAIL");
elmbed 23:26f27c462976 203 if(state == SUCCESS)
elmbed 23:26f27c462976 204 writeToPhone("State is SUCCESS");
elmbed 23:26f27c462976 205 }
elmbed 23:26f27c462976 206
elmbed 23:26f27c462976 207 last_state = state;
elmbed 23:26f27c462976 208
elmbed 23:26f27c462976 209 char message = 'n';
elmbed 23:26f27c462976 210 timer = millis() - start;
elmbed 23:26f27c462976 211
elmbed 23:26f27c462976 212 if(ta.recieve(m_in))
elmbed 23:26f27c462976 213 {
elmbed 23:26f27c462976 214 ta.beep(1000);
elmbed 23:26f27c462976 215 message = m_in->command;
elmbed 23:26f27c462976 216 switch(m_in->command)
elmbed 23:26f27c462976 217 {
elmbed 23:26f27c462976 218 case 't':
elmbed 23:26f27c462976 219 timeout = m_in->value;
elmbed 23:26f27c462976 220 //serial.printf("timeout: ");
elmbed 23:26f27c462976 221 //serial.printf("%d\n",timeout);
elmbed 23:26f27c462976 222 break;
elmbed 23:26f27c462976 223 case 'm':
elmbed 23:26f27c462976 224 //serial.printf("config bits: ");
elmbed 23:26f27c462976 225 mask = m_in->value;
elmbed 23:26f27c462976 226 ta.setMask(mask);// & LIGHTS);
elmbed 23:26f27c462976 227 //serial.printf("%s\n",byte_to_binary(mask));
elmbed 23:26f27c462976 228 fakeout = mask & FAKEOUT;
elmbed 23:26f27c462976 229
elmbed 23:26f27c462976 230 //if(fakeout)
elmbed 23:26f27c462976 231 // serial.printf("fakeout!");
elmbed 23:26f27c462976 232
elmbed 23:26f27c462976 233 fail_quick = mask & FAIL_QUICK;
elmbed 23:26f27c462976 234 break;
elmbed 23:26f27c462976 235 default: break;
elmbed 23:26f27c462976 236 }
elmbed 23:26f27c462976 237 }
elmbed 23:26f27c462976 238
elmbed 23:26f27c462976 239 if(message == 'x')
elmbed 23:26f27c462976 240 {
elmbed 23:26f27c462976 241 //a3 = 0;
elmbed 23:26f27c462976 242 wait_ms(100);
elmbed 23:26f27c462976 243 //a3 = 1;
elmbed 23:26f27c462976 244 }
elmbed 23:26f27c462976 245
elmbed 23:26f27c462976 246 if(message == 'f')
elmbed 23:26f27c462976 247 { // Fail
elmbed 23:26f27c462976 248 //serial.printf("Fail!\n");
elmbed 23:26f27c462976 249 ta.pulse(25,200,3000,0xFF0000);
elmbed 23:26f27c462976 250 state = FAIL;
elmbed 23:26f27c462976 251 }
elmbed 23:26f27c462976 252
elmbed 23:26f27c462976 253 if(message == 's')
elmbed 23:26f27c462976 254 { // Success
elmbed 23:26f27c462976 255 //serial.printf("Success!\n");
elmbed 23:26f27c462976 256 ta.post_color(0x00FF00);
elmbed 23:26f27c462976 257 ta.beep(1500);
elmbed 23:26f27c462976 258 state = SUCCESS;
elmbed 23:26f27c462976 259 }
elmbed 23:26f27c462976 260
elmbed 23:26f27c462976 261 if(message == 'g')
elmbed 23:26f27c462976 262 { // This cone is the active target, GO!
elmbed 23:26f27c462976 263 start = millis();
elmbed 23:26f27c462976 264 warning = false;
elmbed 23:26f27c462976 265 penalty = false;
elmbed 23:26f27c462976 266 ta.pulse(50,750,~0L,0x00FF00);
elmbed 23:26f27c462976 267 state = ACTIVE_TARGET;
elmbed 23:26f27c462976 268 //serial.printf("fakeout, fail_quick\n");
elmbed 23:26f27c462976 269 //serial.printf("%d",fakeout);
elmbed 23:26f27c462976 270 //serial.printf(", ");
elmbed 23:26f27c462976 271 //serial.printf("%d\n",fail_quick);
elmbed 23:26f27c462976 272 }
elmbed 23:26f27c462976 273
elmbed 23:26f27c462976 274 if(message == 'q')
elmbed 23:26f27c462976 275 { // Quit
elmbed 23:26f27c462976 276 //serial.printf("Clear!\n");
elmbed 23:26f27c462976 277 ta.pulse_off();
elmbed 23:26f27c462976 278 ta.mask_color(0xFF0000);
elmbed 23:26f27c462976 279 state = IDLE;
elmbed 23:26f27c462976 280 }
elmbed 23:26f27c462976 281
elmbed 23:26f27c462976 282 if(message != 'n')
elmbed 23:26f27c462976 283 {
elmbed 23:26f27c462976 284 //serial.printf("%d",message);
elmbed 23:26f27c462976 285 //serial.printf(", ");
elmbed 23:26f27c462976 286 //serial.printf("%d\n",m_in->value);
elmbed 23:26f27c462976 287 }
elmbed 23:26f27c462976 288
elmbed 23:26f27c462976 289 if(message == 'u')
elmbed 23:26f27c462976 290 { // powerup noise
elmbed 23:26f27c462976 291 ta.powerup(m_in->value);
elmbed 23:26f27c462976 292 }
elmbed 23:26f27c462976 293
elmbed 23:26f27c462976 294 if(message == 'z')
elmbed 23:26f27c462976 295 {
elmbed 23:26f27c462976 296 m->value = m_in->value;
elmbed 23:26f27c462976 297 m->command = 'z';
elmbed 23:26f27c462976 298 m->cone = 3;
elmbed 23:26f27c462976 299 ta.send(m);
elmbed 23:26f27c462976 300 }
elmbed 23:26f27c462976 301
elmbed 23:26f27c462976 302 timer = millis() - start;
elmbed 23:26f27c462976 303
elmbed 23:26f27c462976 304 switch(state)
elmbed 23:26f27c462976 305 {
elmbed 23:26f27c462976 306 case ACTIVE_TARGET:
elmbed 23:26f27c462976 307 if(ta.activated() || ((timer > timeout) && (fakeout)))
elmbed 23:26f27c462976 308 {
elmbed 23:26f27c462976 309 m->command = 'd';
elmbed 23:26f27c462976 310 m->cone = CONTROL_CONE;
elmbed 23:26f27c462976 311 ta.send(m);
elmbed 23:26f27c462976 312 ta.pulse_off();
elmbed 23:26f27c462976 313 state = IDLE;
elmbed 23:26f27c462976 314 //serial.printf("Done!\n");
elmbed 23:26f27c462976 315 }
elmbed 23:26f27c462976 316 else if(timer > timeout && !penalty)
elmbed 23:26f27c462976 317 {
elmbed 23:26f27c462976 318 //serial.printf("Penalty!\n");
elmbed 23:26f27c462976 319 penalty = true;
elmbed 23:26f27c462976 320 ta.pulse(50,325,~0L,0xFF00FF);
elmbed 23:26f27c462976 321 }
elmbed 23:26f27c462976 322 else if(timer > ((timeout*3)/4) && !warning)
elmbed 23:26f27c462976 323 {
elmbed 23:26f27c462976 324 //serial.printf("Warning!\n");
elmbed 23:26f27c462976 325 warning = true;
elmbed 23:26f27c462976 326 ta.pulse(50,750,~0L,0xFFFF00);
elmbed 23:26f27c462976 327 }
elmbed 23:26f27c462976 328 break;
elmbed 23:26f27c462976 329 case IDLE:
elmbed 23:26f27c462976 330 ta.post_color((ta.activated())?0xFF:0xFF0000);
elmbed 23:26f27c462976 331 break;
elmbed 23:26f27c462976 332 default:
elmbed 23:26f27c462976 333 break;
elmbed 23:26f27c462976 334 }
elmbed 23:26f27c462976 335 }
elmbed 23:26f27c462976 336 #endif
elmbed 23:26f27c462976 337
elmbed 23:26f27c462976 338 #ifdef MASTER
elmbed 23:26f27c462976 339 static void master_loop()
elmbed 23:26f27c462976 340 {
elmbed 23:26f27c462976 341 static Mode_t last_mode = mode;
elmbed 23:26f27c462976 342
elmbed 23:26f27c462976 343 if (last_mode != mode)
elmbed 23:26f27c462976 344 {
elmbed 23:26f27c462976 345 if (mode == FREEFORM)
elmbed 23:26f27c462976 346 writeToPhone("Now running random routes.\n");
elmbed 23:26f27c462976 347
elmbed 23:26f27c462976 348 if (mode == PATTERN)
elmbed 23:26f27c462976 349 writeToPhone("Now running set patterns.\n");
elmbed 23:26f27c462976 350 }
elmbed 23:26f27c462976 351
elmbed 23:26f27c462976 352 last_mode = mode;
elmbed 23:26f27c462976 353
elmbed 23:26f27c462976 354 ta.spin();
elmbed 23:26f27c462976 355 //spinButtons();
elmbed 23:26f27c462976 356 if((logging || micros() < dist_timeout) && ta.recieve(m_in))
elmbed 23:26f27c462976 357 writeToPhone("%c",m_in->command);
elmbed 23:26f27c462976 358 else
elmbed 23:26f27c462976 359 spin();
elmbed 23:26f27c462976 360 }
elmbed 23:26f27c462976 361 #endif
elmbed 17:d8b901d791fd 362
elmbed 17:d8b901d791fd 363 void loop()
elmbed 17:d8b901d791fd 364 {
elmbed 23:26f27c462976 365 #ifdef MASTER
elmbed 23:26f27c462976 366 master_loop();
elmbed 23:26f27c462976 367 #else
elmbed 23:26f27c462976 368 slave_loop();
elmbed 23:26f27c462976 369 #endif
elmbed 17:d8b901d791fd 370 }
elmbed 17:d8b901d791fd 371
elmbed 23:26f27c462976 372 static void getNext()
elmbed 17:d8b901d791fd 373 {
elmbed 23:26f27c462976 374 #ifdef MASTER
elmbed 17:d8b901d791fd 375 if(mode == FREEFORM)
elmbed 17:d8b901d791fd 376 {
elmbed 17:d8b901d791fd 377 DEBUG("get next freeform\r\n");
elmbed 17:d8b901d791fd 378 ++active_cone;//getRandomCone();
elmbed 17:d8b901d791fd 379 if (active_cone > 6)
elmbed 17:d8b901d791fd 380 {
elmbed 17:d8b901d791fd 381 active_cone = 1;
elmbed 17:d8b901d791fd 382 }
elmbed 17:d8b901d791fd 383 mask = 0x07;
elmbed 17:d8b901d791fd 384 ta.setMask(mask & LIGHTS);
elmbed 17:d8b901d791fd 385 timeout = ~0;
elmbed 17:d8b901d791fd 386 return;
elmbed 17:d8b901d791fd 387 }
elmbed 17:d8b901d791fd 388
elmbed 17:d8b901d791fd 389 active_cone = cones[index];
elmbed 17:d8b901d791fd 390 mask = masks[index];
elmbed 17:d8b901d791fd 391 fakeout = mask & FAKEOUT;
elmbed 17:d8b901d791fd 392 fail_quick = mask & FAIL_QUICK;
elmbed 17:d8b901d791fd 393 timeout = times[index];
elmbed 17:d8b901d791fd 394 index++;
elmbed 17:d8b901d791fd 395 DEBUG("Next cone is \n");
elmbed 17:d8b901d791fd 396 DEBUG("%d\n",active_cone);
elmbed 23:26f27c462976 397 #endif
elmbed 17:d8b901d791fd 398 }
elmbed 18:affef3a7db2a 399 #if 1
elmbed 23:26f27c462976 400 static void spin()
elmbed 17:d8b901d791fd 401 {
elmbed 23:26f27c462976 402 #ifdef MASTER
elmbed 17:d8b901d791fd 403 static patternState_t last_state = START_P;
elmbed 17:d8b901d791fd 404 static uint8_t last_cone = 255;
elmbed 17:d8b901d791fd 405 static unsigned long start;
elmbed 17:d8b901d791fd 406 static unsigned long timer;
elmbed 17:d8b901d791fd 407 static bool first; // first should be true when we first enter a state (even if we just exited the same state)
elmbed 17:d8b901d791fd 408 char command = 'n';
elmbed 17:d8b901d791fd 409 unsigned long value = 0;
elmbed 17:d8b901d791fd 410
elmbed 17:d8b901d791fd 411 m_in->command = 0;
elmbed 17:d8b901d791fd 412 m_in->value = 0;
elmbed 17:d8b901d791fd 413 m_in->cone = 0;
elmbed 17:d8b901d791fd 414
elmbed 17:d8b901d791fd 415 if(ta.recieve(m_in))
elmbed 17:d8b901d791fd 416 {
elmbed 17:d8b901d791fd 417 DEBUG("spin received: %d '%c'\r\n", m_in->cone, m_in->command);
elmbed 17:d8b901d791fd 418 command = m_in->command;
elmbed 17:d8b901d791fd 419 value = m_in->value;
elmbed 17:d8b901d791fd 420 }
elmbed 17:d8b901d791fd 421
elmbed 17:d8b901d791fd 422 first = false;
elmbed 17:d8b901d791fd 423
elmbed 17:d8b901d791fd 424 if(last_state != state_p || new_state)
elmbed 17:d8b901d791fd 425 {
elmbed 17:d8b901d791fd 426 if(state_p == START_P)
elmbed 17:d8b901d791fd 427 DEBUG("State is START\n");
elmbed 17:d8b901d791fd 428 if(state_p == WAITING_P)
elmbed 17:d8b901d791fd 429 DEBUG("State is WAITING\n");
elmbed 17:d8b901d791fd 430 if(state_p == ACTIVE_TARGET_P)
elmbed 17:d8b901d791fd 431 DEBUG("State is ACTIVE_TARGET\n");
elmbed 17:d8b901d791fd 432 if(state_p == IDLE_P)
elmbed 17:d8b901d791fd 433 DEBUG("State is IDLE\n");
elmbed 17:d8b901d791fd 434 if(state_p == FAIL_P)
elmbed 17:d8b901d791fd 435 DEBUG("State is FAIL\n");
elmbed 17:d8b901d791fd 436 if(state_p == SUCCESS_P)
elmbed 17:d8b901d791fd 437 DEBUG("State is SUCCESS)\n");
elmbed 17:d8b901d791fd 438
elmbed 17:d8b901d791fd 439 first = true;
elmbed 17:d8b901d791fd 440 new_state = false;
elmbed 17:d8b901d791fd 441 }
elmbed 17:d8b901d791fd 442
elmbed 17:d8b901d791fd 443 last_state = state_p;
elmbed 17:d8b901d791fd 444 last_cone = active_cone;
elmbed 17:d8b901d791fd 445
elmbed 17:d8b901d791fd 446 timer = millis() - start;
elmbed 17:d8b901d791fd 447
elmbed 17:d8b901d791fd 448 switch(state_p)
elmbed 17:d8b901d791fd 449 {
elmbed 17:d8b901d791fd 450 case IDLE_P:
elmbed 17:d8b901d791fd 451 if(!in_menu)
elmbed 17:d8b901d791fd 452 ta.post_color((ta.activated())?0xFF:0xFF0000);
elmbed 17:d8b901d791fd 453 break;
elmbed 17:d8b901d791fd 454
elmbed 17:d8b901d791fd 455 case START_P:
elmbed 17:d8b901d791fd 456 //clearCones();
elmbed 17:d8b901d791fd 457 tag_start = false;
elmbed 17:d8b901d791fd 458 ta.post_color(0xFF0000);
elmbed 17:d8b901d791fd 459 index = 0;
elmbed 17:d8b901d791fd 460 getNext();
elmbed 17:d8b901d791fd 461
elmbed 17:d8b901d791fd 462 if(timeout == 0)
elmbed 17:d8b901d791fd 463 { // timeout of 0 means wait indefinitely for the first cone to be activated, then start the rest of the sequence
elmbed 17:d8b901d791fd 464 timeout = ~0;
elmbed 17:d8b901d791fd 465 tag_start = true;
elmbed 17:d8b901d791fd 466 DEBUG("Activate cone ");
elmbed 17:d8b901d791fd 467 DEBUG("%d",active_cone);
elmbed 17:d8b901d791fd 468 DEBUG(" to start.\n");
elmbed 17:d8b901d791fd 469 }
elmbed 17:d8b901d791fd 470
elmbed 17:d8b901d791fd 471 start = millis();
elmbed 17:d8b901d791fd 472 state_p = stateFromCone(active_cone);
elmbed 17:d8b901d791fd 473 if(active_cone == 0)
elmbed 17:d8b901d791fd 474 { // in this case stateFromCone returns SUCCESS_P, but really there was no course sequence
elmbed 17:d8b901d791fd 475 DEBUG("\n");
elmbed 17:d8b901d791fd 476 DEBUG("Empty course sequence!\n");
elmbed 17:d8b901d791fd 477 ta.post_color(0x0000FF);
elmbed 17:d8b901d791fd 478 state_p = IDLE_P;
elmbed 17:d8b901d791fd 479 break;
elmbed 17:d8b901d791fd 480 }
elmbed 17:d8b901d791fd 481 break;
elmbed 17:d8b901d791fd 482
elmbed 17:d8b901d791fd 483 case WAITING_P:
elmbed 17:d8b901d791fd 484 if(first)
elmbed 17:d8b901d791fd 485 {
elmbed 17:d8b901d791fd 486 m->command = 'm';
elmbed 17:d8b901d791fd 487 m->value = mask;
elmbed 17:d8b901d791fd 488 m->cone = active_cone;
elmbed 17:d8b901d791fd 489 ta.send(m);
elmbed 17:d8b901d791fd 490 m->command = 't';
elmbed 17:d8b901d791fd 491 m->value = (uint32_t)timeout;
elmbed 17:d8b901d791fd 492 ta.send(m);
elmbed 17:d8b901d791fd 493 m->command = 'g';
elmbed 17:d8b901d791fd 494 ta.send(m);
elmbed 17:d8b901d791fd 495
elmbed 17:d8b901d791fd 496 DEBUG("m_in cone=%d\n", active_cone);
elmbed 17:d8b901d791fd 497 m_in->cone = active_cone;
elmbed 17:d8b901d791fd 498 command = 'd';
elmbed 17:d8b901d791fd 499
elmbed 17:d8b901d791fd 500 }
elmbed 17:d8b901d791fd 501
elmbed 17:d8b901d791fd 502 ta.post_color(( ta.activated())?0xFF:0xFF0000);
elmbed 17:d8b901d791fd 503
elmbed 17:d8b901d791fd 504 DEBUG("Waiting: %d %d %c\n", m_in->cone, active_cone, command);
elmbed 17:d8b901d791fd 505
elmbed 17:d8b901d791fd 506 if((m_in->cone == active_cone && command == 'd' ) || ((timer >= timeout) && fakeout))
elmbed 17:d8b901d791fd 507 {
elmbed 17:d8b901d791fd 508 if((timer >= timeout) && !fakeout)
elmbed 17:d8b901d791fd 509 {
elmbed 17:d8b901d791fd 510 DEBUG("Timesplit penalty! ");
elmbed 17:d8b901d791fd 511 }
elmbed 17:d8b901d791fd 512 printSplit(timer);
elmbed 17:d8b901d791fd 513 getNext();
elmbed 17:d8b901d791fd 514 start = millis();
elmbed 17:d8b901d791fd 515
elmbed 17:d8b901d791fd 516 state_p = stateFromCone(active_cone);
elmbed 17:d8b901d791fd 517
elmbed 17:d8b901d791fd 518 if(state_p == WAITING_P)
elmbed 17:d8b901d791fd 519 {
elmbed 17:d8b901d791fd 520 DEBUG("New state from waiting\n");
elmbed 17:d8b901d791fd 521 new_state = true;
elmbed 17:d8b901d791fd 522 }
elmbed 17:d8b901d791fd 523 }
elmbed 17:d8b901d791fd 524 else if(~timeout != 0 && mode == PATTERN && timer >= (timeout + ((fail_quick)?0:GRACE_PERIOD)))
elmbed 17:d8b901d791fd 525 {
elmbed 17:d8b901d791fd 526 DEBUG("Failing from wait\n");
elmbed 17:d8b901d791fd 527 state_p = FAIL_P;
elmbed 17:d8b901d791fd 528 }
elmbed 17:d8b901d791fd 529 break;
elmbed 17:d8b901d791fd 530
elmbed 17:d8b901d791fd 531 case ACTIVE_TARGET_P:
elmbed 17:d8b901d791fd 532 if(first)
elmbed 17:d8b901d791fd 533 {
elmbed 17:d8b901d791fd 534 ta.setMask(mask);
elmbed 17:d8b901d791fd 535
elmbed 17:d8b901d791fd 536 warning = false;
elmbed 17:d8b901d791fd 537 penalty = false;
elmbed 17:d8b901d791fd 538 ta.pulse(50,750,~0L,0x00FF00);
elmbed 17:d8b901d791fd 539 //if(!(mask & SILENT))ta.pulse(50,750,~0L,0c00FF00);
elmbed 17:d8b901d791fd 540 }
elmbed 17:d8b901d791fd 541 if(timer >= timeout)
elmbed 17:d8b901d791fd 542 {
elmbed 17:d8b901d791fd 543 if(!penalty)
elmbed 17:d8b901d791fd 544 {
elmbed 17:d8b901d791fd 545 ta.pulse(50,325,~0L,0xFF00FF);
elmbed 17:d8b901d791fd 546
elmbed 17:d8b901d791fd 547 penalty = true;
elmbed 17:d8b901d791fd 548 }
elmbed 17:d8b901d791fd 549 ta.mask_color(0xFF00FF);
elmbed 17:d8b901d791fd 550 }
elmbed 17:d8b901d791fd 551 else if(timer > ((timeout*3)/4) && !warning)
elmbed 17:d8b901d791fd 552 {
elmbed 17:d8b901d791fd 553 warning = true;
elmbed 17:d8b901d791fd 554 ta.pulse(50,750,~0L,0xFFFF00);
elmbed 17:d8b901d791fd 555 }
elmbed 17:d8b901d791fd 556
elmbed 17:d8b901d791fd 557 if(ta.activated() || ((timer >= timeout) && fakeout))
elmbed 17:d8b901d791fd 558 {
elmbed 17:d8b901d791fd 559 if((timer >= timeout) && !fakeout)
elmbed 17:d8b901d791fd 560 DEBUG("Timesplit penalty! ");
elmbed 17:d8b901d791fd 561
elmbed 17:d8b901d791fd 562 printSplit(timer);
elmbed 17:d8b901d791fd 563 ta.post_color(0xFF0000);
elmbed 17:d8b901d791fd 564 getNext();
elmbed 17:d8b901d791fd 565 start = millis();
elmbed 17:d8b901d791fd 566 state_p = stateFromCone(active_cone);
elmbed 17:d8b901d791fd 567
elmbed 17:d8b901d791fd 568 if(state_p == ACTIVE_TARGET_P)
elmbed 17:d8b901d791fd 569 new_state = true;
elmbed 17:d8b901d791fd 570 ta.pulse_off();
elmbed 17:d8b901d791fd 571
elmbed 17:d8b901d791fd 572 }
elmbed 17:d8b901d791fd 573 else if(~timeout != 0 && mode == PATTERN && timer >= (timeout + ((fail_quick)?0:GRACE_PERIOD)))
elmbed 17:d8b901d791fd 574 {
elmbed 17:d8b901d791fd 575 state_p = FAIL_P;
elmbed 17:d8b901d791fd 576 ta.pulse_off();
elmbed 17:d8b901d791fd 577 }
elmbed 17:d8b901d791fd 578 //DEBUG.println(timeout + ((fail_quick)?0:GRACE_PERIOD));
elmbed 17:d8b901d791fd 579 //DEBUG.println(timeout);
elmbed 17:d8b901d791fd 580
elmbed 17:d8b901d791fd 581 break;
elmbed 17:d8b901d791fd 582
elmbed 17:d8b901d791fd 583 case FAIL_P:
elmbed 17:d8b901d791fd 584 if(first)
elmbed 17:d8b901d791fd 585 {
elmbed 17:d8b901d791fd 586 start = millis();
elmbed 17:d8b901d791fd 587 DEBUG("\n");
elmbed 17:d8b901d791fd 588 DEBUG("Timeout\n");
elmbed 17:d8b901d791fd 589 //ta.post_color();
elmbed 17:d8b901d791fd 590 ta.pulse(25,200,3000,0xFF0000);
elmbed 17:d8b901d791fd 591
elmbed 17:d8b901d791fd 592 failCones();
elmbed 17:d8b901d791fd 593 //ta.fail();
elmbed 17:d8b901d791fd 594 }
elmbed 17:d8b901d791fd 595 else if(timer > 3000)
elmbed 17:d8b901d791fd 596 {
elmbed 17:d8b901d791fd 597 DEBUG("Clear!\n");
elmbed 17:d8b901d791fd 598 state_p = IDLE_P;
elmbed 17:d8b901d791fd 599 clearCones();
elmbed 17:d8b901d791fd 600 }
elmbed 17:d8b901d791fd 601 break;
elmbed 17:d8b901d791fd 602 case SUCCESS_P:
elmbed 17:d8b901d791fd 603 if(first)
elmbed 17:d8b901d791fd 604 {
elmbed 17:d8b901d791fd 605 start = millis();
elmbed 17:d8b901d791fd 606 DEBUG("\n");
elmbed 17:d8b901d791fd 607 DEBUG("Done!\n");
elmbed 17:d8b901d791fd 608 ta.post_color(0x00FF00);
elmbed 17:d8b901d791fd 609 ta.beep(1500);
elmbed 17:d8b901d791fd 610 successCones();
elmbed 17:d8b901d791fd 611 //ta.success();
elmbed 17:d8b901d791fd 612 }
elmbed 17:d8b901d791fd 613 else if(timer > 1500)
elmbed 17:d8b901d791fd 614 {
elmbed 17:d8b901d791fd 615 DEBUG("Clear!\n");
elmbed 17:d8b901d791fd 616 state_p = IDLE_P;
elmbed 17:d8b901d791fd 617 clearCones();
elmbed 17:d8b901d791fd 618 }
elmbed 17:d8b901d791fd 619 break;
elmbed 17:d8b901d791fd 620
elmbed 17:d8b901d791fd 621 default:
elmbed 17:d8b901d791fd 622 break;
elmbed 17:d8b901d791fd 623 }
elmbed 23:26f27c462976 624 #endif
elmbed 17:d8b901d791fd 625 }
elmbed 18:affef3a7db2a 626 #endif
elmbed 18:affef3a7db2a 627
elmbed 23:26f27c462976 628 #ifdef MASTER
elmbed 17:d8b901d791fd 629 void getRadioInput(char *ibuffer, int size)
elmbed 17:d8b901d791fd 630 {
elmbed 17:d8b901d791fd 631 static int i = 0;
elmbed 17:d8b901d791fd 632 int buffer_counter = 0;
elmbed 17:d8b901d791fd 633 static char parameter = '_';
elmbed 17:d8b901d791fd 634 static char buffer[MAX_LEN + 1];
elmbed 17:d8b901d791fd 635 int value = 0;
elmbed 17:d8b901d791fd 636 char *endp = NULL;
elmbed 17:d8b901d791fd 637
elmbed 17:d8b901d791fd 638 // listen for commands coming over bluetooth
elmbed 17:d8b901d791fd 639 while (buffer_counter < size)
elmbed 17:d8b901d791fd 640 {
elmbed 17:d8b901d791fd 641 char ch = ibuffer[buffer_counter++];
elmbed 17:d8b901d791fd 642
elmbed 17:d8b901d791fd 643 if((ch == '\r' || ch == ';' || ch == '\n') && parameter != '_')
elmbed 17:d8b901d791fd 644 {
elmbed 17:d8b901d791fd 645 if(i > 1)
elmbed 17:d8b901d791fd 646 {
elmbed 17:d8b901d791fd 647 buffer[i-1] = 0;
elmbed 17:d8b901d791fd 648 value = atoi(buffer);
elmbed 17:d8b901d791fd 649
elmbed 17:d8b901d791fd 650 if(parameter == 'l')
elmbed 17:d8b901d791fd 651 value = strtoul(buffer, &endp, 2);
elmbed 17:d8b901d791fd 652 }
elmbed 18:affef3a7db2a 653
elmbed 17:d8b901d791fd 654 interpret(parameter, value);
elmbed 17:d8b901d791fd 655 DEBUG("After interp: '%c'\r\n", parameter);
elmbed 17:d8b901d791fd 656 parameter = '_';
elmbed 17:d8b901d791fd 657 buffer[0] = 0;
elmbed 17:d8b901d791fd 658 i=0;
elmbed 17:d8b901d791fd 659 }
elmbed 17:d8b901d791fd 660 else
elmbed 17:d8b901d791fd 661 {
elmbed 17:d8b901d791fd 662 if(i==0)
elmbed 17:d8b901d791fd 663 parameter = ch;
elmbed 17:d8b901d791fd 664 else
elmbed 17:d8b901d791fd 665 buffer[i-1] = ch;
elmbed 17:d8b901d791fd 666 i++;
elmbed 17:d8b901d791fd 667 }
elmbed 17:d8b901d791fd 668
elmbed 17:d8b901d791fd 669 if(ch == '_' || ch == '\r' || ch == ';' || ch == '\n')
elmbed 17:d8b901d791fd 670 {
elmbed 17:d8b901d791fd 671 parameter = '_';
elmbed 17:d8b901d791fd 672 buffer[0] = 0;
elmbed 17:d8b901d791fd 673 i=0;
elmbed 17:d8b901d791fd 674 }
elmbed 17:d8b901d791fd 675 }
elmbed 17:d8b901d791fd 676 }
elmbed 17:d8b901d791fd 677
elmbed 23:26f27c462976 678 static void interpret(char parameter, int value)
elmbed 17:d8b901d791fd 679 {
elmbed 18:affef3a7db2a 680 int remainder;
elmbed 18:affef3a7db2a 681 uint16_t split;
elmbed 18:affef3a7db2a 682 uint16_t t;
elmbed 18:affef3a7db2a 683 uint8_t c;
elmbed 18:affef3a7db2a 684 uint8_t l;
elmbed 18:affef3a7db2a 685 int last;
elmbed 18:affef3a7db2a 686 int middle;
elmbed 18:affef3a7db2a 687 uint8_t length;
elmbed 18:affef3a7db2a 688 uint8_t offset;
elmbed 18:affef3a7db2a 689 int i;
elmbed 18:affef3a7db2a 690 uint8_t v;
elmbed 18:affef3a7db2a 691 uint16_t val;
elmbed 17:d8b901d791fd 692
elmbed 17:d8b901d791fd 693 switch(parameter)
elmbed 17:d8b901d791fd 694 {
elmbed 17:d8b901d791fd 695 case 'f':
elmbed 17:d8b901d791fd 696 if(lonely)
elmbed 17:d8b901d791fd 697 {
elmbed 18:affef3a7db2a 698 writeToPhone("Sorry, no other cones detected, please try detecting cones first.\r\n");
elmbed 17:d8b901d791fd 699 break;
elmbed 17:d8b901d791fd 700 }
elmbed 18:affef3a7db2a 701
elmbed 18:affef3a7db2a 702 writeToPhone("Entered freeform\r\n");
elmbed 17:d8b901d791fd 703 mode = FREEFORM;
elmbed 17:d8b901d791fd 704 state_p = START_P;
elmbed 17:d8b901d791fd 705 clearCones();
elmbed 18:affef3a7db2a 706 //find_cones();
elmbed 17:d8b901d791fd 707 break;
elmbed 17:d8b901d791fd 708 case 'p':
elmbed 17:d8b901d791fd 709 if(value == 0)
elmbed 17:d8b901d791fd 710 {
elmbed 18:affef3a7db2a 711 writeToPhone("\r\n");
elmbed 18:affef3a7db2a 712 writeToPhone("Running pattern %d\r\n", active_sequence + 1);
elmbed 18:affef3a7db2a 713
elmbed 17:d8b901d791fd 714 mode = PATTERN;
elmbed 17:d8b901d791fd 715 state_p = START_P;
elmbed 17:d8b901d791fd 716 active_cone = 0;
elmbed 18:affef3a7db2a 717
elmbed 17:d8b901d791fd 718 clearCones();
elmbed 17:d8b901d791fd 719 }
elmbed 17:d8b901d791fd 720 else
elmbed 17:d8b901d791fd 721 {
elmbed 18:affef3a7db2a 722 writeToPhone("Selected pattern %d\r\n", value);
elmbed 18:affef3a7db2a 723
elmbed 17:d8b901d791fd 724 if(value <= SEQUENCES && value > 0)
elmbed 17:d8b901d791fd 725 {
elmbed 17:d8b901d791fd 726 active_sequence = value - 1;
elmbed 17:d8b901d791fd 727 cones = (uint8_t*)cone_table + (value-1)*STATIONS;
elmbed 17:d8b901d791fd 728 times = (uint16_t*)time_table + (value-1)*STATIONS;
elmbed 17:d8b901d791fd 729 masks = (uint8_t*)mask_table + (value-1)*STATIONS;
elmbed 17:d8b901d791fd 730 }
elmbed 17:d8b901d791fd 731 else
elmbed 17:d8b901d791fd 732 {
elmbed 18:affef3a7db2a 733 writeToPhone("This pattern is not available. Please select a value between 1 and %d", SEQUENCES);
elmbed 17:d8b901d791fd 734 }
elmbed 17:d8b901d791fd 735 }
elmbed 17:d8b901d791fd 736 break;
elmbed 17:d8b901d791fd 737 case 's':
elmbed 17:d8b901d791fd 738 station = value;
AntonLS 19:afcbb425b3cf 739 writeToPhone("Selected station %d\r\n", value);
elmbed 17:d8b901d791fd 740 break;
elmbed 17:d8b901d791fd 741 case 'd':
elmbed 18:affef3a7db2a 742 if(value == 0){
elmbed 17:d8b901d791fd 743 logging = false;
elmbed 17:d8b901d791fd 744 m->value = 0;
elmbed 17:d8b901d791fd 745 dist_timeout = micros() + 2000000;
elmbed 17:d8b901d791fd 746 }
elmbed 18:affef3a7db2a 747 if(value == 1){
elmbed 17:d8b901d791fd 748 logging = true;
elmbed 17:d8b901d791fd 749 m->value = 1;
elmbed 17:d8b901d791fd 750 }
elmbed 17:d8b901d791fd 751 m->command = 'd';
elmbed 17:d8b901d791fd 752 m->cone = TRILAT_CONE;
elmbed 17:d8b901d791fd 753 ta.send(m);
elmbed 18:affef3a7db2a 754 //Serial.print("Sent d");
elmbed 18:affef3a7db2a 755 //Serial.println(value);
elmbed 17:d8b901d791fd 756 break;
elmbed 17:d8b901d791fd 757 case 'c':
elmbed 17:d8b901d791fd 758 c = value;
elmbed 18:affef3a7db2a 759 writeToPhone("Station %d will be cone %d\r\n", station, value);
elmbed 18:affef3a7db2a 760 if(station <= STATIONS && station > 0)cones[station-1] = c;
elmbed 17:d8b901d791fd 761 break;
elmbed 17:d8b901d791fd 762 case 't':
elmbed 17:d8b901d791fd 763 t = (uint16_t)value;
elmbed 17:d8b901d791fd 764 remainder = t%1000;
AntonLS 19:afcbb425b3cf 765 writeToPhone("Station %d split time is: %d.%03d seconds.\r\n", station, t/1000, remainder);
AntonLS 19:afcbb425b3cf 766 /// if(remainder < 100)writeToPhone("0");
AntonLS 19:afcbb425b3cf 767 /// if(remainder < 10)writeToPhone("0");
AntonLS 19:afcbb425b3cf 768 /// writeToPhone("%d seconds.\r\n",remainder);
elmbed 18:affef3a7db2a 769 if(station <= STATIONS && station > 0)times[station-1] = t;
elmbed 17:d8b901d791fd 770 break;
elmbed 17:d8b901d791fd 771 case 'l':
elmbed 17:d8b901d791fd 772 l = 0;
elmbed 17:d8b901d791fd 773 l = (uint8_t)value;
elmbed 17:d8b901d791fd 774 masks[station-1] = l;
AntonLS 19:afcbb425b3cf 775 writeToPhone( "Station %d config bits: ", station );
AntonLS 19:afcbb425b3cf 776 writeBitsToPhone( l );
AntonLS 19:afcbb425b3cf 777 writeToPhone( "\r\n" );
elmbed 17:d8b901d791fd 778 break;
elmbed 17:d8b901d791fd 779 case 'q':
elmbed 17:d8b901d791fd 780 state_p = IDLE_P;
elmbed 17:d8b901d791fd 781 new_state = true; // force state reporting, even if we're already in IDLE
elmbed 23:26f27c462976 782 //ta.pulse_off();
elmbed 23:26f27c462976 783 //clearCones();
elmbed 17:d8b901d791fd 784 break;
elmbed 17:d8b901d791fd 785 case 'r':
elmbed 18:affef3a7db2a 786 //Serial.println(F(""));
AntonLS 19:afcbb425b3cf 787 writeToPhone("Current pattern is %d:\r\n", active_sequence+1);
elmbed 18:affef3a7db2a 788 for(int i=0; i<STATIONS; i++){
elmbed 18:affef3a7db2a 789 writeToPhone("Station %d: cone %d, ", i+1, cones[i]);
elmbed 17:d8b901d791fd 790 split = times[i];
AntonLS 19:afcbb425b3cf 791 printMsAsSeconds(split);
elmbed 18:affef3a7db2a 792 //Serial.print(F("s timeout, lights: "));
elmbed 18:affef3a7db2a 793 writeToPhone("s timeout, config bits: ");
elmbed 17:d8b901d791fd 794 l = masks[i];
elmbed 17:d8b901d791fd 795 /*
elmbed 18:affef3a7db2a 796 if(l<0b10000000)
elmbed 18:affef3a7db2a 797 writeToPhone("0");
elmbed 18:affef3a7db2a 798 if(l<0b1000000)
elmbed 18:affef3a7db2a 799 writeToPhone("0");
elmbed 18:affef3a7db2a 800 if(l<0b100000)
elmbed 18:affef3a7db2a 801 writeToPhone("0");
elmbed 18:affef3a7db2a 802 if(l<0b10000)
elmbed 18:affef3a7db2a 803 writeToPhone("0");
elmbed 18:affef3a7db2a 804 if(l<0b1000)
elmbed 18:affef3a7db2a 805 writeToPhone("0");
elmbed 18:affef3a7db2a 806 if(l<0b100)
elmbed 18:affef3a7db2a 807 writeToPhone("0");
elmbed 18:affef3a7db2a 808 if(l<0b10)
elmbed 18:affef3a7db2a 809 writeToPhone("0");
elmbed 18:affef3a7db2a 810 */
AntonLS 19:afcbb425b3cf 811 writeBitsToPhone( l, 3 );
AntonLS 19:afcbb425b3cf 812 writeToPhone( "\r\n" );
elmbed 18:affef3a7db2a 813 //Serial.println(l, BIN);
elmbed 17:d8b901d791fd 814 }
elmbed 17:d8b901d791fd 815 break;
elmbed 17:d8b901d791fd 816 case 'u':
elmbed 17:d8b901d791fd 817 // let any pending messages clear
elmbed 18:affef3a7db2a 818 while(ta.get_buffer_size()){
elmbed 17:d8b901d791fd 819 ta.spin();
elmbed 17:d8b901d791fd 820 }
elmbed 18:affef3a7db2a 821 if(value == 1){
elmbed 18:affef3a7db2a 822 writeToPhone("Course leader!\r\n");
elmbed 17:d8b901d791fd 823 powerupCones(value);
elmbed 17:d8b901d791fd 824 ta.powerup(value);
elmbed 17:d8b901d791fd 825 }
elmbed 18:affef3a7db2a 826 if(value == 2){
elmbed 18:affef3a7db2a 827 writeToPhone("Split leader!\r\n");
elmbed 17:d8b901d791fd 828 powerupCones(value);
elmbed 18:affef3a7db2a 829 //ta.powerup(value);
elmbed 17:d8b901d791fd 830 }
elmbed 18:affef3a7db2a 831 if(value > 10 && value < 5000){
elmbed 17:d8b901d791fd 832 ta.beep(value);
elmbed 17:d8b901d791fd 833 }
elmbed 17:d8b901d791fd 834 break;
elmbed 17:d8b901d791fd 835 case 'w':
elmbed 18:affef3a7db2a 836 if(value > 0 && value <= SEQUENCES){
elmbed 17:d8b901d791fd 837 length = STATIONS;
elmbed 17:d8b901d791fd 838 offset = (value - 1) * STATIONS;
elmbed 18:affef3a7db2a 839 writeToPhone("Saved sequence %d\r\n", value);
elmbed 17:d8b901d791fd 840 }
elmbed 18:affef3a7db2a 841 else{
elmbed 17:d8b901d791fd 842 length = STATIONS * SEQUENCES;
elmbed 17:d8b901d791fd 843 offset = 0;
elmbed 18:affef3a7db2a 844 writeToPhone("Saved all sequences.\r\n");
elmbed 17:d8b901d791fd 845 }
elmbed 18:affef3a7db2a 846 for(i=offset;i<length+offset;i++){
elmbed 18:affef3a7db2a 847 //eeprom_update_byte(addressConeTable + i, cone_table[i]);
elmbed 18:affef3a7db2a 848 //eeprom_update_byte(addressMaskTable + i, mask_table[i]);
elmbed 18:affef3a7db2a 849 //eeprom_update_word(addressTimeTable + i, time_table[i]);
elmbed 17:d8b901d791fd 850 }
elmbed 17:d8b901d791fd 851 break;
elmbed 17:d8b901d791fd 852 case 'x':
elmbed 17:d8b901d791fd 853 resetSensors();
elmbed 18:affef3a7db2a 854 //digitalWrite(A3, LOW);
elmbed 18:affef3a7db2a 855 //delay(100);
elmbed 18:affef3a7db2a 856 //digitalWrite(A3, HIGH);
elmbed 17:d8b901d791fd 857 break;
elmbed 17:d8b901d791fd 858
elmbed 17:d8b901d791fd 859 case 'z':
elmbed 17:d8b901d791fd 860 find_cones();
elmbed 18:affef3a7db2a 861 /*m->value = value;
elmbed 17:d8b901d791fd 862 m->command = 'z';
elmbed 17:d8b901d791fd 863 m->cone = 2;
elmbed 18:affef3a7db2a 864 Serial.println("sending...");
elmbed 17:d8b901d791fd 865 ta.send(m);
elmbed 18:affef3a7db2a 866 Serial.println("sent");*/
elmbed 17:d8b901d791fd 867 break;
elmbed 17:d8b901d791fd 868 }
elmbed 17:d8b901d791fd 869 }
elmbed 23:26f27c462976 870
elmbed 23:26f27c462976 871 static patternState_t stateFromCone(uint8_t cone)
elmbed 17:d8b901d791fd 872 {
elmbed 17:d8b901d791fd 873 if(cone == 0 || index == STATIONS)
elmbed 17:d8b901d791fd 874 return SUCCESS_P;
elmbed 17:d8b901d791fd 875 if(cone == 1)
elmbed 17:d8b901d791fd 876 return ACTIVE_TARGET_P;
elmbed 17:d8b901d791fd 877
elmbed 17:d8b901d791fd 878 return WAITING_P;
elmbed 17:d8b901d791fd 879 }
elmbed 17:d8b901d791fd 880
elmbed 23:26f27c462976 881 static void printSplit(unsigned long timer)
elmbed 17:d8b901d791fd 882 {
elmbed 17:d8b901d791fd 883 if(tag_start)
elmbed 17:d8b901d791fd 884 {
elmbed 17:d8b901d791fd 885 //DEBUG("Sequence started at cone ");
elmbed 17:d8b901d791fd 886 //DEBUG("%d",active_cone);
elmbed 17:d8b901d791fd 887 //DEBUG(" (");
elmbed 17:d8b901d791fd 888 printMsAsSeconds(timer);
elmbed 17:d8b901d791fd 889 //DEBUG(" seconds).\n");
elmbed 17:d8b901d791fd 890 tag_start = false;
elmbed 17:d8b901d791fd 891 }
elmbed 17:d8b901d791fd 892 else
elmbed 17:d8b901d791fd 893 {
elmbed 17:d8b901d791fd 894 //DEBUG("Target cone is: ");
elmbed 17:d8b901d791fd 895 //DEBUG("%d",active_cone);
elmbed 17:d8b901d791fd 896 //DEBUG(", ");
elmbed 17:d8b901d791fd 897 printMsAsSeconds(timer);
elmbed 17:d8b901d791fd 898 //DEBUG(" split");
elmbed 17:d8b901d791fd 899 }
elmbed 17:d8b901d791fd 900 }
elmbed 17:d8b901d791fd 901
elmbed 23:26f27c462976 902 static uint8_t getRandomCone(void)
elmbed 17:d8b901d791fd 903 {
elmbed 17:d8b901d791fd 904 static uint8_t lastCone = 0;
elmbed 17:d8b901d791fd 905 uint8_t cone;
elmbed 17:d8b901d791fd 906
elmbed 17:d8b901d791fd 907 do
elmbed 17:d8b901d791fd 908 {
elmbed 17:d8b901d791fd 909 cone = random(1, NUM_CONES + 1);
elmbed 17:d8b901d791fd 910 }
elmbed 17:d8b901d791fd 911 while(cone == lastCone || active_cones[cone] == false);
elmbed 17:d8b901d791fd 912
elmbed 17:d8b901d791fd 913 //DEBUG("Target cone is ");
elmbed 17:d8b901d791fd 914 //DEBUG("%d\n",cone);
elmbed 17:d8b901d791fd 915 lastCone = cone;
elmbed 17:d8b901d791fd 916 return cone;
elmbed 17:d8b901d791fd 917 }
elmbed 17:d8b901d791fd 918
elmbed 23:26f27c462976 919 static void clearCones(void)
elmbed 17:d8b901d791fd 920 {
elmbed 23:26f27c462976 921 #if 0
elmbed 17:d8b901d791fd 922 uint8_t i;
elmbed 17:d8b901d791fd 923 m->command = 'q';
elmbed 17:d8b901d791fd 924
elmbed 17:d8b901d791fd 925 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 926 {
elmbed 17:d8b901d791fd 927 m->cone = i;
elmbed 17:d8b901d791fd 928 if(active_cones[i])
elmbed 17:d8b901d791fd 929 ta.send(m);
elmbed 17:d8b901d791fd 930 active_cones[i] = false;
elmbed 17:d8b901d791fd 931 //ta.send("q", i);
elmbed 17:d8b901d791fd 932 }
elmbed 17:d8b901d791fd 933
elmbed 17:d8b901d791fd 934 DEBUG("sent clear\r\n");
elmbed 23:26f27c462976 935 #endif
elmbed 17:d8b901d791fd 936 }
elmbed 17:d8b901d791fd 937
elmbed 23:26f27c462976 938 static void powerupCones(uint8_t sound)
elmbed 17:d8b901d791fd 939 {
elmbed 23:26f27c462976 940 #if 1
elmbed 17:d8b901d791fd 941 uint8_t i;
elmbed 17:d8b901d791fd 942 m->command = 'u';
elmbed 17:d8b901d791fd 943 m->value = sound;
elmbed 17:d8b901d791fd 944
elmbed 17:d8b901d791fd 945 if(sound == 2)
elmbed 17:d8b901d791fd 946 {
elmbed 17:d8b901d791fd 947 if(active_cone == ADDRESS)
elmbed 17:d8b901d791fd 948 {
elmbed 17:d8b901d791fd 949 ta.powerup(sound);
elmbed 17:d8b901d791fd 950 }
elmbed 17:d8b901d791fd 951 else
elmbed 17:d8b901d791fd 952 {
elmbed 17:d8b901d791fd 953 m->cone = active_cone;
elmbed 17:d8b901d791fd 954 ta.send(m);
elmbed 17:d8b901d791fd 955 }
elmbed 17:d8b901d791fd 956 }
elmbed 17:d8b901d791fd 957 else
elmbed 17:d8b901d791fd 958 {
elmbed 17:d8b901d791fd 959 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 960 {
elmbed 17:d8b901d791fd 961 m->cone = i;
elmbed 17:d8b901d791fd 962 if(active_cones[i])
elmbed 17:d8b901d791fd 963 ta.send(m);
elmbed 17:d8b901d791fd 964 //ta.send("f", i);
elmbed 17:d8b901d791fd 965 }
elmbed 17:d8b901d791fd 966 }
elmbed 23:26f27c462976 967 #endif
elmbed 17:d8b901d791fd 968 //DEBUG("sent powerup");
elmbed 17:d8b901d791fd 969 }
elmbed 17:d8b901d791fd 970
elmbed 23:26f27c462976 971 static void failCones(void)
elmbed 17:d8b901d791fd 972 {
elmbed 23:26f27c462976 973 #if 0
elmbed 17:d8b901d791fd 974 uint8_t i;
elmbed 17:d8b901d791fd 975 m->command = 'f';
elmbed 17:d8b901d791fd 976
elmbed 17:d8b901d791fd 977 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 978 {
elmbed 17:d8b901d791fd 979 m->cone = i;
elmbed 17:d8b901d791fd 980
elmbed 17:d8b901d791fd 981 if(active_cones[i])
elmbed 17:d8b901d791fd 982 ta.send(m);
elmbed 17:d8b901d791fd 983 //ta.send("f", i);
elmbed 17:d8b901d791fd 984 }
elmbed 17:d8b901d791fd 985
elmbed 17:d8b901d791fd 986 while(ta.get_buffer_size())
elmbed 17:d8b901d791fd 987 {
elmbed 17:d8b901d791fd 988 ta.spin();
elmbed 17:d8b901d791fd 989 }
elmbed 17:d8b901d791fd 990
elmbed 17:d8b901d791fd 991 //DEBUG("sent fail\n");
elmbed 23:26f27c462976 992 #endif
elmbed 17:d8b901d791fd 993 }
elmbed 17:d8b901d791fd 994
elmbed 23:26f27c462976 995 static void resetSensors(void)
elmbed 17:d8b901d791fd 996 {
elmbed 23:26f27c462976 997 #if 0
elmbed 17:d8b901d791fd 998 uint8_t i;
elmbed 17:d8b901d791fd 999 m->command = 'x';
elmbed 17:d8b901d791fd 1000
elmbed 17:d8b901d791fd 1001 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 1002 {
elmbed 17:d8b901d791fd 1003 m->cone = i;
elmbed 17:d8b901d791fd 1004 if(active_cones[i])
elmbed 17:d8b901d791fd 1005 ta.send(m);
elmbed 17:d8b901d791fd 1006 //ta.send("f", i);
elmbed 17:d8b901d791fd 1007 }
elmbed 17:d8b901d791fd 1008
elmbed 17:d8b901d791fd 1009 DEBUG("sent sensor reset\n");
elmbed 23:26f27c462976 1010 #endif
elmbed 17:d8b901d791fd 1011 }
elmbed 17:d8b901d791fd 1012
elmbed 23:26f27c462976 1013 static void successCones(void)
elmbed 17:d8b901d791fd 1014 {
elmbed 23:26f27c462976 1015 #if 0
elmbed 17:d8b901d791fd 1016 uint8_t i;
elmbed 17:d8b901d791fd 1017 m->command = 's';
elmbed 17:d8b901d791fd 1018
elmbed 17:d8b901d791fd 1019 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 1020 {
elmbed 17:d8b901d791fd 1021 m->cone = i;
elmbed 17:d8b901d791fd 1022 if(active_cones[i])
elmbed 17:d8b901d791fd 1023 ta.send(m);
elmbed 17:d8b901d791fd 1024 //ta.send("s", i);
elmbed 17:d8b901d791fd 1025 }
elmbed 17:d8b901d791fd 1026
elmbed 17:d8b901d791fd 1027 while(ta.get_buffer_size())
elmbed 17:d8b901d791fd 1028 {
elmbed 17:d8b901d791fd 1029 ta.spin();
elmbed 17:d8b901d791fd 1030 }
elmbed 17:d8b901d791fd 1031
elmbed 17:d8b901d791fd 1032 //DEBUG("sent success\n");
elmbed 23:26f27c462976 1033 #endif
elmbed 17:d8b901d791fd 1034 }
elmbed 17:d8b901d791fd 1035
elmbed 23:26f27c462976 1036 static void find_cones(void)
elmbed 17:d8b901d791fd 1037 {
elmbed 23:26f27c462976 1038 #if 1
elmbed 17:d8b901d791fd 1039 while(ta.get_buffer_size())
elmbed 23:26f27c462976 1040 {
elmbed 17:d8b901d791fd 1041 ta.spin(); // wait for all messages to leave queue
elmbed 23:26f27c462976 1042 }
elmbed 17:d8b901d791fd 1043
elmbed 23:26f27c462976 1044 ta.beep_off();
elmbed 17:d8b901d791fd 1045 uint8_t i;
elmbed 17:d8b901d791fd 1046 m->command = 'z';
elmbed 17:d8b901d791fd 1047
elmbed 17:d8b901d791fd 1048 lonely = true;
elmbed 17:d8b901d791fd 1049
elmbed 23:26f27c462976 1050 writeToPhone("Finding cones\r\n");
elmbed 23:26f27c462976 1051 //for (i=3; i <=3; ++i)
elmbed 17:d8b901d791fd 1052 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 1053 {
elmbed 17:d8b901d791fd 1054 active_cones[i] = false;
elmbed 17:d8b901d791fd 1055 m->cone = i;
elmbed 17:d8b901d791fd 1056 ta.send_immediate(m);
elmbed 17:d8b901d791fd 1057
elmbed 17:d8b901d791fd 1058 unsigned long st = millis();
elmbed 23:26f27c462976 1059 unsigned long current = 0;
elmbed 17:d8b901d791fd 1060 unsigned long delta = 0;
elmbed 17:d8b901d791fd 1061
elmbed 23:26f27c462976 1062 writeToPhone("start: %d\r\n", st);
elmbed 23:26f27c462976 1063
elmbed 17:d8b901d791fd 1064 while(1)
elmbed 17:d8b901d791fd 1065 {
elmbed 23:26f27c462976 1066 current = millis();
elmbed 23:26f27c462976 1067 delta = current - st;
elmbed 17:d8b901d791fd 1068
elmbed 23:26f27c462976 1069 if(delta > 5000L)
elmbed 23:26f27c462976 1070 {
elmbed 23:26f27c462976 1071 writeToPhone("Find timeout for: %d\r\n", i);
elmbed 17:d8b901d791fd 1072 break;
elmbed 23:26f27c462976 1073 }
elmbed 17:d8b901d791fd 1074
elmbed 23:26f27c462976 1075 //ta.spin();
elmbed 17:d8b901d791fd 1076
elmbed 17:d8b901d791fd 1077 if(ta.recieve(m_in))
elmbed 17:d8b901d791fd 1078 {
elmbed 17:d8b901d791fd 1079 lonely = false;
elmbed 17:d8b901d791fd 1080 active_cones[m_in->cone] = true;
elmbed 17:d8b901d791fd 1081
elmbed 23:26f27c462976 1082 writeToPhone("Reply from: %d\r\n", m_in->cone);
elmbed 17:d8b901d791fd 1083 DEBUG("Reply from cone: ");
elmbed 17:d8b901d791fd 1084 DEBUG("%d",m_in->cone);
elmbed 17:d8b901d791fd 1085 DEBUG(", ");
elmbed 17:d8b901d791fd 1086 DEBUG("%d",delta);
elmbed 17:d8b901d791fd 1087 DEBUG("ms\n");
elmbed 17:d8b901d791fd 1088 break;
elmbed 17:d8b901d791fd 1089 }
elmbed 17:d8b901d791fd 1090 }
elmbed 17:d8b901d791fd 1091 }
elmbed 17:d8b901d791fd 1092
elmbed 23:26f27c462976 1093 /*
elmbed 17:d8b901d791fd 1094 DEBUG("available cones are: (1");
elmbed 17:d8b901d791fd 1095
elmbed 17:d8b901d791fd 1096 for(i=2;i<NUM_CONES+1;i++)
elmbed 17:d8b901d791fd 1097 {
elmbed 17:d8b901d791fd 1098 if(active_cones[i])
elmbed 17:d8b901d791fd 1099 {
elmbed 17:d8b901d791fd 1100 DEBUG(", ");
elmbed 17:d8b901d791fd 1101 DEBUG("%d",i);
elmbed 17:d8b901d791fd 1102 }
elmbed 17:d8b901d791fd 1103 }
elmbed 17:d8b901d791fd 1104 DEBUG(")\r\n");
elmbed 23:26f27c462976 1105 */
elmbed 23:26f27c462976 1106 #endif
elmbed 17:d8b901d791fd 1107 }
elmbed 17:d8b901d791fd 1108
elmbed 23:26f27c462976 1109 static void printMsAsSeconds(unsigned long number)
elmbed 17:d8b901d791fd 1110 {
elmbed 17:d8b901d791fd 1111 uint16_t remainder;
elmbed 17:d8b901d791fd 1112
elmbed 17:d8b901d791fd 1113 //DEBUG("%d",number/1000);
elmbed 17:d8b901d791fd 1114 //DEBUG(".");
AntonLS 19:afcbb425b3cf 1115
elmbed 17:d8b901d791fd 1116 remainder = number%1000;
AntonLS 19:afcbb425b3cf 1117
elmbed 17:d8b901d791fd 1118 /*
elmbed 17:d8b901d791fd 1119 if(remainder < 100)
elmbed 17:d8b901d791fd 1120 //DEBUG("0");
elmbed 17:d8b901d791fd 1121
elmbed 17:d8b901d791fd 1122 if(remainder < 10)
elmbed 17:d8b901d791fd 1123 //DEBUG("0");
elmbed 17:d8b901d791fd 1124
elmbed 17:d8b901d791fd 1125 //DEBUG("%d",remainder);
elmbed 17:d8b901d791fd 1126 */
AntonLS 19:afcbb425b3cf 1127
AntonLS 19:afcbb425b3cf 1128 writeToPhone( "%d.%03d", number/1000, remainder );
elmbed 17:d8b901d791fd 1129 }
elmbed 17:d8b901d791fd 1130
elmbed 23:26f27c462976 1131 static void spinButtons(void)
elmbed 17:d8b901d791fd 1132 {
elmbed 17:d8b901d791fd 1133 static inputState_t last_state = IDLE_I;
elmbed 17:d8b901d791fd 1134 static bool first_i; // first should be true when we first enter a state (even if we just exited the same state)
elmbed 17:d8b901d791fd 1135 static Event event;
elmbed 17:d8b901d791fd 1136 static uint8_t sequence = 0;
elmbed 17:d8b901d791fd 1137 static unsigned long start = 0;
elmbed 17:d8b901d791fd 1138 uint8_t section = 0;
elmbed 17:d8b901d791fd 1139
elmbed 17:d8b901d791fd 1140 //uint8_t buttons;
elmbed 17:d8b901d791fd 1141
elmbed 17:d8b901d791fd 1142 //timer = millis() - start;
elmbed 17:d8b901d791fd 1143 if(millis() > 500)
elmbed 17:d8b901d791fd 1144 event = getInputEvent();
elmbed 17:d8b901d791fd 1145
elmbed 17:d8b901d791fd 1146 if(event.type == Event::press)
elmbed 17:d8b901d791fd 1147 {
elmbed 17:d8b901d791fd 1148 in_menu = true;
elmbed 17:d8b901d791fd 1149 state_i = MENU_I;
elmbed 17:d8b901d791fd 1150 }
elmbed 17:d8b901d791fd 1151
elmbed 17:d8b901d791fd 1152 first_i = false;
elmbed 17:d8b901d791fd 1153
elmbed 17:d8b901d791fd 1154 if(last_state != state_i)
elmbed 17:d8b901d791fd 1155 {
elmbed 17:d8b901d791fd 1156 //if(state_i == IDLE_I)////////////DEBUG.println(F("");
elmbed 17:d8b901d791fd 1157 //if(state_i == RUNNING_I)//////////////DEBUG.println(F("State is WAITING");
elmbed 17:d8b901d791fd 1158 // need to print menu timeout?
elmbed 17:d8b901d791fd 1159 if(state_i == MENU_I)
elmbed 17:d8b901d791fd 1160 ////DEBUG("Menu\n");
elmbed 17:d8b901d791fd 1161 if(state_i == PATTERN_SELECT_I)
elmbed 17:d8b901d791fd 1162 ////DEBUG("Choosing pattern");
elmbed 17:d8b901d791fd 1163 first_i = true;
elmbed 17:d8b901d791fd 1164 }
elmbed 17:d8b901d791fd 1165
elmbed 17:d8b901d791fd 1166 last_state = state_i;
elmbed 17:d8b901d791fd 1167
elmbed 17:d8b901d791fd 1168 if(state_i == RUNNING_I)
elmbed 17:d8b901d791fd 1169 in_menu = false;
elmbed 17:d8b901d791fd 1170
elmbed 17:d8b901d791fd 1171 switch(state_i)
elmbed 17:d8b901d791fd 1172 {
elmbed 17:d8b901d791fd 1173 case IDLE_I:
elmbed 17:d8b901d791fd 1174 // display something distinctive
elmbed 17:d8b901d791fd 1175 if(event.type == Event::tap)
elmbed 17:d8b901d791fd 1176 {
elmbed 17:d8b901d791fd 1177 state_i = RUNNING_I;
elmbed 17:d8b901d791fd 1178 //send 'p' or 'f' command as appropriate
elmbed 17:d8b901d791fd 1179 if(mode == FREEFORM)
elmbed 17:d8b901d791fd 1180 interpret('f', 0);
elmbed 17:d8b901d791fd 1181 else
elmbed 17:d8b901d791fd 1182 interpret('p', 0);
elmbed 17:d8b901d791fd 1183 }
elmbed 17:d8b901d791fd 1184 break;
elmbed 17:d8b901d791fd 1185 case RUNNING_I:
elmbed 17:d8b901d791fd 1186 if(event.type == Event::finish)
elmbed 17:d8b901d791fd 1187 state_i = IDLE_I;
elmbed 17:d8b901d791fd 1188 break;
elmbed 17:d8b901d791fd 1189 case MENU_I:
elmbed 17:d8b901d791fd 1190 if(first_i)
elmbed 17:d8b901d791fd 1191 interpret('q', 0);
elmbed 17:d8b901d791fd 1192 // every 3 seconds we cycle through the menu
elmbed 17:d8b901d791fd 1193 // one option per second
elmbed 17:d8b901d791fd 1194 // light changes color and stays on for 500ms
elmbed 17:d8b901d791fd 1195 section = ((millis() - start)%3000)/500;
elmbed 17:d8b901d791fd 1196
elmbed 17:d8b901d791fd 1197 if(section == 0)
elmbed 17:d8b901d791fd 1198 ta.post_color(0xFF);
elmbed 17:d8b901d791fd 1199 if(section == 1)
elmbed 17:d8b901d791fd 1200 ta.post_color(0);
elmbed 17:d8b901d791fd 1201 if(section == 2)
elmbed 17:d8b901d791fd 1202 ta.post_color(0xFF00);
elmbed 17:d8b901d791fd 1203 if(section == 3)
elmbed 17:d8b901d791fd 1204 ta.post_color(0);
elmbed 17:d8b901d791fd 1205 if(section == 4)
elmbed 17:d8b901d791fd 1206 ta.post_color(0xFF0000);
elmbed 17:d8b901d791fd 1207 if(section == 5)
elmbed 17:d8b901d791fd 1208 ta.post_color(0);
elmbed 17:d8b901d791fd 1209 if(event.type == Event::tap)
elmbed 17:d8b901d791fd 1210 {
elmbed 17:d8b901d791fd 1211 // set state here based on current light color
elmbed 17:d8b901d791fd 1212 if(section < 2)
elmbed 17:d8b901d791fd 1213 {
elmbed 17:d8b901d791fd 1214 mode = FREEFORM;
elmbed 17:d8b901d791fd 1215 ta.post_color(0xFF);
elmbed 17:d8b901d791fd 1216 ////////DEBUG.println(F("Freeform mode.");
elmbed 17:d8b901d791fd 1217 state_i = IDLE_I;
elmbed 17:d8b901d791fd 1218 break;
elmbed 17:d8b901d791fd 1219 }
elmbed 17:d8b901d791fd 1220
elmbed 17:d8b901d791fd 1221 if(section < 4)
elmbed 17:d8b901d791fd 1222 {
elmbed 17:d8b901d791fd 1223 mode = PATTERN;
elmbed 17:d8b901d791fd 1224 ta.post_color(0xFF00);
elmbed 17:d8b901d791fd 1225 ////////DEBUG.println(F("Pattern mode.");
elmbed 17:d8b901d791fd 1226 state_i = IDLE_I;
elmbed 17:d8b901d791fd 1227 break;
elmbed 17:d8b901d791fd 1228 }
elmbed 17:d8b901d791fd 1229
elmbed 17:d8b901d791fd 1230 if(section < 6)
elmbed 17:d8b901d791fd 1231 {
elmbed 17:d8b901d791fd 1232 state_i = PATTERN_SELECT_I;
elmbed 17:d8b901d791fd 1233 ta.post_color(0xFF0000);
elmbed 17:d8b901d791fd 1234 break;
elmbed 17:d8b901d791fd 1235 }
elmbed 17:d8b901d791fd 1236 }
elmbed 17:d8b901d791fd 1237 break;
elmbed 17:d8b901d791fd 1238 case PATTERN_SELECT_I:
elmbed 17:d8b901d791fd 1239 if(first_i)
elmbed 17:d8b901d791fd 1240 {
elmbed 17:d8b901d791fd 1241 sequence = active_sequence;
elmbed 17:d8b901d791fd 1242 mode = PATTERN;
elmbed 17:d8b901d791fd 1243 //start = millis();
elmbed 17:d8b901d791fd 1244 }
elmbed 17:d8b901d791fd 1245 if(event.type == Event::tap)
elmbed 17:d8b901d791fd 1246 {
elmbed 17:d8b901d791fd 1247 ta.beep(50);
elmbed 17:d8b901d791fd 1248 if(event.value == 1 && sequence > 0)
elmbed 17:d8b901d791fd 1249 {
elmbed 17:d8b901d791fd 1250 sequence--;
elmbed 17:d8b901d791fd 1251 }
elmbed 17:d8b901d791fd 1252
elmbed 17:d8b901d791fd 1253 if(event.value == 2 && sequence < SEQUENCES - 1)
elmbed 17:d8b901d791fd 1254 {
elmbed 17:d8b901d791fd 1255 sequence++;
elmbed 17:d8b901d791fd 1256 }
elmbed 17:d8b901d791fd 1257
elmbed 17:d8b901d791fd 1258 if(event.value == 3)
elmbed 17:d8b901d791fd 1259 {
elmbed 17:d8b901d791fd 1260 interpret('p', sequence + 1);
elmbed 17:d8b901d791fd 1261 state_i = IDLE_I;
elmbed 17:d8b901d791fd 1262 }
elmbed 17:d8b901d791fd 1263
elmbed 17:d8b901d791fd 1264 if(event.value != 3)
elmbed 17:d8b901d791fd 1265 {
elmbed 17:d8b901d791fd 1266 ////DEBUG("Menu says: sequence ");
elmbed 17:d8b901d791fd 1267 ////DEBUG("%d\n",sequence + 1);
elmbed 17:d8b901d791fd 1268 }
elmbed 17:d8b901d791fd 1269 break;
elmbed 17:d8b901d791fd 1270 case TEACH_I:
elmbed 17:d8b901d791fd 1271 // not implemented yet
elmbed 17:d8b901d791fd 1272 break;
elmbed 17:d8b901d791fd 1273 default: break;
elmbed 17:d8b901d791fd 1274 }
elmbed 17:d8b901d791fd 1275 }
elmbed 17:d8b901d791fd 1276 }
elmbed 17:d8b901d791fd 1277
elmbed 23:26f27c462976 1278 static uint8_t checkButtons(void)
elmbed 17:d8b901d791fd 1279 {
elmbed 17:d8b901d791fd 1280 static unsigned long last_time = 0;
elmbed 17:d8b901d791fd 1281 //static uint8_t last = 0;
elmbed 17:d8b901d791fd 1282 static uint8_t buttons = 0;
elmbed 17:d8b901d791fd 1283
elmbed 17:d8b901d791fd 1284 // listen for commands from the buttons
elmbed 17:d8b901d791fd 1285 unsigned long time = millis();
elmbed 17:d8b901d791fd 1286 // only check every DEBOUNCE_MS to avoid jitter
elmbed 17:d8b901d791fd 1287 if(time - last_time > DEBOUNCE_MS)
elmbed 17:d8b901d791fd 1288 {
elmbed 17:d8b901d791fd 1289 last_time = time;
elmbed 17:d8b901d791fd 1290 buttons = ta.buttons();
elmbed 17:d8b901d791fd 1291 }
elmbed 17:d8b901d791fd 1292
elmbed 17:d8b901d791fd 1293 return buttons;
elmbed 17:d8b901d791fd 1294 }
elmbed 17:d8b901d791fd 1295
elmbed 23:26f27c462976 1296 static Event getInputEvent(void)
elmbed 17:d8b901d791fd 1297 {
elmbed 17:d8b901d791fd 1298 static uint8_t last_buttons = 0;
elmbed 17:d8b901d791fd 1299 static unsigned long time1 = 0;
elmbed 17:d8b901d791fd 1300 static unsigned long time2 = 0;
elmbed 17:d8b901d791fd 1301 static unsigned long time3 = 0;
elmbed 17:d8b901d791fd 1302 unsigned long duration = 0;
elmbed 17:d8b901d791fd 1303 uint8_t buttons = 0;
elmbed 17:d8b901d791fd 1304 Event event;
elmbed 17:d8b901d791fd 1305 event.type = Event::none;
elmbed 17:d8b901d791fd 1306 event.value = 0;
elmbed 17:d8b901d791fd 1307
elmbed 17:d8b901d791fd 1308 buttons = checkButtons();
elmbed 17:d8b901d791fd 1309 uint8_t rising = buttons & ~last_buttons;
elmbed 17:d8b901d791fd 1310 uint8_t falling = ~buttons & last_buttons;
elmbed 17:d8b901d791fd 1311
elmbed 17:d8b901d791fd 1312 /*if(rising){
elmbed 17:d8b901d791fd 1313 //DEBUG.print("Rising ");
elmbed 17:d8b901d791fd 1314 //DEBUG.println(rising);
elmbed 17:d8b901d791fd 1315 }
elmbed 17:d8b901d791fd 1316 if(falling){
elmbed 17:d8b901d791fd 1317 //DEBUG.print("Falling ");
elmbed 17:d8b901d791fd 1318 //DEBUG.println(falling);
elmbed 17:d8b901d791fd 1319 }*/
elmbed 17:d8b901d791fd 1320 if(rising & 0x01)
elmbed 17:d8b901d791fd 1321 time1 = millis();
elmbed 17:d8b901d791fd 1322 if(rising & 0x02)
elmbed 17:d8b901d791fd 1323 time2 = millis();
elmbed 17:d8b901d791fd 1324 if(rising & 0x04)
elmbed 17:d8b901d791fd 1325 time3 = millis();
elmbed 17:d8b901d791fd 1326
elmbed 17:d8b901d791fd 1327 // simultaneous falling edges will cause lower values to be ignored
elmbed 17:d8b901d791fd 1328 if(falling & 0x01)
elmbed 17:d8b901d791fd 1329 {
elmbed 17:d8b901d791fd 1330 duration = millis() - time1;
elmbed 17:d8b901d791fd 1331 event.value = 1;
elmbed 17:d8b901d791fd 1332 }
elmbed 17:d8b901d791fd 1333
elmbed 17:d8b901d791fd 1334 if(falling & 0x02)
elmbed 17:d8b901d791fd 1335 {
elmbed 17:d8b901d791fd 1336 duration = millis() - time2;
elmbed 17:d8b901d791fd 1337 event.value = 2;
elmbed 17:d8b901d791fd 1338 }
elmbed 17:d8b901d791fd 1339
elmbed 17:d8b901d791fd 1340 if(falling & 0x04)
elmbed 17:d8b901d791fd 1341 {
elmbed 17:d8b901d791fd 1342 duration = millis() - time3;
elmbed 17:d8b901d791fd 1343 event.value = 3;
elmbed 17:d8b901d791fd 1344 }
elmbed 17:d8b901d791fd 1345
elmbed 17:d8b901d791fd 1346 if(duration > 0)
elmbed 17:d8b901d791fd 1347 event.type = Event::tap;
elmbed 17:d8b901d791fd 1348 if(duration > 2000)
elmbed 17:d8b901d791fd 1349 event.type = Event::press;
elmbed 17:d8b901d791fd 1350
elmbed 17:d8b901d791fd 1351 // give feedback that we've waited lng enough for a press
elmbed 17:d8b901d791fd 1352 unsigned long t = millis() - time1;
elmbed 17:d8b901d791fd 1353
elmbed 17:d8b901d791fd 1354 if(2020 > t && t > 2000 && (buttons & 0x01))
elmbed 17:d8b901d791fd 1355 ta.beep(20);
elmbed 17:d8b901d791fd 1356
elmbed 17:d8b901d791fd 1357 t = millis() - time2;
elmbed 17:d8b901d791fd 1358
elmbed 17:d8b901d791fd 1359 if(2020 > t && t > 2000 && (buttons & 0x02))
elmbed 17:d8b901d791fd 1360 ta.beep(20);
elmbed 17:d8b901d791fd 1361
elmbed 17:d8b901d791fd 1362 t = millis() - time3;
elmbed 17:d8b901d791fd 1363
elmbed 17:d8b901d791fd 1364 if(2020 > t && t > 2000 && (buttons & 0x04))
elmbed 17:d8b901d791fd 1365 ta.beep(20);
elmbed 17:d8b901d791fd 1366
elmbed 17:d8b901d791fd 1367 if(event.type != Event::none)
elmbed 17:d8b901d791fd 1368 {
elmbed 17:d8b901d791fd 1369 //DEBUG("Event: ");
elmbed 17:d8b901d791fd 1370 if(event.type == Event::tap)
elmbed 17:d8b901d791fd 1371 ////DEBUG("tap, ");
elmbed 17:d8b901d791fd 1372 if(event.type == Event::press)
elmbed 17:d8b901d791fd 1373 ////DEBUG("press, ");
elmbed 17:d8b901d791fd 1374
elmbed 17:d8b901d791fd 1375 uint8_t val = event.value;
elmbed 17:d8b901d791fd 1376 //DEBUG("%d\n",val);
elmbed 17:d8b901d791fd 1377 //////DEBUG.println(duration);
elmbed 17:d8b901d791fd 1378 }
elmbed 17:d8b901d791fd 1379
elmbed 17:d8b901d791fd 1380 last_buttons = buttons;
elmbed 17:d8b901d791fd 1381 return event;
elmbed 17:d8b901d791fd 1382 }
elmbed 18:affef3a7db2a 1383 #endif
elmbed 18:affef3a7db2a 1384
elmbed 18:affef3a7db2a 1385 #endif