Can now define the operation mode for each GPIO line individually.

Need to test actual functionality, GUI OK.
This commit is contained in:
Ray Jones 2019-08-07 22:04:20 +10:00
parent 10db95733f
commit 48a0254f13
8 changed files with 363 additions and 156 deletions

View file

@ -1373,12 +1373,12 @@ void setupGPIO()
// 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.getUserSettings().GPIO.inMode, activePinState);
GPIOin.begin(Input1, GPIOin2_pin, NVstore.getUserSettings().GPIO.in1Mode, NVstore.getUserSettings().GPIO.in2Mode, activePinState);
// GPIO out is always active high from ESP32
// V1.0 PCBs only expose the bare pins
// V2.0+ PCBs provide an open collector output that conducts when active
GPIOout.begin(GPIOout1_pin, GPIOout2_pin, NVstore.getUserSettings().GPIO.outMode);
GPIOout.begin(GPIOout1_pin, GPIOout2_pin, NVstore.getUserSettings().GPIO.out1Mode, NVstore.getUserSettings().GPIO.out2Mode);
// ### MAJOR ISSUE WITH ADC INPUTS ###
//
@ -1407,27 +1407,44 @@ void setupGPIO()
pinMode(GPIOin1_pinV20, INPUT_PULLUP);
pinMode(GPIOout1_pin, INPUT_PULLUP);
pinMode(GPIOout2_pin, INPUT_PULLUP);
GPIOin.begin(0, 0, GPIOinNone, LOW); // ensure modes disabled (should already be by constructors)
GPIOout.begin(0, 0, GPIOoutNone);
GPIOin.begin(0, 0, GPIOin1None, GPIOin2None, LOW); // ensure modes disabled (should already be by constructors)
GPIOout.begin(0, 0, GPIOout1None, GPIOout2None);
GPIOalg.begin(ADC1_CHANNEL_5, GPIOalgNone);
}
}
bool toggleGPIOout(int channel)
{
if(NVstore.getUserSettings().GPIO.outMode == GPIOoutUser) {
setGPIOout(channel, !getGPIOout(channel)); // toggle selected GPIO output
return true;
if(channel == 0) {
if(NVstore.getUserSettings().GPIO.out1Mode == GPIOout1User) {
setGPIOout(channel, !getGPIOout(channel)); // toggle selected GPIO output
return true;
}
}
else if(channel == 1) {
if(NVstore.getUserSettings().GPIO.out2Mode == GPIOout2User) {
setGPIOout(channel, !getGPIOout(channel)); // toggle selected GPIO output
return true;
}
}
return false;
}
bool setGPIOout(int channel, bool state)
{
if(GPIOout.getMode() != GPIOoutNone) {
DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state);
GPIOout.setState(channel, state);
return true;
if(channel == 0) {
if(GPIOout.getMode1() != GPIOout1None) {
DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state);
GPIOout.setState(channel, state);
return true;
}
}
else if(channel == 1) {
if(GPIOout.getMode2() != GPIOout2None) {
DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state);
GPIOout.setState(channel, state);
return true;
}
}
return false;
}
@ -1526,8 +1543,10 @@ void getGPIOinfo(sGPIO& info)
info.outState[0] = GPIOout.getState(0);
info.outState[1] = GPIOout.getState(1);
info.algVal = GPIOalg.getValue();
info.inMode = GPIOin.getMode();
info.outMode = GPIOout.getMode();
info.in1Mode = GPIOin.getMode1();
info.in2Mode = GPIOin.getMode2();
info.out1Mode = GPIOout.getMode1();
info.out2Mode = GPIOout.getMode2();
info.algMode = GPIOalg.getMode();
}

View file

