Files
Yona-W_OpeNITHM/Firmware/Touchboard.cpp
T
veroxzik 514ab9740b Updates to match PCB
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)
2019-04-18 23:17:19 -04:00

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();
}