Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Committer:
elmbed
Date:
Tue Nov 03 07:05:15 2015 +0000
Revision:
17:d8b901d791fd
Child:
18:affef3a7db2a
Removed the inter device radio link, sending data to phone causes crash

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