The issue is, the user may press the button very fast and the blocking delay of 300 causes some button presses to be missed.
Is there a way to overcome this. Perhaps queue up the requests of keystrokes or do it some other non blocking way? not sure this is possible with an Arduino?
One way to approach this would be to record the value of millis() when the button press is detected, let's say in a variable called pressTime, then test for 300ms passing since the button press in loop...
I have a potentiometer with 8 'positions'. You can spin the pot in less than a seconds, but of course Arduino needs to spend 300millis sending each position of the pot to the host app.
So if you spin it fast, it only sends 1 or 2 positions because of the blocking when sending, as its not reading. So it needs to read all positions and then spend time 'later' sending each 300millisecond command.
When the pot becomes close to one of the trigger positions save the position number or the pot value in an array. Once the pot value stablises for a significant period send the position numbers or post positions
This or a variation of this is what I use for switch debouncing
const uint8_t pin = A0;
void setup()
{
Serial.begin(115200);
while(!Serial);
pinMode( pin , INPUT_PULLUP );
}
void loop()
{
static uint32_t stateChanged = 0;
uint32_t debouncePeriod = 10;
static int state = 1;
int reading = digitalRead( pin );
if ( reading != state ) stateChanged = millis();
state = reading;
if ( stateChanged && ( millis() - stateChanged ) >= debouncePeriod )
{
stateChanged = 0;
if ( state == 0 )
{
// Switch closed code here
}
else
{
// Switch open code here
}
}
}
it's more or less the same as the example from the IDE except I use the timer variable to double as a flag / state variable. it makes sense to my addled old brain and it works so I'm sticking with it.
Here's the version that demonstrates what I said in my other post
#include<Keyboard.h>
const uint8_t pin = A0;
void setup()
{
Serial.begin(115200);
while(!Serial);
pinMode( pin , INPUT_PULLUP );
}
void loop()
{
static uint32_t stateChanged = 0;
uint32_t debouncePeriod = 10;
static int state = 1;
static uint32_t pressTime = 0;
uint32_t pressPeriod = 300;
int reading = digitalRead( pin );
if ( reading != state ) stateChanged = millis();
state = reading;
if ( pressTime && ( millis() - pressTime ) >= pressPeriod )
{
pressTime = 0;
Keyboard.release('a');
}
if ( stateChanged && ( millis() - stateChanged ) >= debouncePeriod )
{
stateChanged = 0;
if ( state == 0 )
{
pressTime = millis();
Keyboard.write('a');
}
else
{
// Switch open code here
}
}
}
The difference between the two is basically just the addition of a timer not unlike the debounce timer
Circular buffer application? Create an array to hold the switch closures. When a closure is detected 'push' it into the buffer. Meanwhile, monitor the buffer and when there's a value in the first position pull it out and send to host. Do the time delay thing. Check first position, lather, rinse, repeat. delay() is not compatible with this sort of thing
Site search 'circular buffer', 'fifo'. There are libraries available to implement these concepts.