Added generic Debounce class for use by keypad and GPIO inputs
This commit is contained in:
parent
83784a77d2
commit
1819a244f9
|
@ -1241,9 +1241,9 @@ void setupGPIO()
|
|||
{
|
||||
if(BoardRevision) {
|
||||
// some special considerations for GPIO inputs, depending upon PCB hardware
|
||||
// V1.0 PCBs only expose bare inputs, which are pulled high. Active state into ESP32 is LOW
|
||||
// V2.0+ PCBs use an input transistor buffer. Active state into ESP32 is HIGH (inverted)
|
||||
int activePinState = BoardRevision == 10 ? LOW : HIGH;
|
||||
// V1.0 PCBs only expose bare inputs, which are pulled high. Active state into ESP32 is LOW.
|
||||
// V2.0+ PCBs use an input transistor buffer. Active state into ESP32 is HIGH (inverted).
|
||||
int activePinState = (BoardRevision == 10) ? LOW : HIGH;
|
||||
int Input1 = BoardRevision == 20 ? GPIOin1_pinV20 : GPIOin1_pinV21V10;
|
||||
GPIOin.begin(Input1, GPIOin2_pin, NVstore.getGPIOinMode(), activePinState);
|
||||
|
||||
|
|
|
@ -25,11 +25,6 @@
|
|||
|
||||
CKeyPad::CKeyPad()
|
||||
{
|
||||
// pin scanning
|
||||
_debouncedPins = 0;
|
||||
_prevPins = 0;
|
||||
_lastDebounceTime = millis();
|
||||
_debounceDelay = 50;
|
||||
// handler
|
||||
_lastKey = 0;
|
||||
_lastHoldTime = 0;
|
||||
|
@ -40,39 +35,11 @@ CKeyPad::CKeyPad()
|
|||
void
|
||||
CKeyPad::begin(int Lkey, int Rkey, int Ckey, int Ukey, int Dkey)
|
||||
{
|
||||
_pins[0] = Lkey;
|
||||
_pins[1] = Rkey;
|
||||
_pins[2] = Ckey;
|
||||
_pins[3] = Ukey;
|
||||
_pins[4] = Dkey;
|
||||
for(int i=0; i<5; i++)
|
||||
pinMode(_pins[i], INPUT);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CKeyPad::scanPins()
|
||||
{
|
||||
|
||||
uint8_t newPins = 0;
|
||||
if(digitalRead(_pins[0]) == LOW) newPins |= key_Left;
|
||||
if(digitalRead(_pins[1]) == LOW) newPins |= key_Right;
|
||||
if(digitalRead(_pins[2]) == LOW) newPins |= key_Centre;
|
||||
if(digitalRead(_pins[3]) == LOW) newPins |= key_Up;
|
||||
if(digitalRead(_pins[4]) == LOW) newPins |= key_Down;
|
||||
|
||||
if(newPins != _prevPins) {
|
||||
_lastDebounceTime = millis();
|
||||
_prevPins = newPins;
|
||||
}
|
||||
|
||||
long elapsed = millis() - _lastDebounceTime;
|
||||
if (elapsed > _debounceDelay) {
|
||||
// whatever the reading is at, it's been there for longer than the debounce
|
||||
// delay, so take it as the actual current state:
|
||||
_debouncedPins = newPins;
|
||||
}
|
||||
|
||||
return _debouncedPins;
|
||||
_Debounce.addPin(Lkey);
|
||||
_Debounce.addPin(Rkey);
|
||||
_Debounce.addPin(Ckey);
|
||||
_Debounce.addPin(Ukey);
|
||||
_Debounce.addPin(Dkey);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -84,7 +51,7 @@ CKeyPad::setCallback(void (*callback)(uint8_t event))
|
|||
uint8_t
|
||||
CKeyPad::update()
|
||||
{
|
||||
uint8_t newKey = scanPins();
|
||||
uint8_t newKey = _Debounce.manage();
|
||||
|
||||
// determine edge events
|
||||
uint8_t keyChange = newKey ^ _lastKey;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define __BTC_KEYPAD_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../Utility/Debounce.h"
|
||||
|
||||
|
||||
const uint8_t key_Left = 0x01;
|
||||
|
@ -37,17 +38,11 @@ const uint8_t keyRepeat = 0x80; // action flag
|
|||
class CKeyPad {
|
||||
private:
|
||||
void (*_keyCallback)(uint8_t event);
|
||||
uint8_t _pins[5]; //0:L, 1:R, 2:C, 3:U, 4:D
|
||||
// pin scanning usage
|
||||
uint8_t _prevPins;
|
||||
uint8_t _debouncedPins;
|
||||
CDebounce _Debounce;
|
||||
// handler usage
|
||||
uint8_t _lastKey;
|
||||
unsigned long _lastHoldTime;
|
||||
unsigned long _holdTimeout;
|
||||
uint8_t scanPins();
|
||||
unsigned long _lastDebounceTime;
|
||||
unsigned long _debounceDelay;
|
||||
public:
|
||||
CKeyPad();
|
||||
void begin(int Lkey, int Rkey, int Ckey, int Ukey, int Dkey);
|
||||
|
|
|
@ -81,10 +81,11 @@ int BoardDetect()
|
|||
uint8_t revision = 0;
|
||||
uint8_t val = preferences.getUChar("Board Revision", revision);
|
||||
if(val != 0) {
|
||||
// return val;
|
||||
DebugPort.print("Board detect: Using saved revision V"); DebugPort.println(float(val) * 0.1f, 1);
|
||||
return val;
|
||||
}
|
||||
|
||||
DebugPort.println("Virgin system - attempting to detect revision");
|
||||
DebugPort.println("Board detect: Virgin system - attempting to detect revision");
|
||||
pinMode(33, INPUT_PULLUP);
|
||||
pinMode(26, INPUT_PULLUP);
|
||||
// there is a 100nF capacitor across the analogue input, allow that to charge before testing
|
||||
|
@ -94,27 +95,28 @@ int BoardDetect()
|
|||
|
||||
if(pin33 == HIGH && pin26 == HIGH) {
|
||||
revision = 10;
|
||||
DebugPort.println("Board detect: digital input test suggests V1.x PCB");
|
||||
DebugPort.println("Board detect: digital input test reveals V1.x PCB");
|
||||
}
|
||||
else if(pin33 == LOW && pin26 == HIGH) {
|
||||
revision = 20;
|
||||
DebugPort.println("Board detect: digital input test suggests V2.0 PCB");
|
||||
DebugPort.println("Board detect: digital input test reveals V2.0 PCB");
|
||||
}
|
||||
else if(pin33 == HIGH && pin26 == LOW) {
|
||||
revision = 21;
|
||||
DebugPort.println("Board detect: digital input test suggests V2.1 PCB");
|
||||
DebugPort.println("Board detect: digital input test reveals V2.1 PCB");
|
||||
}
|
||||
else {
|
||||
DebugPort.println("Board detect: digital input test failed to detect a sane combination!!!");
|
||||
DebugPort.println("Board detect: digital input test failed to detect a valid combination!!!");
|
||||
}
|
||||
|
||||
pinMode(33, INPUT); // revert to normal inputs (remove pull ups)
|
||||
pinMode(26, INPUT);
|
||||
|
||||
//store the detected revision
|
||||
if(revision) {
|
||||
preferences.putUChar("Board Revision", revision);
|
||||
}
|
||||
|
||||
DebugPort.print("Board detect result: V"); DebugPort.println(float(revision)*0.1f, 1);
|
||||
DebugPort.print("Board detect: Result = V"); DebugPort.println(float(revision)*0.1f, 1);
|
||||
return revision;
|
||||
}
|
86
Arduino/BTCDieselHeater/src/Utility/Debounce.cpp
Normal file
86
Arduino/BTCDieselHeater/src/Utility/Debounce.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Debounce.h"
|
||||
|
||||
CDebounce::CDebounce()
|
||||
{
|
||||
_pinActiveState = LOW;
|
||||
_prevPins = 0;
|
||||
_lastDebounceTime = 0;
|
||||
_debounceDelay = 50;
|
||||
}
|
||||
|
||||
void
|
||||
CDebounce::addPin(int pin)
|
||||
{
|
||||
if(pin && (_pins.size() < 8)) {
|
||||
_pins.push_back(pin);
|
||||
pinMode(pin, INPUT_PULLUP); // GPIO input pin #1
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CDebounce::setActiveState(int activeState)
|
||||
{
|
||||
_pinActiveState = activeState;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CDebounce::getState()
|
||||
{
|
||||
return _debouncedPins;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CDebounce::manage()
|
||||
{
|
||||
return _scanInputs();
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CDebounce::_scanInputs()
|
||||
{
|
||||
uint8_t newPins = 0;
|
||||
uint8_t mask = 0x01;
|
||||
for(int i = 0; i < _pins.size(); i++) {
|
||||
if(digitalRead(_pins[i]) == _pinActiveState)
|
||||
newPins |= mask;
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
if(newPins != _prevPins) {
|
||||
_lastDebounceTime = millis();
|
||||
_prevPins = newPins;
|
||||
}
|
||||
|
||||
long elapsed = millis() - _lastDebounceTime;
|
||||
if (elapsed > _debounceDelay) {
|
||||
// whatever the reading is at, it's been there for longer than the debounce
|
||||
// delay, so take it as the actual current state:
|
||||
_debouncedPins = newPins;
|
||||
}
|
||||
|
||||
return _debouncedPins;
|
||||
}
|
||||
|
||||
|
44
Arduino/BTCDieselHeater/src/Utility/Debounce.h
Normal file
44
Arduino/BTCDieselHeater/src/Utility/Debounce.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This file is part of the "bluetoothheater" distribution
|
||||
* (https://gitlab.com/mrjones.id.au/bluetoothheater)
|
||||
*
|
||||
* Copyright (C) 2018 Ray Jones <ray@mrjones.id.au>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DEBOUNCE_H__
|
||||
#define __DEBOUNCE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
class CDebounce {
|
||||
int _pinActiveState;
|
||||
std::vector<int> _pins;
|
||||
uint8_t _prevPins;
|
||||
uint8_t _debouncedPins;
|
||||
unsigned long _lastDebounceTime;
|
||||
unsigned long _debounceDelay;
|
||||
uint8_t _scanInputs();
|
||||
public:
|
||||
CDebounce();
|
||||
void addPin(int pin);
|
||||
void setActiveState(int state);
|
||||
uint8_t manage();
|
||||
uint8_t getState();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -32,23 +32,15 @@ const int ONFLASHINTERVAL = 50;
|
|||
CGPIOin::CGPIOin()
|
||||
{
|
||||
_Mode = GPIOinNone;
|
||||
_pins[0] = 0;
|
||||
_pins[1] = 0;
|
||||
_pinActive = LOW;
|
||||
_prevPins = 0;
|
||||
_lastDebounceTime = 0;
|
||||
_lastKey = 0;
|
||||
_debounceDelay = 50;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOin::begin(int pin1, int pin2, GPIOinModes mode, int activeState)
|
||||
{
|
||||
_pins[0] = pin1;
|
||||
_pins[1] = pin2;
|
||||
_pinActive = activeState;
|
||||
pinMode(pin1, INPUT_PULLUP); // GPIO input pin #1
|
||||
pinMode(pin2, INPUT_PULLUP); // GPIO input pin #2
|
||||
_Debounce.addPin(pin1);
|
||||
_Debounce.addPin(pin2);
|
||||
_Debounce.setActiveState(activeState);
|
||||
|
||||
setMode(mode);
|
||||
}
|
||||
|
@ -57,7 +49,7 @@ uint8_t
|
|||
CGPIOin::getState(int channel)
|
||||
{
|
||||
int mask = 0x01 << (channel & 0x01);
|
||||
return (_debouncedPins & mask) != 0;
|
||||
return (_Debounce.getState() & mask) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -81,7 +73,7 @@ CGPIOin::manage()
|
|||
void
|
||||
CGPIOin::_doOn1Off2()
|
||||
{
|
||||
uint8_t newKey = _scanInputs();
|
||||
uint8_t newKey = _Debounce.manage();
|
||||
// determine edge events
|
||||
uint8_t keyChange = newKey ^ _lastKey;
|
||||
_lastKey = newKey;
|
||||
|
@ -101,7 +93,7 @@ CGPIOin::_doOn1Off2()
|
|||
void
|
||||
CGPIOin::_doOnHold1()
|
||||
{
|
||||
uint8_t newKey = _scanInputs();
|
||||
uint8_t newKey = _Debounce.manage();
|
||||
// determine edge events
|
||||
uint8_t keyChange = newKey ^ _lastKey;
|
||||
_lastKey = newKey;
|
||||
|
@ -121,7 +113,7 @@ CGPIOin::_doOnHold1()
|
|||
void
|
||||
CGPIOin::_doOn1Off1()
|
||||
{
|
||||
uint8_t newKey = _scanInputs();
|
||||
uint8_t newKey = _Debounce.manage();
|
||||
// determine edge events
|
||||
uint8_t keyChange = newKey ^ _lastKey;
|
||||
_lastKey = newKey;
|
||||
|
@ -136,29 +128,6 @@ CGPIOin::_doOn1Off1()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
CGPIOin::_scanInputs()
|
||||
{
|
||||
uint8_t newPins = 0;
|
||||
if(_pins[0] && (digitalRead(_pins[0]) == _pinActive)) newPins |= 0x01;
|
||||
if(_pins[1] && (digitalRead(_pins[1]) == _pinActive)) newPins |= 0x02;
|
||||
|
||||
if(newPins != _prevPins) {
|
||||
_lastDebounceTime = millis();
|
||||
_prevPins = newPins;
|
||||
}
|
||||
|
||||
long elapsed = millis() - _lastDebounceTime;
|
||||
if (elapsed > _debounceDelay) {
|
||||
// whatever the reading is at, it's been there for longer than the debounce
|
||||
// delay, so take it as the actual current state:
|
||||
_debouncedPins = newPins;
|
||||
}
|
||||
|
||||
return _debouncedPins;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CGPIOout::CGPIOout()
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <driver/adc.h>
|
||||
#include "Debounce.h"
|
||||
|
||||
enum GPIOinModes {
|
||||
GPIOinNone,
|
||||
|
@ -46,14 +47,15 @@ enum GPIOalgModes {
|
|||
|
||||
class CGPIOin {
|
||||
GPIOinModes _Mode;
|
||||
int _pinActive;
|
||||
int _pins[2];
|
||||
uint8_t _prevPins;
|
||||
uint8_t _debouncedPins;
|
||||
CDebounce _Debounce;
|
||||
// int _pinActive;
|
||||
// int _pins[2];
|
||||
// uint8_t _prevPins;
|
||||
// uint8_t _debouncedPins;
|
||||
uint8_t _lastKey;
|
||||
unsigned long _lastDebounceTime;
|
||||
unsigned long _debounceDelay;
|
||||
uint8_t _scanInputs();
|
||||
// unsigned long _lastDebounceTime;
|
||||
// unsigned long _debounceDelay;
|
||||
// uint8_t _scanInputs();
|
||||
void _doOn1Off2();
|
||||
void _doOnHold1();
|
||||
void _doOn1Off1();
|
||||
|
|
Loading…
Reference in a new issue