Changed pin names to match schematic and PCB per mickabrig7 Changed default pins numbers to match PCB Added ability to use digitalRead for IR sensors Changes tabs to 2 spaces (consistent with Arduino standard) Fixes build for 32U4 based processors (SerialOutput.h/.cpp is untested)
129 lines
3.0 KiB
C++
129 lines
3.0 KiB
C++
#include "Touchboard.h"
|
|
|
|
void Touchboard::scan()
|
|
{
|
|
// For each key, set multiplexers and poll both capacitive sensors simultaneously
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
digitalWrite(MUX_0, bitRead(i, 0));
|
|
digitalWrite(MUX_1, bitRead(i, 1));
|
|
digitalWrite(MUX_2, bitRead(i, 2));
|
|
|
|
unsigned int* values = sensor.sense(3);
|
|
|
|
// Store the values received from the sensor poll into their respective positions
|
|
keys[i] = values[0];
|
|
keys[i + 8] = values[1];
|
|
}
|
|
}
|
|
|
|
void Touchboard::calibrateKeys()
|
|
{
|
|
// Reset calibration data for all keys
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
em_averages[i] = 0;
|
|
neutral_values[i] = 0;
|
|
key_states[i] = false;
|
|
keys[i] = false;
|
|
}
|
|
|
|
for (int i = 0; i < CALIBRATION_SAMPLES; i++) {
|
|
// Repeatedly scan all keys
|
|
scan();
|
|
// Store the lowest read value as our baseline
|
|
for (int j = 0; j < 16; j++) {
|
|
if (keys[j] > neutral_values[j]) neutral_values[j] = keys[j];
|
|
}
|
|
}
|
|
// After calibration is complete, initialize the averages to the baseline values established previously
|
|
for (int i = 0; i < 16; i++) {
|
|
em_averages[i] = neutral_values[i];
|
|
}
|
|
}
|
|
|
|
bool Touchboard::update(int key)
|
|
{
|
|
int read_value = keys[key];
|
|
float new_average = alpha * read_value + (1 - alpha) * em_averages[key];
|
|
if (read_value - neutral_values[key] < deadzone)
|
|
{
|
|
// If we are in the deadzone, ignore any touch events, set the key to be untouched and update the moving average.
|
|
if (key_states[key])
|
|
em_averages[key] = neutral_values[key];
|
|
else
|
|
em_averages[key] = new_average;
|
|
key_states[key] = false;
|
|
}
|
|
else
|
|
{
|
|
//If we are outside of the deadzone:
|
|
if (read_value > em_averages[key] + threshold)
|
|
{
|
|
// If we just detected a touch, make the key touched, discard the previous moving average and trigger the callback.
|
|
em_averages[key] = read_value;
|
|
onKeyPress(key, key_states[key]);
|
|
key_states[key] = true;
|
|
}
|
|
else
|
|
{
|
|
// Otherwise, just update the average.
|
|
em_averages[key] = new_average;
|
|
}
|
|
}
|
|
return key_states[key];
|
|
}
|
|
|
|
void Touchboard::setThreshold(uint16_t threshold)
|
|
{
|
|
this->threshold = threshold;
|
|
EEPROM.put(0, threshold);
|
|
}
|
|
|
|
void Touchboard::setDeadzone(uint16_t deadzone)
|
|
{
|
|
this->deadzone = deadzone;
|
|
EEPROM.put(4, deadzone);
|
|
}
|
|
|
|
void Touchboard::setAlpha(float alpha)
|
|
{
|
|
this->alpha = alpha;
|
|
EEPROM.put(8, alpha);
|
|
}
|
|
|
|
int Touchboard::getThreshold()
|
|
{
|
|
return threshold;
|
|
}
|
|
|
|
int Touchboard::getDeadzone()
|
|
{
|
|
return deadzone;
|
|
}
|
|
|
|
float Touchboard::getAlpha()
|
|
{
|
|
return alpha;
|
|
}
|
|
|
|
float Touchboard::getEmAverages(int key)
|
|
{
|
|
return em_averages[key];
|
|
}
|
|
|
|
Touchboard::Touchboard(void(*keyPressCallback)(int, bool)) :
|
|
sensor(CapacitiveSensor(SEND, RECEIVE_1, RECEIVE_2)),
|
|
onKeyPress(keyPressCallback)
|
|
{
|
|
EEPROM.get(0, threshold);
|
|
EEPROM.get(4, deadzone);
|
|
EEPROM.get(8, alpha);
|
|
|
|
pinMode(MUX_0, OUTPUT);
|
|
pinMode(MUX_1, OUTPUT);
|
|
pinMode(MUX_2, OUTPUT);
|
|
|
|
calibrateKeys();
|
|
}
|