初始化提交
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#include "Arduino.h"
|
||||
#include "NoiselessTouchESP32.h"
|
||||
|
||||
#define struct_member_size(type, member) sizeof(((type *)0)->member)
|
||||
|
||||
NoiselessTouchESP32::NoiselessTouchESP32(uint8_t pin) {
|
||||
NoiselessTouchESP32(pin, 6, 3);
|
||||
}
|
||||
|
||||
NoiselessTouchESP32::NoiselessTouchESP32(uint8_t pin, uint8_t history_length, uint8_t hysteresis) {
|
||||
Touchdata touch = {
|
||||
pin : pin,
|
||||
history : { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
hist_len : _max(_min((uint8_t)struct_member_size(Touchdata, history), history_length), 1),
|
||||
hist_cur : 0,
|
||||
hysteresis : _max(_min(hysteresis, 63), 1),
|
||||
last : 0,
|
||||
last_event : 0,
|
||||
last_event_ms : 0
|
||||
};
|
||||
_data = touch;
|
||||
for( _data.hist_cur = 0; _data.hist_cur < _data.hist_len; _data.hist_cur++ ) {
|
||||
_data.history[_data.hist_cur] = touchRead(_data.pin);
|
||||
}
|
||||
_data.last = value_from_history();
|
||||
}
|
||||
|
||||
int NoiselessTouchESP32::value_from_history() {
|
||||
uint8_t minimum = _data.history[0];
|
||||
uint8_t maximum = _data.history[0];
|
||||
uint8_t mean = 0;
|
||||
uint32_t sum = 0;
|
||||
for( int i = 0; i < _data.hist_len; i++) {
|
||||
minimum = _min(minimum, _data.history[i]);
|
||||
maximum = _max(maximum, _data.history[i]);
|
||||
sum += _data.history[i];
|
||||
}
|
||||
mean = sum / _data.hist_len;
|
||||
//Serial.printf("mean: %d\n", mean);
|
||||
while( mean - minimum > _data.hysteresis || maximum - mean > _data.hysteresis ) {
|
||||
//Serial.printf("abs(%d - %d) = %d\n", maximum, minimum, abs(maximum - minimum));
|
||||
uint8_t ldelta = abs(mean - minimum);
|
||||
uint8_t udelta = abs(maximum - mean);
|
||||
uint8_t lbound = minimum + (ldelta/2);
|
||||
uint8_t ubound = maximum - (udelta/2);
|
||||
if( ldelta < udelta ) {
|
||||
lbound = minimum;
|
||||
} else {
|
||||
ubound = maximum;
|
||||
}
|
||||
//Serial.printf("Min: %d, Lower: %d, Mean: %d, Upper: %d, Max: %d\n", minimum, lbound, mean, ubound, maximum);
|
||||
sum = 0;
|
||||
uint8_t count = 0;
|
||||
minimum = ubound;
|
||||
maximum = lbound;
|
||||
for( int i = 0; i < _data.hist_len; i++) {
|
||||
if( lbound <= _data.history[i] && _data.history[i] <= ubound ) {
|
||||
minimum = _min(minimum, _data.history[i]);
|
||||
maximum = _max(maximum, _data.history[i]);
|
||||
sum += _data.history[i];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count == 0) {
|
||||
return mean;
|
||||
}
|
||||
mean = sum/count;
|
||||
}
|
||||
return mean;
|
||||
}
|
||||
|
||||
int NoiselessTouchESP32::read_raw_mean() {
|
||||
_data.hist_cur = (_data.hist_cur + 1) % _data.hist_len;
|
||||
_data.history[_data.hist_cur] = touchRead(_data.pin);
|
||||
return value_from_history();
|
||||
}
|
||||
|
||||
int NoiselessTouchESP32::read_with_hysteresis() {
|
||||
int val = read_raw_mean();
|
||||
//Serial.printf("last: %d, hysteresis: %d, new value: %d\n", _data.last, _data.hysteresis, val);
|
||||
if( val < _data.last - _data.hysteresis || _data.last + _data.hysteresis < val ) {
|
||||
_data.last = val;
|
||||
}
|
||||
return _data.last;
|
||||
}
|
||||
|
||||
int NoiselessTouchESP32::last_value() {
|
||||
return _data.last;
|
||||
}
|
||||
|
||||
int NoiselessTouchESP32::changed() {
|
||||
int last = _data.last;
|
||||
int val = read_with_hysteresis();
|
||||
if( val > last ) {
|
||||
_data.last_event = -1;
|
||||
_data.last_event_ms = millis();
|
||||
return -1;
|
||||
}
|
||||
if( val < last ) {
|
||||
_data.last_event = 1;
|
||||
_data.last_event_ms = millis();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool NoiselessTouchESP32::touched() {
|
||||
int last = _data.last;
|
||||
int val = read_with_hysteresis();
|
||||
if( val > last ) {
|
||||
if( millis()-_data.last_event_ms < 5000 && _data.last_event == -1 ) {
|
||||
return false;
|
||||
}
|
||||
_data.last_event = -1;
|
||||
_data.last_event_ms = millis();
|
||||
return false;
|
||||
}
|
||||
if( val < last ) {
|
||||
if( millis()-_data.last_event_ms < 5000 && _data.last_event == 1 ) {
|
||||
return false;
|
||||
}
|
||||
_data.last_event = 1;
|
||||
_data.last_event_ms = millis();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NoiselessTouchESP32::touching() {
|
||||
int last = _data.last;
|
||||
int val = read_with_hysteresis();
|
||||
if( val > last ) {
|
||||
_data.last_event = -1;
|
||||
_data.last_event_ms = millis();
|
||||
return false;
|
||||
}
|
||||
if( val < last ) {
|
||||
_data.last_event = 1;
|
||||
_data.last_event_ms = millis();
|
||||
return true;
|
||||
}
|
||||
return _data.last_event == 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef NoiselessTouchESP32_h
|
||||
#define NoiselessTouchESP32_h
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
typedef struct Touchdata {
|
||||
uint8_t pin;
|
||||
uint8_t history[16];
|
||||
uint8_t hist_len;
|
||||
uint8_t hist_cur;
|
||||
uint8_t hysteresis;
|
||||
uint8_t last;
|
||||
int8_t last_event;
|
||||
uint32_t last_event_ms;
|
||||
} Touchdata;
|
||||
|
||||
class NoiselessTouchESP32 {
|
||||
public:
|
||||
NoiselessTouchESP32(uint8_t pin);
|
||||
NoiselessTouchESP32(uint8_t pin, uint8_t history_length, uint8_t hysteresis);
|
||||
|
||||
int value_from_history();
|
||||
int read_raw_mean();
|
||||
int read_with_hysteresis();
|
||||
|
||||
int changed();
|
||||
bool touched();
|
||||
bool touching();
|
||||
int last_value();
|
||||
|
||||
private:
|
||||
Touchdata _data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user