Slightly tested --- the button matrix example. I stuck jumpers in 6 and 7 then put them in and out of 4 and 5.
I learned a bit about timing with this one. Answer was to run asynch between inputs and outputs.
// add-a-sketch_matrix_buttons 2018 by GoForSmoke @ Arduino.cc Forum
// Free for use, May 9/2018 by GFS. Compiled on Arduino IDE 1.6.9.
/* Button Debounce Example
This example requires a diode per button in the row&column matrix.
Each row and column pin has its own wire. Where they cross a button and diode
connect in series allowing current to flow from the row wire to th column wire
only. The diode is to allow multiple buttons pressed at once detected correctly.
OTOH for this test, jumper a row pin (2 or 3) to a column pin (4 or 5) while
watching serial monitor.
Yes I'm using a 16 bit micros timer to time fractions of millis as micros.
The button reader only reads 1 button per call so as to not block void loop().
Each button has a history byte that holds the last 8 reads with 256 possible
states but only 4 of them being significant.
0 is the button held down
255 is the button left up
127 is the buton transitioning from up to down, button just released.
128 is the button transititioning from down to up, button just pressed.
everything else is to be ignored as bounce.
For multiple buttons the between-reads time is reduced and each pin is read in
turn.
*/
// int r,s,t;
// byte a,b,c;
// matrix_buttons vars --- 2D matrix
const byte rows = 2; // test with 4 buttons or jumper
const byte cols = 2;
byte rowIdx, colIdx = 255;
byte buttonRowPin[ rows ] = { 6, 7 };
byte buttonColPin[ cols ] = { 4, 5 };
byte buttonHistory[ rows ][ cols ];
word markButtonTime; // 16-bit micros timers
const word waitButtonTime = 50; // micros, 50 us
// type word as micros can time across 65.535 millis before rollover, can be a few late
void matrixButtonsTask()
{
if ( word( micros()) - markButtonTime >= waitButtonTime ) // read occaisoinally
{
// iterate the row and column indexes
if ( ++colIdx >= cols ) // ++rowIdx pre-increments rowIdx before comparing to rows
{
colIdx = 0;
if ( ++rowIdx >= rows ) // ++rowIdx pre-increments rowIdx before comparing to rows
{
rowIdx = 0;
}
}
pinMode( buttonRowPin[ rowIdx ], INPUT_PULLUP ); // supplies weak 5V
pinMode( buttonColPin[ colIdx ], OUTPUT ); // is LOW, grounds pressed buttons
buttonHistory[ rowIdx ][ colIdx ] <<= 1; // shift history bits up 1 for the new read
buttonHistory[ rowIdx ][ colIdx ] += digitalRead( buttonRowPin[ rowIdx ] ); // read history streams through buttonHistory
markButtonTime = micros(); // gets the low 16 bits of micros(), time to 60 ms + margin
// digitalWrite( buttonRowPin[ rowIdx ], LOW ); // turn the weak 5V off
// pinMode( buttonRowPin[ rowIdx ], OUTPUT );
// delayMicroseconds( 10 ); // drain the wire
pinMode( buttonRowPin[ rowIdx ], INPUT );
pinMode( buttonColPin[ colIdx ], INPUT ); // was OUTPUT LOW
}
}
void setup()
{
Serial.begin( 115200 );
Serial.println( F( "\n\n\n Button Matrix Example, free by GoForSmoke\n" ));
for ( byte i = 0; i < rows; i++ )
{
pinMode( buttonRowPin[ i ], INPUT ); // mode INPUT pin is electrically neutral
for ( byte j = 0; j < cols; j++ )
{
if ( i == 0 ) // only set the column pins once
{
pinMode( buttonColPin[ j ], INPUT ); // mode INPUT pin is electrically neutral
}
buttonHistory[ i ][ j ] = 255; // all buttons start UP
}
}
};
void loop()
{
matrixButtonsTask();
/*
0 is the button held down
255 is the button left up
127 is the buton changing from up to down, button just released.
128 is the button changing from down to up, button just pressed.
everything else is to be ignored as bounce.
*/
static byte row, col;
switch ( buttonHistory[ row ][ col ] )
{
case 128 : // pin is HIGH in bit 7, LOW for 7 reads, up to down detected
buttonHistory[ row ][ col ] = 0; // change detected, make it into no change now
Serial.print( F( "button " ));
Serial.print( rowIdx );
Serial.print( F( ", " ));
Serial.print( colIdx );
Serial.print( F( " press detected " ));
Serial.println( millis());
break;
case 127 : // pin is LOW in bit 7, HIGH for 7 reads, down to up detected
buttonHistory[ row ][ col ] = 255; // change detected, make it into no change now
Serial.print( F( "button " ));
Serial.print( rowIdx );
Serial.print( F( ", " ));
Serial.print( colIdx );
Serial.print( F( " release detected " ));
Serial.println( millis());
break;
}
if ( ++col >= cols )
{
col = 0;;
if ( ++row >= rows )
{
row = 0;;
}
}
}