Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of football_project by
proto_code.cpp
- Committer:
- AntonLS
- Date:
- 2015-12-01
- Revision:
- 19:afcbb425b3cf
- Parent:
- 18:affef3a7db2a
- Child:
- 23:26f27c462976
File content as of revision 19:afcbb425b3cf:
#include <TA.h>
#include <types.h>
#define RED p3
#define GREEN p5
#define BLUE p6
#define ENABLE_1 p4
#define ENABLE_2 p7
#define ENABLE_3 p8
#define DEBUG_BAUD 57600 //57600
#define ADDRESS 1
#define MAX_LEN 24 // buffer input commands up to this length
#define NUM_CONES 6
#define STATIONS 20 // max length of a pattern
#define SEQUENCES 9 // number of patterns to store
#define TRILAT_CONE 99
#define DEBOUNCE_MS 100
#define LIGHTS 0x07
#define FAKEOUT 0x08
#define FAIL_QUICK 0x10
#define SILENT 0x20
#define GRACE_PERIOD 3000
#define NEED_CONSOLE_OUTPUT 1 /* Set this if you need //////////////////////DEBUG messages on the console;
* it will have an impact on code-size and power consumption. */
#define LOOPBACK_MODE 0 // Loopback mode
#if NEED_CONSOLE_OUTPUT
#define DEBUG(...) { printf(__VA_ARGS__); }
#else
#define DEBUG(...) /* nothing */
#endif /* #if NEED_CONSOLE_OUTPUT */
#if 1
extern int random(int numberone, int numbertwo);
unsigned long millis();
unsigned long micros();
TA ta;
static bool active_cones[NUM_CONES + 1]; // + 1 so we can be 1 based like the cone numbers are
static Mode_t mode = PATTERN;
static patternState_t state_p = IDLE_P;
static inputState_t state_i = IDLE_I;
static Message m1 = { 'm',0,2 };
static Message *m = &m1;
static Message m2 = { 'm',0,2 };
static Message *m_in = &m2;
static uint8_t active_cone = 0;
static unsigned long timeout = 0;
static uint8_t mask = 0x07;
static uint8_t fakeout = 0;
static uint8_t fail_quick = 0;
static uint8_t index = 0;
static bool new_state = false;
static bool tag_start = false; // flag to indicate we should wait for the user to activate the first station before going through the sequence
static bool in_menu = false;
static bool warning = false;
static bool penalty = false;
static bool logging = false;
// course setup (probably should make some of these persistant settings)
static uint8_t active_sequence = 0;
static uint8_t station = 1;
static uint8_t cone = 0;
static uint16_t ltime = 0;
volatile bool triggered;
volatile bool pin;
volatile bool ping = false;
static volatile bool captured = false;
static volatile unsigned long ping_timer = 0;
static volatile unsigned long dist_timeout = 0;
// all sequence data
uint8_t cone_table[STATIONS * SEQUENCES];
uint8_t mask_table[STATIONS * SEQUENCES];
uint16_t time_table[STATIONS * SEQUENCES];
// pointer to active table
uint8_t *cones = (uint8_t*)cone_table;
uint8_t *masks = (uint8_t*)mask_table;
uint16_t *times = (uint16_t*)time_table;
static bool lonely = false;
// Function prototypes
void spin();
patternState_t stateFromCone(uint8_t cone);
void printSplit(unsigned long timer);
uint8_t getRandomCone(void);
void clearCones(void);
void powerupCones(uint8_t sound);
void failCones(void);
void resetSensors(void);
void successCones(void);
void find_cones(void);
void printMsAsSeconds(unsigned long number);
void spinButtons(void);
uint8_t checkButtons(void);
Event getInputEvent(void);
void getRadioInput(char *ibuffer, int size);
void interpret(char parameter, int value);
char local_input[50] = {0};
//DigitalOut red(RED);
//DigitalOut enable1(ENABLE_1);
//DigitalOut green(GREEN);
//DigitalOut blue(BLUE);
//DigitalOut enable2(ENABLE_2);
//DigitalOut enable3(ENABLE_3);
void setup()
{
ta.initialize(ADDRESS);
uint16_t sent = 0;
uint16_t lost = 0;
unsigned long start = micros();
//while (millis() - now <= ACK_TIME){
m->command = 'p';
m->value = 0;
m->cone = 0;
find_cones(); // this causes the beep to be interrupted
ta.beep(100);
int i;
for(i=1;i<NUM_CONES+1;i++)active_cones[i] = true;
unsigned long time = 0;
// pull course sequences from non-volatile memory
for(uint8_t i=0;i<STATIONS * SEQUENCES;i++){
cone_table[i] = i+1;
mask_table[i] = 1;
time_table[i] = 1000;
}
ta.post_color(0xFF0000);
}
void loop()
{
static Mode_t last_mode = mode;
last_mode = mode;
//ta.spin();
DEBUG("spinning");
//spinButtons();
//if((logging || micros() < dist_timeout) && ta.recieve(m_in))
// //////DEBUG("%c",m_in->command);
//else
spin();
}
void getNext()
{
if(mode == FREEFORM)
{
DEBUG("get next freeform\r\n");
++active_cone;//getRandomCone();
if (active_cone > 6)
{
active_cone = 1;
}
mask = 0x07;
ta.setMask(mask & LIGHTS);
timeout = ~0;
return;
}
active_cone = cones[index];
mask = masks[index];
fakeout = mask & FAKEOUT;
fail_quick = mask & FAIL_QUICK;
timeout = times[index];
index++;
DEBUG("Next cone is \n");
DEBUG("%d\n",active_cone);
}
#if 1
void spin()
{
static patternState_t last_state = START_P;
static uint8_t last_cone = 255;
static unsigned long start;
static unsigned long timer;
static bool first; // first should be true when we first enter a state (even if we just exited the same state)
char command = 'n';
unsigned long value = 0;
m_in->command = 0;
m_in->value = 0;
m_in->cone = 0;
if(ta.recieve(m_in))
{
DEBUG("spin received: %d '%c'\r\n", m_in->cone, m_in->command);
command = m_in->command;
value = m_in->value;
}
first = false;
if(last_state != state_p || new_state)
{
if(state_p == START_P)
DEBUG("State is START\n");
if(state_p == WAITING_P)
DEBUG("State is WAITING\n");
if(state_p == ACTIVE_TARGET_P)
DEBUG("State is ACTIVE_TARGET\n");
if(state_p == IDLE_P)
DEBUG("State is IDLE\n");
if(state_p == FAIL_P)
DEBUG("State is FAIL\n");
if(state_p == SUCCESS_P)
DEBUG("State is SUCCESS)\n");
first = true;
new_state = false;
}
last_state = state_p;
last_cone = active_cone;
timer = millis() - start;
switch(state_p)
{
case IDLE_P:
if(!in_menu)
ta.post_color((ta.activated())?0xFF:0xFF0000);
break;
case START_P:
//clearCones();
tag_start = false;
ta.post_color(0xFF0000);
index = 0;
getNext();
if(timeout == 0)
{ // timeout of 0 means wait indefinitely for the first cone to be activated, then start the rest of the sequence
timeout = ~0;
tag_start = true;
DEBUG("Activate cone ");
DEBUG("%d",active_cone);
DEBUG(" to start.\n");
}
start = millis();
state_p = stateFromCone(active_cone);
if(active_cone == 0)
{ // in this case stateFromCone returns SUCCESS_P, but really there was no course sequence
DEBUG("\n");
DEBUG("Empty course sequence!\n");
ta.post_color(0x0000FF);
state_p = IDLE_P;
break;
}
break;
case WAITING_P:
if(first)
{
m->command = 'm';
m->value = mask;
m->cone = active_cone;
ta.send(m);
m->command = 't';
m->value = (uint32_t)timeout;
ta.send(m);
m->command = 'g';
ta.send(m);
DEBUG("m_in cone=%d\n", active_cone);
m_in->cone = active_cone;
command = 'd';
}
ta.post_color(( ta.activated())?0xFF:0xFF0000);
DEBUG("Waiting: %d %d %c\n", m_in->cone, active_cone, command);
if((m_in->cone == active_cone && command == 'd' ) || ((timer >= timeout) && fakeout))
{
if((timer >= timeout) && !fakeout)
{
DEBUG("Timesplit penalty! ");
}
printSplit(timer);
getNext();
start = millis();
state_p = stateFromCone(active_cone);
if(state_p == WAITING_P)
{
DEBUG("New state from waiting\n");
new_state = true;
}
}
else if(~timeout != 0 && mode == PATTERN && timer >= (timeout + ((fail_quick)?0:GRACE_PERIOD)))
{
DEBUG("Failing from wait\n");
state_p = FAIL_P;
}
break;
case ACTIVE_TARGET_P:
if(first)
{
ta.setMask(mask);
warning = false;
penalty = false;
ta.pulse(50,750,~0L,0x00FF00);
//if(!(mask & SILENT))ta.pulse(50,750,~0L,0c00FF00);
}
if(timer >= timeout)
{
if(!penalty)
{
ta.pulse(50,325,~0L,0xFF00FF);
penalty = true;
}
ta.mask_color(0xFF00FF);
}
else if(timer > ((timeout*3)/4) && !warning)
{
warning = true;
ta.pulse(50,750,~0L,0xFFFF00);
}
if(ta.activated() || ((timer >= timeout) && fakeout))
{
if((timer >= timeout) && !fakeout)
DEBUG("Timesplit penalty! ");
printSplit(timer);
ta.post_color(0xFF0000);
getNext();
start = millis();
state_p = stateFromCone(active_cone);
if(state_p == ACTIVE_TARGET_P)
new_state = true;
ta.pulse_off();
}
else if(~timeout != 0 && mode == PATTERN && timer >= (timeout + ((fail_quick)?0:GRACE_PERIOD)))
{
state_p = FAIL_P;
ta.pulse_off();
}
//DEBUG.println(timeout + ((fail_quick)?0:GRACE_PERIOD));
//DEBUG.println(timeout);
break;
case FAIL_P:
if(first)
{
start = millis();
DEBUG("\n");
DEBUG("Timeout\n");
//ta.post_color();
ta.pulse(25,200,3000,0xFF0000);
failCones();
//ta.fail();
}
else if(timer > 3000)
{
DEBUG("Clear!\n");
state_p = IDLE_P;
clearCones();
}
break;
case SUCCESS_P:
if(first)
{
start = millis();
DEBUG("\n");
DEBUG("Done!\n");
ta.post_color(0x00FF00);
ta.beep(1500);
successCones();
//ta.success();
}
else if(timer > 1500)
{
DEBUG("Clear!\n");
state_p = IDLE_P;
clearCones();
}
break;
default:
break;
}
}
#endif
#if 0
void clearCones()
{
}
void find_cones()
{
}
void powerupCones(unsigned char c)
{
}
void resetSensors()
{
}
void printMsAsSeconds(unsigned long)
{
}
#endif
void getRadioInput(char *ibuffer, int size)
{
static int i = 0;
int buffer_counter = 0;
static char parameter = '_';
static char buffer[MAX_LEN + 1];
int value = 0;
char *endp = NULL;
// listen for commands coming over bluetooth
while (buffer_counter < size)
{
char ch = ibuffer[buffer_counter++];
if((ch == '\r' || ch == ';' || ch == '\n') && parameter != '_')
{
if(i > 1)
{
buffer[i-1] = 0;
value = atoi(buffer);
if(parameter == 'l')
value = strtoul(buffer, &endp, 2);
}
interpret(parameter, value);
DEBUG("After interp: '%c'\r\n", parameter);
parameter = '_';
buffer[0] = 0;
i=0;
}
else
{
if(i==0)
parameter = ch;
else
buffer[i-1] = ch;
i++;
}
if(ch == '_' || ch == '\r' || ch == ';' || ch == '\n')
{
parameter = '_';
buffer[0] = 0;
i=0;
}
}
}
void interpret(char parameter, int value)
{
int remainder;
uint16_t split;
uint16_t t;
uint8_t c;
uint8_t l;
int last;
int middle;
uint8_t length;
uint8_t offset;
int i;
uint8_t v;
uint16_t val;
switch(parameter)
{
case 'f':
if(lonely)
{
writeToPhone("Sorry, no other cones detected, please try detecting cones first.\r\n");
break;
}
writeToPhone("Entered freeform\r\n");
mode = FREEFORM;
state_p = START_P;
clearCones();
//find_cones();
break;
case 'p':
if(value == 0)
{
writeToPhone("\r\n");
writeToPhone("Running pattern %d\r\n", active_sequence + 1);
mode = PATTERN;
state_p = START_P;
active_cone = 0;
clearCones();
}
else
{
writeToPhone("Selected pattern %d\r\n", value);
if(value <= SEQUENCES && value > 0)
{
active_sequence = value - 1;
cones = (uint8_t*)cone_table + (value-1)*STATIONS;
times = (uint16_t*)time_table + (value-1)*STATIONS;
masks = (uint8_t*)mask_table + (value-1)*STATIONS;
}
else
{
writeToPhone("This pattern is not available. Please select a value between 1 and %d", SEQUENCES);
}
}
break;
case 's':
station = value;
writeToPhone("Selected station %d\r\n", value);
break;
case 'd':
if(value == 0){
logging = false;
m->value = 0;
dist_timeout = micros() + 2000000;
}
if(value == 1){
logging = true;
m->value = 1;
}
m->command = 'd';
m->cone = TRILAT_CONE;
ta.send(m);
//Serial.print("Sent d");
//Serial.println(value);
break;
case 'c':
c = value;
writeToPhone("Station %d will be cone %d\r\n", station, value);
if(station <= STATIONS && station > 0)cones[station-1] = c;
break;
case 't':
t = (uint16_t)value;
remainder = t%1000;
writeToPhone("Station %d split time is: %d.%03d seconds.\r\n", station, t/1000, remainder);
/// if(remainder < 100)writeToPhone("0");
/// if(remainder < 10)writeToPhone("0");
/// writeToPhone("%d seconds.\r\n",remainder);
if(station <= STATIONS && station > 0)times[station-1] = t;
break;
case 'l':
l = 0;
l = (uint8_t)value;
masks[station-1] = l;
writeToPhone( "Station %d config bits: ", station );
writeBitsToPhone( l );
writeToPhone( "\r\n" );
break;
case 'q':
state_p = IDLE_P;
new_state = true; // force state reporting, even if we're already in IDLE
ta.pulse_off();
clearCones();
break;
case 'r':
//Serial.println(F(""));
writeToPhone("Current pattern is %d:\r\n", active_sequence+1);
for(int i=0; i<STATIONS; i++){
writeToPhone("Station %d: cone %d, ", i+1, cones[i]);
split = times[i];
printMsAsSeconds(split);
//Serial.print(F("s timeout, lights: "));
writeToPhone("s timeout, config bits: ");
l = masks[i];
/*
if(l<0b10000000)
writeToPhone("0");
if(l<0b1000000)
writeToPhone("0");
if(l<0b100000)
writeToPhone("0");
if(l<0b10000)
writeToPhone("0");
if(l<0b1000)
writeToPhone("0");
if(l<0b100)
writeToPhone("0");
if(l<0b10)
writeToPhone("0");
*/
writeBitsToPhone( l, 3 );
writeToPhone( "\r\n" );
//Serial.println(l, BIN);
}
break;
case 'u':
// let any pending messages clear
while(ta.get_buffer_size()){
ta.spin();
}
if(value == 1){
writeToPhone("Course leader!\r\n");
powerupCones(value);
ta.powerup(value);
}
if(value == 2){
writeToPhone("Split leader!\r\n");
powerupCones(value);
//ta.powerup(value);
}
if(value > 10 && value < 5000){
ta.beep(value);
}
break;
case 'w':
if(value > 0 && value <= SEQUENCES){
length = STATIONS;
offset = (value - 1) * STATIONS;
writeToPhone("Saved sequence %d\r\n", value);
}
else{
length = STATIONS * SEQUENCES;
offset = 0;
writeToPhone("Saved all sequences.\r\n");
}
for(i=offset;i<length+offset;i++){
//eeprom_update_byte(addressConeTable + i, cone_table[i]);
//eeprom_update_byte(addressMaskTable + i, mask_table[i]);
//eeprom_update_word(addressTimeTable + i, time_table[i]);
}
break;
case 'x':
resetSensors();
//digitalWrite(A3, LOW);
//delay(100);
//digitalWrite(A3, HIGH);
break;
case 'z':
find_cones();
/*m->value = value;
m->command = 'z';
m->cone = 2;
Serial.println("sending...");
ta.send(m);
Serial.println("sent");*/
break;
}
}
#if 1
patternState_t stateFromCone(uint8_t cone)
{
if(cone == 0 || index == STATIONS)
return SUCCESS_P;
if(cone == 1)
return ACTIVE_TARGET_P;
return WAITING_P;
}
void printSplit(unsigned long timer)
{
if(tag_start)
{
//DEBUG("Sequence started at cone ");
//DEBUG("%d",active_cone);
//DEBUG(" (");
printMsAsSeconds(timer);
//DEBUG(" seconds).\n");
tag_start = false;
}
else
{
//DEBUG("Target cone is: ");
//DEBUG("%d",active_cone);
//DEBUG(", ");
printMsAsSeconds(timer);
//DEBUG(" split");
}
}
uint8_t getRandomCone(void)
{
static uint8_t lastCone = 0;
uint8_t cone;
do
{
cone = random(1, NUM_CONES + 1);
}
while(cone == lastCone || active_cones[cone] == false);
//DEBUG("Target cone is ");
//DEBUG("%d\n",cone);
lastCone = cone;
return cone;
}
void clearCones(void)
{
uint8_t i;
m->command = 'q';
for(i=2;i<NUM_CONES+1;i++)
{
m->cone = i;
if(active_cones[i])
ta.send(m);
active_cones[i] = false;
//ta.send("q", i);
}
DEBUG("sent clear\r\n");
}
void powerupCones(uint8_t sound)
{
uint8_t i;
m->command = 'u';
m->value = sound;
if(sound == 2)
{
if(active_cone == ADDRESS)
{
ta.powerup(sound);
}
else
{
m->cone = active_cone;
ta.send(m);
}
}
else
{
for(i=2;i<NUM_CONES+1;i++)
{
m->cone = i;
if(active_cones[i])
ta.send(m);
//ta.send("f", i);
}
}
//DEBUG("sent powerup");
}
void failCones(void)
{
uint8_t i;
m->command = 'f';
for(i=2;i<NUM_CONES+1;i++)
{
m->cone = i;
if(active_cones[i])
ta.send(m);
//ta.send("f", i);
}
while(ta.get_buffer_size())
{
ta.spin();
}
//DEBUG("sent fail\n");
}
void resetSensors(void)
{
uint8_t i;
m->command = 'x';
for(i=2;i<NUM_CONES+1;i++)
{
m->cone = i;
if(active_cones[i])
ta.send(m);
//ta.send("f", i);
}
DEBUG("sent sensor reset\n");
}
void successCones(void)
{
uint8_t i;
m->command = 's';
for(i=2;i<NUM_CONES+1;i++)
{
m->cone = i;
if(active_cones[i])
ta.send(m);
//ta.send("s", i);
}
while(ta.get_buffer_size())
{
ta.spin();
}
//DEBUG("sent success\n");
}
void find_cones(void)
{
while(ta.get_buffer_size())
ta.spin(); // wait for all messages to leave queue
uint8_t i;
m->command = 'z';
lonely = true;
DEBUG("Finding cones\r\n");
for(i=2;i<NUM_CONES+1;i++)
{
active_cones[i] = false;
m->cone = i;
ta.send_immediate(m);
unsigned long st = millis();
unsigned long delta = 0;
while(1)
{
delta = millis() - st;
if(delta > 50)
break;
ta.spin();
if(ta.recieve(m_in))
{
lonely = false;
active_cones[m_in->cone] = true;
DEBUG("Reply from cone: ");
DEBUG("%d",m_in->cone);
DEBUG(", ");
DEBUG("%d",delta);
DEBUG("ms\n");
break;
}
}
}
DEBUG("available cones are: (1");
for(i=2;i<NUM_CONES+1;i++)
{
if(active_cones[i])
{
DEBUG(", ");
DEBUG("%d",i);
}
}
DEBUG(")\r\n");
}
void printMsAsSeconds(unsigned long number)
{
uint16_t remainder;
//DEBUG("%d",number/1000);
//DEBUG(".");
remainder = number%1000;
/*
if(remainder < 100)
//DEBUG("0");
if(remainder < 10)
//DEBUG("0");
//DEBUG("%d",remainder);
*/
writeToPhone( "%d.%03d", number/1000, remainder );
}
void spinButtons(void)
{
static inputState_t last_state = IDLE_I;
static bool first_i; // first should be true when we first enter a state (even if we just exited the same state)
static Event event;
static uint8_t sequence = 0;
static unsigned long start = 0;
uint8_t section = 0;
//uint8_t buttons;
//timer = millis() - start;
if(millis() > 500)
event = getInputEvent();
if(event.type == Event::press)
{
in_menu = true;
state_i = MENU_I;
}
first_i = false;
if(last_state != state_i)
{
//if(state_i == IDLE_I)////////////DEBUG.println(F("");
//if(state_i == RUNNING_I)//////////////DEBUG.println(F("State is WAITING");
// need to print menu timeout?
if(state_i == MENU_I)
////DEBUG("Menu\n");
if(state_i == PATTERN_SELECT_I)
////DEBUG("Choosing pattern");
first_i = true;
}
last_state = state_i;
if(state_i == RUNNING_I)
in_menu = false;
switch(state_i)
{
case IDLE_I:
// display something distinctive
if(event.type == Event::tap)
{
state_i = RUNNING_I;
//send 'p' or 'f' command as appropriate
if(mode == FREEFORM)
interpret('f', 0);
else
interpret('p', 0);
}
break;
case RUNNING_I:
if(event.type == Event::finish)
state_i = IDLE_I;
break;
case MENU_I:
if(first_i)
interpret('q', 0);
// every 3 seconds we cycle through the menu
// one option per second
// light changes color and stays on for 500ms
section = ((millis() - start)%3000)/500;
if(section == 0)
ta.post_color(0xFF);
if(section == 1)
ta.post_color(0);
if(section == 2)
ta.post_color(0xFF00);
if(section == 3)
ta.post_color(0);
if(section == 4)
ta.post_color(0xFF0000);
if(section == 5)
ta.post_color(0);
if(event.type == Event::tap)
{
// set state here based on current light color
if(section < 2)
{
mode = FREEFORM;
ta.post_color(0xFF);
////////DEBUG.println(F("Freeform mode.");
state_i = IDLE_I;
break;
}
if(section < 4)
{
mode = PATTERN;
ta.post_color(0xFF00);
////////DEBUG.println(F("Pattern mode.");
state_i = IDLE_I;
break;
}
if(section < 6)
{
state_i = PATTERN_SELECT_I;
ta.post_color(0xFF0000);
break;
}
}
break;
case PATTERN_SELECT_I:
if(first_i)
{
sequence = active_sequence;
mode = PATTERN;
//start = millis();
}
if(event.type == Event::tap)
{
ta.beep(50);
if(event.value == 1 && sequence > 0)
{
sequence--;
}
if(event.value == 2 && sequence < SEQUENCES - 1)
{
sequence++;
}
if(event.value == 3)
{
interpret('p', sequence + 1);
state_i = IDLE_I;
}
if(event.value != 3)
{
////DEBUG("Menu says: sequence ");
////DEBUG("%d\n",sequence + 1);
}
break;
case TEACH_I:
// not implemented yet
break;
default: break;
}
}
}
uint8_t checkButtons(void)
{
static unsigned long last_time = 0;
//static uint8_t last = 0;
static uint8_t buttons = 0;
// listen for commands from the buttons
unsigned long time = millis();
// only check every DEBOUNCE_MS to avoid jitter
if(time - last_time > DEBOUNCE_MS)
{
last_time = time;
buttons = ta.buttons();
}
return buttons;
}
Event getInputEvent(void)
{
static uint8_t last_buttons = 0;
static unsigned long time1 = 0;
static unsigned long time2 = 0;
static unsigned long time3 = 0;
unsigned long duration = 0;
uint8_t buttons = 0;
Event event;
event.type = Event::none;
event.value = 0;
buttons = checkButtons();
uint8_t rising = buttons & ~last_buttons;
uint8_t falling = ~buttons & last_buttons;
/*if(rising){
//DEBUG.print("Rising ");
//DEBUG.println(rising);
}
if(falling){
//DEBUG.print("Falling ");
//DEBUG.println(falling);
}*/
if(rising & 0x01)
time1 = millis();
if(rising & 0x02)
time2 = millis();
if(rising & 0x04)
time3 = millis();
// simultaneous falling edges will cause lower values to be ignored
if(falling & 0x01)
{
duration = millis() - time1;
event.value = 1;
}
if(falling & 0x02)
{
duration = millis() - time2;
event.value = 2;
}
if(falling & 0x04)
{
duration = millis() - time3;
event.value = 3;
}
if(duration > 0)
event.type = Event::tap;
if(duration > 2000)
event.type = Event::press;
// give feedback that we've waited lng enough for a press
unsigned long t = millis() - time1;
if(2020 > t && t > 2000 && (buttons & 0x01))
ta.beep(20);
t = millis() - time2;
if(2020 > t && t > 2000 && (buttons & 0x02))
ta.beep(20);
t = millis() - time3;
if(2020 > t && t > 2000 && (buttons & 0x04))
ta.beep(20);
if(event.type != Event::none)
{
//DEBUG("Event: ");
if(event.type == Event::tap)
////DEBUG("tap, ");
if(event.type == Event::press)
////DEBUG("press, ");
uint8_t val = event.value;
//DEBUG("%d\n",val);
//////DEBUG.println(duration);
}
last_buttons = buttons;
return event;
}
#endif
#endif
