Morning, sorry I'm a total novice at this (about half an hour !) so please excuse my ignorance.
Currently the code looks like this (irrelevant parts removed so that it is small enough for the forum)
#define BUFFER_LENGTH 3 // 3 bytes gives us 24 samples
#define NUM_INPUTS 18 // 6 on the front + 12 on the back
#define TARGET_LOOP_TIME 744 // (1/56 seconds) / 24 samples = 744 microseconds per sample
#define MOUSE_MOVE_UP -1
#define MOUSE_MOVE_DOWN -2
#define MOUSE_MOVE_LEFT -3
#define MOUSE_MOVE_RIGHT -4
#include <Keyboard.h>
#include <Mouse.h>
#include "settings.h"
STRUCT
typedef struct {
byte pinNumber;
int keyCode;
byte measurementBuffer[BUFFER_LENGTH];
boolean oldestMeasurement;
byte bufferSum;
boolean pressed;
boolean prevPressed;
boolean isMouseMotion;
boolean isMouseButton;
boolean isKey;
}
MakeyMakeyInput;
MakeyMakeyInput inputs[NUM_INPUTS];
VARIABLES
int bufferIndex = 0;
byte byteCounter = 0;
byte bitCounter = 0;
int mouseMovementCounter = 0; // for sending mouse movement events at a slower interval
int pressThreshold;
int releaseThreshold;
boolean inputChanged;
int mouseHoldCount[NUM_INPUTS]; // used to store mouse movement hold data
int pinNumbers[NUM_INPUTS] = {
12, 8, 13, 15, 7, 6, // top of makey makey board
5, 4, 3, 2, 1, 0, // left side of female header, KEBYBOARD
23, 22, 21, 20, 19, 18 // right side of female header, MOUSE
};
const int inputLED_a = 9;
const int inputLED_b = 10;
const int inputLED_c = 11;
const int outputK = 14;
const int outputM = 16;
byte ledCycleCounter = 0;
int loopTime = 0;
int prevTime = 0;
int loopCounter = 0;
FUNCTIONS
void initializeArduino();
void initializeInputs();
void updateMeasurementBuffers();
void updateBufferSums();
void updateBufferIndex();
void updateInputStates();
void sendMouseButtonEvents();
void sendMouseMovementEvents();
void addDelay();
void cycleLEDs();
void danceLeds();
void updateOutLEDs();
SETUP
void setup()
{
initializeArduino();
initializeInputs();
danceLeds();
}
MAIN LOOP
void loop()
{
updateMeasurementBuffers();
updateBufferSums();
updateBufferIndex();
updateInputStates();
sendMouseButtonEvents();
sendMouseMovementEvents();
cycleLEDs();
updateOutLEDs();
addDelay();
}
INITIALIZE ARDUINO
void initializeArduino() {
#ifdef DEBUG
Serial.begin(9600); // Serial for debugging
#endif
for (int i=0; i<NUM_INPUTS; i++)
{
pinMode(pinNumbers[i], INPUT);
digitalWrite(pinNumbers[i], LOW);
}
pinMode(inputLED_a, INPUT);
pinMode(inputLED_b, INPUT);
pinMode(inputLED_c, INPUT);
digitalWrite(inputLED_a, LOW);
digitalWrite(inputLED_b, LOW);
digitalWrite(inputLED_c, LOW);
pinMode(outputK, OUTPUT);
pinMode(outputM, OUTPUT);
digitalWrite(outputK, LOW);
digitalWrite(outputM, LOW);
#ifdef DEBUG
delay(4000); // allow us time to reprogram in case things are freaking out
#endif
Keyboard.begin();
Mouse.begin();
}
INITIALIZE INPUTS
void initializeInputs() {
float thresholdPerc = SWITCH_THRESHOLD_OFFSET_PERC;
float thresholdCenterBias = SWITCH_THRESHOLD_CENTER_BIAS/50.0;
float pressThresholdAmount = (BUFFER_LENGTH * 8) * (thresholdPerc / 100.0);
float thresholdCenter = ( (BUFFER_LENGTH * 8) / 2.0 ) * (thresholdCenterBias);
pressThreshold = int(thresholdCenter + pressThresholdAmount);
releaseThreshold = int(thresholdCenter - pressThresholdAmount);
#ifdef DEBUG
Serial.println(pressThreshold);
Serial.println(releaseThreshold);
#endif
for (int i=0; i<NUM_INPUTS; i++) {
inputs[i].pinNumber = pinNumbers[i];
inputs[i].keyCode = keyCodes[i];
for (int j=0; j<BUFFER_LENGTH; j++) {
inputs[i].measurementBuffer[j] = 0;
}
inputs[i].oldestMeasurement = 0;
inputs[i].bufferSum = 0;
inputs[i].pressed = false;
inputs[i].prevPressed = false;
inputs[i].isMouseMotion = false;
inputs[i].isMouseButton = false;
inputs[i].isKey = false;
if (inputs[i].keyCode < 0) {
#ifdef DEBUG_MOUSE
Serial.println("GOT IT");
#endif
inputs[i].isMouseMotion = true;
}
else if ((inputs[i].keyCode == MOUSE_LEFT) || (inputs[i].keyCode == MOUSE_RIGHT)) {
inputs[i].isMouseButton = true;
}
else {
inputs[i].isKey = true;
}
#ifdef DEBUG
Serial.println(i);
#endif
}
}
UPDATE MEASUREMENT BUFFERS
void updateMeasurementBuffers() {
for (int i=0; i<NUM_INPUTS; i++) {
byte currentByte = inputs[i].measurementBuffer[byteCounter];
inputs[i].oldestMeasurement = (currentByte >> bitCounter) & 0x01;
boolean newMeasurement = digitalRead(inputs[i].pinNumber);
newMeasurement = !newMeasurement;
if (newMeasurement) {
currentByte |= (1<<bitCounter);
}
else {
currentByte &= ~(1<<bitCounter);
}
inputs[i].measurementBuffer[byteCounter] = currentByte;
}
}
UPDATE BUFFER SUMS
void updateBufferSums() {
for (int i=0; i<NUM_INPUTS; i++) {
byte currentByte = inputs[i].measurementBuffer[byteCounter];
boolean currentMeasurement = (currentByte >> bitCounter) & 0x01;
if (currentMeasurement) {
inputs[i].bufferSum++;
}
if (inputs[i].oldestMeasurement) {
inputs[i].bufferSum--;
}
}
}
UPDATE BUFFER INDEX
void updateBufferIndex() {
bitCounter++;
if (bitCounter == 8) {
bitCounter = 0;
byteCounter++;
if (byteCounter == BUFFER_LENGTH) {
byteCounter = 0;
}
}
}
UPDATE INPUT STATES
void updateInputStates() {
inputChanged = false;
for (int i=0; i<NUM_INPUTS; i++) {
inputs[i].prevPressed = inputs[i].pressed; // store previous pressed state (only used for mouse buttons)
if (inputs[i].pressed) {
if (inputs[i].bufferSum < releaseThreshold) {
inputChanged = true;
inputs[i].pressed = false;
if (inputs[i].isKey) {
Keyboard.release(inputs[i].keyCode);
}
if (inputs[i].isMouseMotion) {
mouseHoldCount[i] = 0; // input becomes released, reset mouse hold
}
}
else if (inputs[i].isMouseMotion) {
mouseHoldCount[i]++; // input remains pressed, increment mouse hold
}
}
else if (!inputs[i].pressed) {
if (inputs[i].bufferSum > pressThreshold) { // input becomes pressed
inputChanged = true;
inputs[i].pressed = true;
if (inputs[i].isKey) {
Keyboard.press(inputs[i].keyCode);
}
}
}
}
#ifdef DEBUG3
if (inputChanged) {
Serial.println("change");
}
#endif
}
ADD DELAY
void addDelay() {
loopTime = micros() - prevTime;
if (loopTime < TARGET_LOOP_TIME) {
int wait = TARGET_LOOP_TIME - loopTime;
delayMicroseconds(wait);
}
prevTime = micros();
#ifdef DEBUG_TIMING
if (loopCounter == 0) {
int t = micros()-prevTime;
Serial.println(t);
}
loopCounter++;
loopCounter %= 999;
#endif
}
if (keyPressed)
{
digitalWrite(outputK, HIGH);
TXLED1;
}
else
{
digitalWrite(outputK, LOW);
TXLED0;
}
if (mousePressed)
{
digitalWrite(outputM, HIGH);
RXLED1;
}
else
{
digitalWrite(outputM, LOW);
RXLED0;
}
}
Key assignment is done as such -
int keyCodes[NUM_INPUTS] = {
'w', // pin D5
'a', // pin D4
's', // pin D3
'd', // pin D2
'f', // pin D1
'g', // pin D0
};
For arguments sake, what I'd like to achieve is a trigger of pin D5 for example could select the video file associated with 'W' and then trigger an ENTER command, if that makes sense ?