@ -42,14 +42,16 @@ extern CGPIOalg GPIOalg;
static const int Line3 = 14;
static const int Line2 = 27;
static const int Line1 = 40;
//static const int Column = 58;
static const int Column = 38;
static const int Column1 = 26;
static const int Column2 = 85;
CGPIOScreen::CGPIOScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
{
_initUI();
_GPIOparams.inMode = GPIOinNone;
_GPIOparams.outMode = GPIOoutNone;
_GPIOparams.in1Mode = GPIOin1None;
_GPIOparams.in2Mode = GPIOin2None;
_GPIOparams.out1Mode = GPIOout1None;
_GPIOparams.out2Mode = GPIOout2None;
_GPIOparams.algMode = GPIOalgNone;
}
@ -73,36 +75,57 @@ CGPIOScreen::show()
{
_display.clearDisplay();
static bool animated = false;
animated = !animated;
if(!CPasswordScreen::show()) { // for showing "saving settings"
if(_rowSel == 4) {
if(_rowSel == 10) {
_showConfirmMessage();
}
else {
_showTitle("GPIO Settings");
_drawBitmap(10, 14, (getBoardRevision() != BRD_V2_GPIO_NOALG) ? GPIOIconInfo : GPIOIconNoAlgInfo);
_drawBitmap(0, 14, (getBoardRevision() != BRD_V2_GPIO_NOALG) ? GPIOIconInfo : GPIOIconNoAlgInfo);
{
const char* msgText = NULL;
switch(_GPIOparams.inMode) {
case GPIOinNone: msgText = "Disabled"; break;
case GPIOinOn1Off2: msgText = "1:On 2:Off"; break;
case GPIOinOnHold1: msgText = "1:On 2:\352T"; break;
case GPIOinOn1Off1: msgText = "1:On/Off"; break;
case GPIOinExtThermostat2: msgText = "2:\352T"; break;
switch(_GPIOparams.in1Mode) {
case GPIOin1None: msgText = "1: --- "; break;
case GPIOin1On: msgText = "1:Start"; break;
case GPIOin1Hold: msgText = "1: Run "; break;
case GPIOin1OnOff: msgText = animated ? "1:Start" : "1: Stop"; break;
}
if(msgText)
_printMenuText(Column, Line3, msgText, _rowSel == 3);
_printMenuText(Column1, Line3, msgText, _rowSel == 4);
}
{
const char* msgText = NULL;
switch(_GPIOparams.in2Mode) {
case GPIOin2None: msgText = "2: ---"; break;
case GPIOin2Off: msgText = "2:Stop"; break;
case GPIOin2ExtThermostat: msgText = "2: \352T "; break;
}
if(msgText)
_printMenuText(Column2, Line3, msgText, _rowSel == 5);
}
{
const char* msgText = NULL;
switch(_GPIOparams.outMode) {
case GPIOoutNone: msgText = "Disabled"; break;
case GPIOoutStatus: msgText = "1: Status LED"; break;
case GPIOoutUser: msgText = "1&2 User"; break;
switch(_GPIOparams.out1Mode) {
case GPIOout1None: msgText = "1: --- "; break;
case GPIOout1Status: msgText = "1:Status"; break;
case GPIOout1User: msgText = "1: User "; break;
}
if(msgText)
_printMenuText(Column, Line2, msgText, _rowSel == 2);
_printMenuText(Column1, Line2, msgText, _rowSel == 2);
}
{
const char* msgText = NULL;
switch(_GPIOparams.out2Mode) {
case GPIOout2None: msgText = "2: ---"; break;
case GPIOout2User: msgText = "2:User"; break;
}
if(msgText)
_printMenuText(Column2, Line2, msgText, _rowSel == 3);
}
if(getBoardRevision() != BRD_V2_GPIO_NOALG) { // Not No Analog support
@ -112,7 +135,7 @@ CGPIOScreen::show()
case GPIOalgHeatDemand: msgText = "Ip1 allows"; break;
}
if(msgText)
_printMenuText(Column, Line1, msgText, _rowSel == 1);
_printMenuText(Column1, Line1, msgText, _rowSel == 1);
}
}
}
@ -126,7 +149,7 @@ CGPIOScreen::animate()
CPasswordScreen::animate();
if(!CPasswordScreen::_busy()) {
if(_rowSel != 4) {
if(_rowSel != 10) {
int yPos = 53;
int xPos = _display.xCentre();
const char* pMsg = NULL;
@ -146,23 +169,41 @@ CGPIOScreen::animate()
case 2:
_display.drawFastHLine(0, 52, 128, WHITE);
switch(_GPIOparams.outMode) {
case GPIOoutNone: pMsg = " Digital outputs are disabled. "; break;
case GPIOoutStatus: pMsg = " Output1: LED status indicator. "; break;
case GPIOoutUser: pMsg = " Output 1&2: User controlled. "; break;
switch(_GPIOparams.out1Mode) {
case GPIOout1None: pMsg = " Output 1: DISABLED. "; break;
case GPIOout1Status: pMsg = " Output 1: LED status indicator. "; break;
case GPIOout1User: pMsg = " Output 1: User controlled. "; break;
}
if(pMsg)
_scrollMessage(56, pMsg, _scrollChar);
break;
case 3:
_display.drawFastHLine(0, 52, 128, WHITE);
switch(_GPIOparams.out2Mode) {
case GPIOout2None: pMsg = " Output 2: DISABLED. "; break;
case GPIOout2User: pMsg = " Output 2: User controlled. "; break;
}
if(pMsg)
_scrollMessage(56, pMsg, _scrollChar);
break;
case 3:
case 4:
_display.drawFastHLine(0, 52, 128, WHITE);
switch(_GPIOparams.inMode) {
case GPIOinNone: pMsg = " Digital inputs are disabled. "; break;
case GPIOinOn1Off2: pMsg = " Input 1: Starts upon closure. Input 2: Stops upon closure. "; break;
case GPIOinOnHold1: pMsg = " Input 1: Starts when held closed, stops when opened. Input2: Max fuel when closed, min fuel when open. "; break;
case GPIOinOn1Off1: pMsg = " Input 1: Starts or Stops upon closure. "; break;
case GPIOinExtThermostat2: pMsg = " Input 1: not used. Input 2: Max fuel when closed, min fuel when open. "; break;
switch(_GPIOparams.in1Mode) {
case GPIOin1None: pMsg = " Input 1: DISABLED. "; break;
case GPIOin1On: pMsg = " Input 1: Starts heater upon closure. "; break;
case GPIOin1Hold: pMsg = " Input 1: Starts heater when held closed, stops when opened. "; break;
case GPIOin1OnOff: pMsg = " Input 1: Starts or Stops heater upon closure. "; break;
}
if(pMsg)
_scrollMessage(56, pMsg, _scrollChar);
break;
case 5:
_display.drawFastHLine(0, 52, 128, WHITE);
switch(_GPIOparams.in2Mode) {
case GPIOin2None: pMsg = " Input 2: DISABLED. "; break;
case GPIOin2Off: pMsg = " Input 2: Stops heater upon closure. "; break;
case GPIOin2ExtThermostat: pMsg = " Input 2: External thermostat. Max fuel when closed, min fuel when open. "; break;
}
if(pMsg)
_scrollMessage(56, pMsg, _scrollChar);
@ -188,10 +229,12 @@ CGPIOScreen::keyHandler(uint8_t event)
case 1:
case 2:
case 3:
case 4:
case 5:
_scrollChar = 0;
_adjust(-1);
break;
case 4:
case 10:
_rowSel = 0; // abort save
break;
}
@ -205,10 +248,12 @@ CGPIOScreen::keyHandler(uint8_t event)
case 1:
case 2:
case 3:
case 4:
case 5:
_scrollChar = 0;
_adjust(+1);
break;
case 4:
case 10:
_rowSel = 0; // abort save
break;
}
@ -229,11 +274,13 @@ CGPIOScreen::keyHandler(uint8_t event)
case 1:
case 2:
case 3:
case 4:
case 5:
_scrollChar = 0;
_rowSel++;
UPPERLIMIT(_rowSel, 3);
UPPERLIMIT(_rowSel, 5);
break;
case 4: // confirmed save
case 10: // confirmed save
_enableStoringMessage();
us = NVstore.getUserSettings();
us.GPIO = _GPIOparams;
@ -256,7 +303,9 @@ CGPIOScreen::keyHandler(uint8_t event)
case 1:
case 2:
case 3:
_rowSel = 4;
case 4:
case 5:
_rowSel = 10;
break;
}
}
@ -278,16 +327,28 @@ CGPIOScreen::_adjust(int dir)
_GPIOparams.algMode = (GPIOalgModes)tVal;
break;
case 2: // outputs mode
tVal = _GPIOparams.outMode;
tVal = _GPIOparams.out1Mode;
tVal += dir;
WRAPLIMITS(tVal, 0, 2);
_GPIOparams.outMode = (GPIOoutModes)tVal;
_GPIOparams.out1Mode = (GPIOout1Modes)tVal;
break;
case 3:
tVal = _GPIOparams.inMode;
case 3: // outputs mode
tVal = _GPIOparams.out2Mode;
tVal += dir;
WRAPLIMITS(tVal, 0, 4);
_GPIOparams.inMode = (GPIOinModes)tVal;
WRAPLIMITS(tVal, 0, 1);
_GPIOparams.out2Mode = (GPIOout2Modes)tVal;
break;
case 4:
tVal = _GPIOparams.in1Mode;
tVal += dir;
WRAPLIMITS(tVal, 0, 3);
_GPIOparams.in1Mode = (GPIOin1Modes)tVal;
break;
case 5:
tVal = _GPIOparams.in2Mode;
tVal += dir;
WRAPLIMITS(tVal, 0, 2);
_GPIOparams.in2Mode = (GPIOin2Modes)tVal;
break;
}
}
@ -319,39 +380,45 @@ CGPIOInfoScreen::show()
_printMenuText(91, 20, "1", false, eCentreJustify);
_printMenuText(118, 20, "2", false, eCentreJustify);
_printMenuText(55, Line1, "Analogue:", false, eRightJustify);
if(getBoardRevision() == BRD_V2_FULLGPIO || getBoardRevision() == BRD_V1_FULLGPIO)
_printMenuText(55, Line1, "Analogue:", false, eRightJustify);
if(NVstore.getUserSettings().GPIO.inMode == GPIOinNone) {
if(NVstore.getUserSettings().GPIO.in1Mode == GPIOin1None) {
_drawBitmap(7, 28, CrossLgIconInfo);
_drawBitmap(30, 28, CrossLgIconInfo);
}
else {
_drawBitmap(4, 29, GPIOin.getState(0) ? CloseIconInfo : OpenIconInfo);
if(NVstore.getUserSettings().GPIO.inMode == GPIOinOn1Off1)
_drawBitmap(30, 28, CrossLgIconInfo);
else
_drawBitmap(27, 29, GPIOin.getState(1) ? CloseIconInfo : OpenIconInfo);
}
if(NVstore.getUserSettings().GPIO.in2Mode == GPIOin2None) {
_drawBitmap(30, 28, CrossLgIconInfo);
}
else {
_drawBitmap(27, 29, GPIOin.getState(1) ? CloseIconInfo : OpenIconInfo);
}
if(NVstore.getUserSettings().GPIO.outMode == GPIOoutNone) {
if(NVstore.getUserSettings().GPIO.out1Mode == GPIOout1None) {
_drawBitmap(87, 28, CrossLgIconInfo);
_drawBitmap(114, 28, CrossLgIconInfo);
}
else {
_drawBitmap(86, 29, GPIOout.getState(0) ? BulbOnIconInfo : BulbOffIconInfo);
if(NVstore.getUserSettings().GPIO.outMode == GPIOoutStatus)
_drawBitmap(114, 28, CrossLgIconInfo);
else
_drawBitmap(113, 29, GPIOout.getState(1) ? BulbOnIconInfo : BulbOffIconInfo);
}
if(NVstore.getUserSettings().GPIO.algMode == GPIOalgNone) {
_drawBitmap(58, Line1, CrossLgIconInfo);
if(NVstore.getUserSettings().GPIO.out2Mode == GPIOout2None) {
_drawBitmap(114, 28, CrossLgIconInfo);
}
else {
sprintf(msg, "%d%%", GPIOalg.getValue() * 100 / 4096);
_printMenuText(58, Line1, msg);
_drawBitmap(113, 29, GPIOout.getState(1) ? BulbOnIconInfo : BulbOffIconInfo);
}
if(getBoardRevision() == BRD_V2_FULLGPIO || getBoardRevision() == BRD_V1_FULLGPIO) {
if(NVstore.getUserSettings().GPIO.algMode == GPIOalgNone) {
_drawBitmap(58, Line1, CrossLgIconInfo);
}
else {
sprintf(msg, "%d%%", GPIOalg.getValue() * 100 / 4096);
_printMenuText(58, Line1, msg);
}
}
_printMenuText(_display.xCentre(), 53, " \021 \020 ", true, eCentreJustify);

View file

@ -71,8 +71,6 @@ CVersionInfoScreen::_initUI()
bool
CVersionInfoScreen::show()
{
char msg[16];
_display.clearDisplay();
if(!CPasswordScreen::show()) { // for showing "saving settings"
@ -86,14 +84,6 @@ CVersionInfoScreen::show()
_printMenuText(41, 15, getVersionStr());
_printMenuText(41, 26, getVersionDate());
int newVer = isUpdateAvailable();
// if(newVer) {
// char msg[32];
// int major = (int)(newVer * 0.01);
// int minor = newVer - major*100;
// float prtMajor = major * 0.1;
// sprintf(msg, "V%.1f.%d", prtMajor, minor);
// _printMenuText(128, 15, msg, false, eRightJustify);
// }
_drawBitmap(18, 34, HardwareIconInfo);
int PCB = getBoardRevision();
_printMenuText(41, 38, getBoardRevisionString(PCB));

View file

@ -30,19 +30,41 @@ const int FADEAMOUNT = 3;
const int FLASHPERIOD = 2000;
const int ONFLASHINTERVAL = 50;
const char* GPIOinNames[] = {
// const char* GPIOinNames[] = {
// "Disabled",
// "On1Off2",
// "Hold1",
// "On1Off1",
// "ExtThermostat"
// };
const char* GPIOin1Names[] = {
"Disabled",
"On1Off2",
"Hold1",
"On1Off1",
"ExtThermostat"
"Mom On",
"Hold On",
"Mom On/Off"
};
const char* GPIOin2Names[] = {
"Disabled",
"Mom Off",
"Ext \352T"
};
const char* GPIOoutNames[] = {
// const char* GPIOoutNames[] = {
// "Disabled",
// "Status",
// "User"
// };
const char* GPIOout1Names[] = {
"Disabled",
"Status",
"User"
};
const char* GPIOout2Names[] = {
"Disabled",
"User"
};
const char* GPIOalgNames[] = {
"Disabled",
@ -52,18 +74,19 @@ const char* GPIOalgNames[] = {
CGPIOin::CGPIOin()
{
_Mode = GPIOinNone;
_Mode1 = GPIOin1None;
_Mode2 = GPIOin2None;
_lastKey = 0;
}
void
CGPIOin::begin(int pin1, int pin2, GPIOinModes mode, int activeState)
CGPIOin::begin(int pin1, int pin2, GPIOin1Modes mode1, GPIOin2Modes mode2, int activeState)
{
_Debounce.addPin(pin1);
_Debounce.addPin(pin2);
_Debounce.setActiveState(activeState);
setMode(mode);
setMode(mode1, mode2);
}
uint8_t
@ -89,9 +112,14 @@ CGPIOin::getState(int channel)
return retval;
}
GPIOinModes CGPIOin::getMode() const
GPIOin1Modes CGPIOin::getMode1() const
{
return _Mode;
return _Mode1;
};
GPIOin2Modes CGPIOin::getMode2() const
{
return _Mode2;
};
void
@ -116,29 +144,41 @@ CGPIOin::manage()
void
CGPIOin::simulateKey(uint8_t newKey)
{
switch (_Mode) {
case GPIOinNone:
switch (_Mode1) {
case GPIOin1None:
break;
case GPIOinOn1Off2:
_doOn1Off2(newKey);
case GPIOin1On:
_doOn1(newKey);
break;
case GPIOinOnHold1:
case GPIOin1Hold:
_doOnHold1(newKey);
break;
case GPIOinOn1Off1:
case GPIOin1OnOff:
_doOn1Off1(newKey);
break;
case GPIOinExtThermostat2:
}
switch (_Mode2) {
case GPIOin2None:
break;
case GPIOin2Off:
_doOff2(newKey);
break;
case GPIOin2ExtThermostat:
break; // handling actually performed at Tx Manage for setting the fuel rate
}
}
void
CGPIOin::_doOn1Off2(uint8_t newKey)
CGPIOin::_doOn1(uint8_t newKey)
{
if(newKey & 0x01) {
requestOn();
}
}
void
CGPIOin::_doOff2(uint8_t newKey)
{
if(newKey & 0x02) {
requestOff();
}
@ -174,7 +214,8 @@ CGPIOin::_doOn1Off1(uint8_t newKey)
CGPIOout::CGPIOout()
{
_Mode = GPIOoutNone;
_Mode1 = GPIOout1None;
_Mode2 = GPIOout2None;
_pins[0] = 0;
_pins[1] = 0;
_breatheDelay = 0;
@ -185,7 +226,7 @@ CGPIOout::CGPIOout()
}
void
CGPIOout::begin(int pin1, int pin2, GPIOoutModes mode)
CGPIOout::begin(int pin1, int pin2, GPIOout1Modes mode1, GPIOout2Modes mode2)
{
_pins[0] = pin1;
_pins[1] = pin2;
@ -200,30 +241,40 @@ CGPIOout::begin(int pin1, int pin2, GPIOoutModes mode)
ledcSetup(1, 500, 8); // create PWM channel for GPIO2: 500Hz, 8 bits
}
setMode(mode);
setMode(mode1, mode2);
}
void
CGPIOout::setMode(GPIOoutModes mode)
CGPIOout::setMode(GPIOout1Modes mode1, GPIOout2Modes mode2)
{
_Mode = mode;
_Mode1 = mode1;
_Mode2 = mode2;
_prevState = -1;
ledcDetachPin(_pins[0]); // ensure PWM detached from IO line
ledcDetachPin(_pins[1]); // ensure PWM detached from IO line
};
GPIOoutModes CGPIOout::getMode() const
GPIOout1Modes CGPIOout::getMode1() const
{
return _Mode;
return _Mode1;
};
GPIOout2Modes CGPIOout::getMode2() const
{
return _Mode2;
};
void
CGPIOout::manage()
{
switch (_Mode) {
case GPIOoutNone: break;
case GPIOoutStatus: _doStatus(); break;
case GPIOoutUser: _doUser(); break;
switch (_Mode1) {
case GPIOout1None: break;
case GPIOout1Status: _doStatus(); break;
case GPIOout1User: _doUser1(); break;
}
switch (_Mode2) {
case GPIOout2None: break;
case GPIOout2User: _doUser2(); break;
}
}
@ -304,12 +355,18 @@ CGPIOout::_doStatus()
}
void
CGPIOout::_doUser()
CGPIOout::_doUser1()
{
// DebugPort.println("GPIOout::_doUser()");
// DebugPort.println("GPIOout::_doUser1()");
if(_pins[0]) {
digitalWrite(_pins[0], (_userState & 0x01) ? HIGH : LOW);
}
}
void
CGPIOout::_doUser2()
{
// DebugPort.println("GPIOout::_doUser2()");
if(_pins[1]) {
digitalWrite(_pins[1], (_userState & 0x02) ? HIGH : LOW);
}

View file

@ -27,23 +27,33 @@
#include "Debounce.h"
#include <list>
extern const char* GPIOinNames[];
extern const char* GPIOoutNames[];
extern const char* GPIOin1Names[];
extern const char* GPIOin2Names[];
extern const char* GPIOout1Names[];
extern const char* GPIOout2Names[];
extern const char* GPIOalgNames[];
enum GPIOinModes {
GPIOinNone,
GPIOinOn1Off2, // input 1 closure, heater starts; input2 closure, heater stops
GPIOinOnHold1, // hold input 1 closure, heater runs; input 1 open, heater stops
GPIOinOn1Off1, // alternate input 1 closures start or stop the heater
GPIOinExtThermostat2 // input 2 used to max/min heater if closed/open
enum GPIOin1Modes {
GPIOin1None,
GPIOin1On, // input 1 closure, heater starts; input2 closure, heater stops
GPIOin1Hold, // hold input 1 closure, heater runs; input 1 open, heater stops
GPIOin1OnOff // alternate input 1 closures start or stop the heater
};
enum GPIOin2Modes {
GPIOin2None,
GPIOin2Off, // input 2 closure stops heater
GPIOin2ExtThermostat // input 2 used to max/min heater if closed/open
};
enum GPIOoutModes {
GPIOoutNone,
GPIOoutStatus,
GPIOoutUser
enum GPIOout1Modes {
GPIOout1None,
GPIOout1Status,
GPIOout1User
};
enum GPIOout2Modes {
GPIOout2None,
GPIOout2User
};
@ -54,37 +64,48 @@ enum GPIOalgModes {
struct sGPIOparams {
GPIOinModes inMode;
GPIOoutModes outMode;
GPIOin1Modes in1Mode;
GPIOin2Modes in2Mode;
GPIOout1Modes out1Mode;
GPIOout2Modes out2Mode;
GPIOalgModes algMode;
};
class CGPIOin {
GPIOinModes _Mode;
GPIOin1Modes _Mode1;
GPIOin2Modes _Mode2;
CDebounce _Debounce;
uint8_t _lastKey;
std::list<uint8_t> _eventList[2];
void _doOn1Off2(uint8_t newKey);
void _doOn1(uint8_t newKey);
void _doOff2(uint8_t newKey);
void _doOnHold1(uint8_t newKey);
void _doOn1Off1(uint8_t newKey);
public:
CGPIOin();
void setMode(GPIOinModes mode) { _Mode = mode; };
void begin(int pin1, int pin2, GPIOinModes mode, int activeState);
// void setMode(GPIOinModes mode) { _Mode = mode; };
// void begin(int pin1, int pin2, GPIOinModes mode, int activeState);
void setMode(GPIOin1Modes mode1, GPIOin2Modes mode2) { _Mode1 = mode1; _Mode2 = mode2; };
void begin(int pin1, int pin2, GPIOin1Modes mode1, GPIOin2Modes mode2, int activeState);
void manage();
uint8_t getState(int channel);
GPIOinModes getMode() const;
GPIOin1Modes getMode1() const;
GPIOin2Modes getMode2() const;
void simulateKey(uint8_t newKey);
bool usesExternalThermostat() const {
return (_Mode == GPIOinOnHold1) || (_Mode == GPIOinExtThermostat2);
// return (_Mode == GPIOinOnHold1) || (_Mode == GPIOinExtThermostat2);
return (_Mode2 == GPIOin2ExtThermostat);
};
};
class CGPIOout {
GPIOoutModes _Mode;
// GPIOoutModes _Mode;
GPIOout1Modes _Mode1;
GPIOout2Modes _Mode2;
void _doStatus();
void _doUser();
void _doUser1();
void _doUser2();
int _pins[2];
int _prevState;
int _statusState;
@ -96,12 +117,16 @@ class CGPIOout {
void _doSuspendMode();
public:
CGPIOout();
void setMode(GPIOoutModes mode);
void begin(int pin1, int pin2, GPIOoutModes mode);
// void setMode(GPIOoutModes mode);
// void begin(int pin1, int pin2, GPIOoutModes mode);
void setMode(GPIOout1Modes mode1, GPIOout2Modes mode2);
void begin(int pin1, int pin2, GPIOout1Modes mode1, GPIOout2Modes mode2);
void manage();
void setState(int channel, bool state);
bool getState(int channel);
GPIOoutModes getMode() const;
// GPIOoutModes getMode() const;
GPIOout1Modes getMode1() const;
GPIOout2Modes getMode2() const;
};
class CGPIOalg {
@ -120,8 +145,12 @@ struct sGPIO {
bool outState[2];
bool inState[2];
int algVal;
GPIOoutModes outMode;
GPIOinModes inMode;
// GPIOoutModes outMode;
// GPIOinModes inMode;
GPIOout1Modes out1Mode;
GPIOout2Modes out2Mode;
GPIOin1Modes in1Mode;
GPIOin2Modes in2Mode;
GPIOalgModes algMode;
sGPIO& operator=(const sGPIO& rhs) {
outState[0] = rhs.outState[0];
@ -129,8 +158,10 @@ struct sGPIO {
inState[0] = rhs.inState[0];
inState[1] = rhs.inState[1];
algVal = rhs.algVal;
outMode = rhs.outMode;
inMode = rhs.inMode;
out1Mode = rhs.out1Mode;
out2Mode = rhs.out2Mode;
in1Mode = rhs.in1Mode;
in2Mode = rhs.in2Mode;
algMode = rhs.algMode;
return *this;
}

View file

@ -428,8 +428,10 @@ bool makeJSONStringGPIO(CModerator& moderator, char* opStr, int len)
bSend |= moderator.addJson("GPout1", info.outState[0], root);
bSend |= moderator.addJson("GPout2", info.outState[1], root);
bSend |= moderator.addJson("GPanlg", info.algVal * 100 / 4096, root);
bSend |= moderator.addJson("GPmodeIn", GPIOinNames[info.inMode], root);
bSend |= moderator.addJson("GPmodeOut", GPIOoutNames[info.outMode], root);
bSend |= moderator.addJson("GPmodeIn1", GPIOin1Names[info.in1Mode], root);
bSend |= moderator.addJson("GPmodeIn2", GPIOin2Names[info.in2Mode], root);
bSend |= moderator.addJson("GPmodeOut1", GPIOout1Names[info.out1Mode], root);
bSend |= moderator.addJson("GPmodeOut2", GPIOout2Names[info.out2Mode], root);
bSend |= moderator.addJson("GPmodeAnlg", GPIOalgNames[info.algMode], root);
if(bSend) {

View file

@ -345,8 +345,41 @@ sUserSettings::load()
validatedLoad("cyclicStop", cyclic.Stop, 0, s8inBounds, 0, 10);
validatedLoad("cyclicStart", cyclic.Start, -1, s8inBounds, -20, 0);
uint8_t tVal;
validatedLoad("GPIOinMode", tVal, 0, u8inBounds, 0, 4); GPIO.inMode = (GPIOinModes)tVal;
validatedLoad("GPIOoutMode", tVal, 0, u8inBounds, 0, 2); GPIO.outMode = (GPIOoutModes)tVal;
// validatedLoad("GPIOinMode", tVal, 0, u8inBounds, 0, 4); GPIO.inMode = (GPIOinModes)tVal;
validatedLoad("GPIOinMode", tVal, 0, u8inBounds, 0, 255);
if(tVal <= 4) {
// migrate old GPIO input mode
GPIO.in1Mode = GPIOin1None;
GPIO.in2Mode = GPIOin2None;
switch(tVal) {
case 1: GPIO.in1Mode = GPIOin1On; GPIO.in2Mode = GPIOin2Off; break;
case 2: GPIO.in1Mode = GPIOin1Hold; GPIO.in2Mode = GPIOin2ExtThermostat; break;
case 3: GPIO.in1Mode = GPIOin1OnOff; break;
case 4: GPIO.in2Mode = GPIOin2ExtThermostat; break;
}
preferences.putUChar("GPIOinMode", 0xff); // cancel old
preferences.putUChar("GPIOin1Mode", GPIO.in1Mode); // set new
preferences.putUChar("GPIOin2Mode", GPIO.in2Mode); // set new
}
validatedLoad("GPIOin1Mode", tVal, 0, u8inBounds, 0, 3); GPIO.in1Mode = (GPIOin1Modes)tVal;
validatedLoad("GPIOin2Mode", tVal, 0, u8inBounds, 0, 2); GPIO.in2Mode = (GPIOin2Modes)tVal;
// validatedLoad("GPIOoutMode", tVal, 0, u8inBounds, 0, 2); GPIO.outMode = (GPIOoutModes)tVal;
validatedLoad("GPIOoutMode", tVal, 0, u8inBounds, 0, 255);
if(tVal <= 2) {
// migrate old GPIO output mode
GPIO.out1Mode = GPIOout1None;
GPIO.out2Mode = GPIOout2None;
switch(tVal) {
case 0: GPIO.out1Mode = GPIOout1None; GPIO.out2Mode = GPIOout2None; break;
case 1: GPIO.out1Mode = GPIOout1Status; GPIO.out2Mode = GPIOout2None; break;
case 2: GPIO.out1Mode = GPIOout1User; GPIO.out2Mode = GPIOout2User; break;
}
preferences.putUChar("GPIOoutMode", 0xff); // cancel old
preferences.putUChar("GPIOout1Mode", GPIO.out1Mode); // set new
preferences.putUChar("GPIOout2Mode", GPIO.out2Mode); // set new
}
validatedLoad("GPIOout1Mode", tVal, 0, u8inBounds, 0, 2); GPIO.out1Mode = (GPIOout1Modes)tVal;
validatedLoad("GPIOout2Mode", tVal, 0, u8inBounds, 0, 1); GPIO.out2Mode = (GPIOout2Modes)tVal;
validatedLoad("GPIOalgMode", tVal, 0, u8inBounds, 0, 2); GPIO.algMode = (GPIOalgModes)tVal;
validatedLoad("MenuOnTimeout", HomeMenu.onTimeout, 0, u8inBounds, 0, 3);
validatedLoad("MenuonStart", HomeMenu.onStart, 0, u8inBounds, 0, 3);
@ -373,8 +406,10 @@ sUserSettings::save()
preferences.putUChar("enableOTA", enableOTA);
preferences.putChar("cyclicStop", cyclic.Stop);
preferences.putChar("cyclicStart",cyclic.Start);
preferences.putUChar("GPIOinMode", GPIO.inMode);
preferences.putUChar("GPIOoutMode", GPIO.outMode);
preferences.putUChar("GPIOin1Mode", GPIO.in1Mode);
preferences.putUChar("GPIOin2Mode", GPIO.in2Mode);
preferences.putUChar("GPIOout1Mode", GPIO.out1Mode);
preferences.putUChar("GPIOout2Mode", GPIO.out2Mode);
preferences.putUChar("GPIOalgMode", GPIO.algMode);
preferences.putUChar("MenuOnTimeout", HomeMenu.onTimeout);
preferences.putUChar("MenuonStart", HomeMenu.onStart);

View file

@ -267,8 +267,10 @@ struct sUserSettings : public CESP32_NVStorage {
retval &= useThermostat < 2;
retval &= (enableWifi == 0) || (enableWifi == 1);
retval &= (enableOTA == 0) || (enableOTA == 1);
retval &= GPIO.inMode < 4;
retval &= GPIO.outMode < 3;
retval &= GPIO.in1Mode < 4;
retval &= GPIO.in2Mode < 3;
retval &= GPIO.out1Mode < 3;
retval &= GPIO.out2Mode < 2;
retval &= INBOUNDS(FrameRate, 300, 1500);
retval &= cyclic.valid();
retval &= HomeMenu.valid();
@ -284,8 +286,10 @@ struct sUserSettings : public CESP32_NVStorage {
useThermostat = 1;
enableWifi = 1;
enableOTA = 1;
GPIO.inMode = GPIOinNone;
GPIO.outMode = GPIOoutNone;
GPIO.in1Mode = GPIOin1None;
GPIO.in2Mode = GPIOin2None;
GPIO.out1Mode = GPIOout1None;
GPIO.out2Mode = GPIOout2None;
GPIO.algMode = GPIOalgNone;
FrameRate = 1000;
cyclic.init();
@ -303,8 +307,10 @@ struct sUserSettings : public CESP32_NVStorage {
useThermostat = rhs.useThermostat;
enableWifi = rhs.enableWifi;
enableOTA = rhs.enableOTA;
GPIO.inMode = rhs.GPIO.inMode;
GPIO.outMode = rhs.GPIO.outMode;
GPIO.in1Mode = rhs.GPIO.in1Mode;
GPIO.in2Mode = rhs.GPIO.in2Mode;
GPIO.out1Mode = rhs.GPIO.out1Mode;
GPIO.out2Mode = rhs.GPIO.out2Mode;
GPIO.algMode = rhs.GPIO.algMode;
FrameRate = rhs.FrameRate;
cyclic = rhs.cyclic;