Support multiple pr...
 
Notifications
Clear all

Support multiple pressed buttons for arduino button matrix

1 Posts
1 Users
0 Reactions
911 Views
(@bracket)
Active Member
Joined: 2 years ago
Posts: 2
Topic starter  

I built a button box with a toggle switch that I wanted to be part of a button matrix along with regular pushbuttons. When I realized SimHub's button matrix implementation only supported one button pressed at a time, I was sad, though I understood why:

On a basic button matrix, pressing three or more buttons at once can lead to "ghost" inputs from other buttons. However, if you only ever press two buttons at once, you'll never get ghosting.

Also, if you add diodes to the button matrix, you could read all the buttons at once with no ghosting. (But that's pretty advanced for this application)

Anyway, since I just had one toggle switch in my matrix and the rest were buttons, I figure I won't run into the ghosting problem, since I would rarely ever push two buttons at once while the switch was active. I rewrote SHButtonMatrix.h to support multiple buttons pressed at once (ghosting be damned), and thought I might share it here in hope that it might make it into the next version of SimHub.

#ifndef __SHBUTTONMATRIX_H__
#define __SHBUTTONMATRIX_H__

#include <Arduino.h>
#include "SHDebouncer.h"

typedef void(*SHButtonMatrixChanged) (int, byte);

class SHButtonMatrix {

private:

	SHButtonMatrixChanged shButtonChangedCallback;
	SHDebouncer debouncer;

	byte rowCount;
	byte colCount;
	byte * colPins;
	byte * rowPins;

	uint8_t lastPressedStates[8];
public:

	void begin(byte cols, byte rows, byte * col, byte * row, SHButtonMatrixChanged changedcallback) {

		debouncer.begin(10);
		rowCount = rows;
		colCount = cols;
		colPins = col;
		rowPins = row;

		for (int x = 0; x < rowCount; x++) {

			pinMode(rowPins[x], INPUT);
		}

		for (int x = 0; x < colCount; x++) {

			pinMode(colPins[x], INPUT_PULLUP);
		}

		shButtonChangedCallback = changedcallback;
	}

	void read() {
		if (debouncer.Debounce()) {

				for (int colIndex = 0; colIndex < colCount; colIndex++) {

					byte curCol = colPins[colIndex];
					pinMode(curCol, OUTPUT);
					digitalWrite(curCol, LOW);

					for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
						byte rowCol = rowPins[rowIndex];
						pinMode(rowCol, INPUT_PULLUP);

						uint8_t lastPressed = lastPressedStates[rowIndex] & (1 << colIndex);
						int pressed = digitalRead(rowCol) == LOW;

						int button = (rowIndex * colCount) + colIndex + 1;

						if(pressed && !(lastPressed)) {
							shButtonChangedCallback(button, 1);
							lastPressedStates[rowIndex] |= (1 << colIndex);
						} else if(lastPressed && !pressed) {
							shButtonChangedCallback(button, 0);
							lastPressedStates[rowIndex] &= ~(1 << colIndex);
						}
					}

					pinMode(curCol, INPUT);
				}
		}

		return;
	}
};

#endif

   
Quote
Share: