clean method to evaluate multiple switch changes in given time period

Hi,

I’m trying to figure out a clean way of evaluating whether a switch has changed from high to low or vice versa 4 times within 2 seconds. Currently I am doing as below, but I am wondering if anyone has any better ideas.

Thanks!

byte highswitchhist[5];
int numchanges=0;

highswitchhist[0]=digitalRead(highswitch);
for(int i=0; i++; i<100)
{
highswitchstate=digitalRead(highswitch);
if(highswitchstate =! highswitchhist[histpos])
{
histpos++;
highswitchhist[histpos]=highswitchstate;
}
}
for(int i=0;i++;i<4)
{
if(highswitchhist*=!highswitchhist[i+1]) numchanges++;*

  • }*
    if(numchanges>3)
    {
    do something
    }

Currently I am doing as below, but I am wondering if anyone has any better ideas.

How does that work? You have no idea how long the 100 iteration for loop takes to execute.

You need to define whether the time is more critical, or if the other other things loop is doing is more critical.

You can, each time the switch changes state, record when the change occured. If the interval is less than 2 seconds, increment a counter. If not, reset the counter to 1.

If the program is some sort of "How many times can you detect a switch change in 2 seconds" application, then you need a while loop, while now (= millis()) - then (millis() before the while loop starts) is less than 2000.

Something like below?

create a circular buffer size 4 and an index

volatile unsigned long buffer[4]; // todo good initial values
volatile uint8_t idx = 0;

create an interrupt routine that places the time in millis in the next buffer entry %4 .
Connect the switch to the interrupt routine (google Arduino AttachInterrupt)

void IRQ()
{
idx++;
if (idx == 4) idx = 0;
buffer[idx] = millis();
}

now you can check the buffer in your loop for the last 4 keypresses.

loop()
{

noInterrupts(); // disable
// check here
unsigned int delta = buffer[idx] - buffer[(idx+1)%4]; // delta in msec between last and last-3
if (delta < 2000) …

interrupts();

}

Woops, I of course forgot the ~20ms delay in the loop. Robtillart I'll check that out, Thanks.

I think the simplest way is below, any comments?

highswitchlaststate = digitalRead(highswitch);
for(int i=0;i < 100; i++)
{
highswitchstate = digitalRead(highswitch);
if(highswitchstate != highswitchlaststate)
{
numchanges++;
highswitchlaststate=highswitchstate;

}
delay(20);
}