Added GPIO out user mode

This commit is contained in:
rljonesau 2019-04-10 09:28:46 +10:00
parent 7332d4e797
commit aba5762c0c
16 changed files with 285 additions and 348 deletions

View file

@ -410,9 +410,8 @@ void setup() {
bBTconnected = false;
Bluetooth.begin();
GPIOin.begin(GPIOin1_pin, GPIOin2_pin, GPIOinOn1Off1);
GPIOout.begin(GPIOout1_pin, GPIOout2_pin, GPIOoutStatus);
setupGPIO();
}
@ -1231,3 +1230,21 @@ bool isCyclicActive()
return bUserON && (NVstore.getCyclicMode() != 0);
}
void setupGPIO()
{
GPIOin.begin(GPIOin1_pin, GPIOin2_pin, NVstore.getGPIOinMode());
GPIOout.begin(GPIOout1_pin, GPIOout2_pin, NVstore.getGPIOoutMode());
}
void setGPIO(int channel, bool state)
{
DebugPort.print("setGPIO: Output #"); DebugPort.print(channel+1); DebugPort.print(" = "); DebugPort.println(state);
GPIOout.setState(channel, state);
}
bool getGPIO(int channel)
{
bool retval = GPIOout.getState(channel);
DebugPort.print("getGPIO: Output #"); DebugPort.print(channel+1); DebugPort.print(" = "); DebugPort.println(retval);
return retval;
}

View file

@ -144,7 +144,7 @@ CBasicScreen::keyHandler(uint8_t event)
if(event & keyPressed) {
repeatCount = 0; // unlock tracking of repeat events
// press LEFT to select previous screen, or Fixed Hz mode when in mode select
/* // press LEFT to select previous screen, or Fixed Hz mode when in mode select
if(event & key_Left) {
if(!_showMode)
_ScreenManager.prevMenu();
@ -159,8 +159,8 @@ CBasicScreen::keyHandler(uint8_t event)
}
_ScreenManager.reqUpdate();
}
}
// press RIGHT to select next screen, or Thermostat mode when in mode select
}**/
/* // press RIGHT to select next screen, or Thermostat mode when in mode select
if(event & key_Right) {
if(!_showMode)
_ScreenManager.nextMenu();
@ -175,7 +175,7 @@ CBasicScreen::keyHandler(uint8_t event)
}
_ScreenManager.reqUpdate();
}
}
}*/
// press UP & DOWN to toggle thermostat / fixed Hz mode
// impossible with 5 way switch!
uint8_t doubleKey = key_Down | key_Up;
@ -192,6 +192,20 @@ CBasicScreen::keyHandler(uint8_t event)
if(event & keyRepeat) {
if(repeatCount >= 0) {
repeatCount++;
// hold LEFT to toggle GPIO output #1
if(event & key_Left) {
if(repeatCount > 2) {
repeatCount = -1; // prevent double handling
setGPIO(0, !getGPIO(0)); // toggle GPIO output #1
}
}
// hold RIGHT to toggle GPIO output #2
if(event & key_Right) {
if(repeatCount > 2) {
repeatCount = -1; // prevent double handling
setGPIO(1, !getGPIO(1)); // toggle GPIO output #2
}
}
// hold DOWN to enter thermostat / fixed mode selection
if(event & key_Down) {
if(repeatCount > 2) {
@ -244,6 +258,41 @@ CBasicScreen::keyHandler(uint8_t event)
_reqOEMWarning();
}
}
if(event & key_Left) {
if(repeatCount >= 0) {
if(!_showMode) {
_ScreenManager.prevMenu();
}
else {
if(hasOEMcontroller())
_reqOEMWarning();
else {
_showMode = millis() + 5000;
_nModeSel = 0;
setThermostatMode(1); // set the new mode
NVstore.save();
}
_ScreenManager.reqUpdate();
}
}
}
if(event & key_Right) {
if(repeatCount >= 0) {
if(!_showMode)
_ScreenManager.nextMenu();
else {
if(hasOEMcontroller())
_reqOEMWarning();
else {
_showMode = millis() + 5000;
_nModeSel = 1;
setThermostatMode(0); // set the new mode
NVstore.save();
}
_ScreenManager.reqUpdate();
}
}
}
// release CENTRE to accept new mode, and/or show current setting
if(event & key_Centre) {
if(repeatCount != -2) { // prevent after off commands

View file

@ -37,6 +37,7 @@
CClockScreen::CClockScreen(C128x64_OLED& display, CScreenManager& mgr) : CScreenHeader(display, mgr)
{
_colon = false;
_keyRepeatCount = -1;
}
void
@ -77,14 +78,15 @@ bool
CClockScreen::keyHandler(uint8_t event)
{
if(event & keyPressed) {
_keyRepeatCount = 0; // unlock tracking of repeat events
// press LEFT
if(event & key_Left) {
/* if(event & key_Left) {
_ScreenManager.prevMenu();
}
// press RIGHT
if(event & key_Right) {
_ScreenManager.nextMenu();
}
}*/
// press UP
if(event & key_Up) {
_ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::SetClockUI); // switch to clock set screen
@ -94,6 +96,37 @@ CClockScreen::keyHandler(uint8_t event)
_ScreenManager.selectMenu(CScreenManager::TimerMenuLoop); // switch to timer set screen loop
}
}
if(event & keyRepeat) {
if(_keyRepeatCount >= 0) {
_keyRepeatCount++;
// hold LEFT to toggle GPIO output #1
if(event & key_Left) {
if(_keyRepeatCount > 2) {
_keyRepeatCount = -1; // prevent double handling
setGPIO(0, !getGPIO(0)); // toggle GPIO output #1
}
}
// hold RIGHT to toggle GPIO output #2
if(event & key_Right) {
if(_keyRepeatCount > 2) {
_keyRepeatCount = -1; // prevent double handling
setGPIO(1, !getGPIO(1)); // toggle GPIO output #2
}
}
}
}
// release event
if(event & keyReleased) {
if(_keyRepeatCount == 0) { // short Up press - lower target
if(event & key_Left) {
_ScreenManager.prevMenu();
}
if(event & key_Right) {
_ScreenManager.nextMenu();
}
}
_keyRepeatCount = -1;
}
return true;
}

View file

@ -32,6 +32,7 @@ class CClockScreen : public CScreenHeader {
protected:
virtual void showTime(int numTimers);
bool _colon;
int _keyRepeatCount;
public:
CClockScreen(C128x64_OLED& display, CScreenManager& mgr);
bool show();

View file

@ -176,17 +176,32 @@ CDetailedScreen::keyHandler(uint8_t event)
if(event & keyPressed) {
_keyRepeatCount = 0; // unlock tracking of repeat events
if(event & key_Left) {
/* if(event & key_Left) {
_ScreenManager.prevMenu();
}
if(event & key_Right) {
_ScreenManager.nextMenu();
}
}*/
}
// require hold to turn ON or OFF
if(event & keyRepeat) {
if(_keyRepeatCount >= 0) {
_keyRepeatCount++;
// hold LEFT to toggle GPIO output #1
if(event & key_Left) {
if(_keyRepeatCount > 2) {
_keyRepeatCount = -1; // prevent double handling
setGPIO(0, !getGPIO(0)); // toggle GPIO output #1
}
}
// hold RIGHT to toggle GPIO output #2
if(event & key_Right) {
if(_keyRepeatCount > 2) {
_keyRepeatCount = -1; // prevent double handling
setGPIO(1, !getGPIO(1)); // toggle GPIO output #2
}
}
if(event & key_Centre) {
int runstate = getHeaterInfo().getRunStateEx();
if(runstate) { // running, including cyclic mode idle
@ -235,6 +250,12 @@ CDetailedScreen::keyHandler(uint8_t event)
_showTarget = millis() + 3500;
}
_ScreenManager.reqUpdate();
if(event & key_Left) {
_ScreenManager.prevMenu();
}
if(event & key_Right) {
_ScreenManager.nextMenu();
}
}
_keyRepeatCount = -1;
}

View file

@ -1,257 +0,0 @@
/*
* 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 "128x64OLED.h"
#include "ExperimentalSettingsScreen.h"
#include "KeyPad.h"
#include "../Protocol/helpers.h"
#include "../Utility/UtilClasses.h"
#include "../Utility/NVStorage.h"
///////////////////////////////////////////////////////////////////////////
//
// CExperimentalSettingsScreen
//
// This screen provides control over experimental features
//
///////////////////////////////////////////////////////////////////////////
static const int Line3 = 14;
static const int Line2 = 27;
static const int Line1 = 40;
static const int Column = 70;
CExperimentalSettingsScreen::CExperimentalSettingsScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr)
{
_initUI();
_window = 10;
_thermoMode = 0;
_cyclicMode = 0;
}
void
CExperimentalSettingsScreen::onSelect()
{
CPasswordScreen::onSelect();
_initUI();
_window = NVstore.getThermostatMethodWindow();
_thermoMode = NVstore.getThermostatMethodMode();
_cyclicMode = NVstore.getCyclicMode();
}
void
CExperimentalSettingsScreen::_initUI()
{
_rowSel = 0;
_animateCount = 0;
}
bool
CExperimentalSettingsScreen::show()
{
char msg[20];
_display.clearDisplay();
if(!CPasswordScreen::show()) { // for showing "saving settings"
if(_rowSel == 4) {
_printInverted(_display.xCentre(), 0, " Saving Settings ", true, eCentreJustify);
_printMenuText(_display.xCentre(), 35, "Press UP to", false, eCentreJustify);
_printMenuText(_display.xCentre(), 43, "confirm save", false, eCentreJustify);
}
else {
_printInverted(_display.xCentre(), 0, " Experimental ", true, eCentreJustify);
_printMenuText(65, Line3, "Suspend:", false, eRightJustify);
_printMenuText(65, Line2, "Thermostat:", false, eRightJustify);
_printMenuText(65, Line1, "Window:", false, eRightJustify);
sprintf(msg, "%.1f\367C", _window); // \367 is octal for Adafruit degree symbol
_printMenuText(Column, Line1, msg, _rowSel == 1);
switch(_thermoMode) {
case 1:
_printMenuText(Column, Line2, "Deadband", _rowSel == 2);
break;
case 2:
_printMenuText(Column, Line2, "Linear Hz", _rowSel == 2);
break;
default:
_printMenuText(Column, Line2, "Standard", _rowSel == 2);
break;
}
if(_cyclicMode) {
sprintf(msg, "> %d\367C", _cyclicMode+1); // \367 is octal for Adafruit degree symbol
}
else {
strcpy(msg, "OFF");
}
_printMenuText(Column, Line3, msg, _rowSel == 3);
}
}
return true;
}
bool
CExperimentalSettingsScreen::animate()
{
if(_rowSel != 4) {
int yPos = 53;
int xPos = _display.xCentre();
const char* pMsg = NULL;
switch(_rowSel) {
case 0:
_printMenuText(xPos, yPos, " Exit ", true, eCentreJustify);
_printMenuText(_display.width(), yPos, "\030Edit", false, eRightJustify);
break;
case 1:
_display.drawFastHLine(0, 52, 128, WHITE);
pMsg = " User defined window for custom thermostat modes. ";
_scrollMessage(56, pMsg, _startChar);
break;
case 2:
_display.drawFastHLine(0, 52, 128, WHITE);
switch(_thermoMode) {
case 1:
pMsg = " Controller holds measured temperature at the set point whilst within the window. ";
break;
case 2:
pMsg = " Controller uses Fixed Hz mode, adjusting pump rate linearly across the set point window. ";
break;
default:
pMsg = " Use heater's standard thermostat control. ";
break;
}
if(pMsg)
_scrollMessage(56, pMsg, _startChar);
break;
case 3:
_display.drawFastHLine(0, 52, 128, WHITE);
pMsg = " Controller auto cycles heater if over temperature occurs. ";
_scrollMessage(56, pMsg, _startChar);
break;
}
return true;
}
return false;
}
bool
CExperimentalSettingsScreen::keyHandler(uint8_t event)
{
if(event & keyPressed) {
// press LEFT to select previous screen
if(event & key_Left) {
switch(_rowSel) {
case 2:
_startChar = 0;
case 1:
case 3:
_adjust(-1);
break;
case 4:
_rowSel = 0; // abort save
break;
}
}
// press RIGHT to select next screen
if(event & key_Right) {
switch(_rowSel) {
case 2:
_startChar = 0;
case 1:
case 3:
_adjust(+1);
break;
case 4:
_rowSel = 0; // abort save
break;
}
}
if(event & key_Down) {
if(_rowSel == 0) {
_ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::FontDumpUI);
}
else {
_rowSel--;
LOWERLIMIT(_rowSel, 0);
}
}
// UP press
if(event & key_Up) {
switch(_rowSel) {
case 0:
case 1:
case 2:
case 3:
_startChar = 0;
_rowSel++;
UPPERLIMIT(_rowSel, 3);
break;
case 4: // confirmed save
_showStoringMessage();
NVstore.setThermostatMethodMode(_thermoMode);
NVstore.setThermostatMethodWindow(_window);
NVstore.setCyclicMode(_cyclicMode);
saveNV();
_rowSel = 0;
break;
}
}
// CENTRE press
if(event & key_Centre) {
switch(_rowSel) {
case 0:
_ScreenManager.selectMenu(CScreenManager::RootMenuLoop); // force return to main menu
break;
case 1:
case 2:
case 3:
_rowSel = 4;
break;
}
}
_ScreenManager.reqUpdate();
}
return true;
}
void
CExperimentalSettingsScreen::_adjust(int dir)
{
switch(_rowSel) {
case 1: // window
_window += (dir * 0.1);
UPPERLIMIT(_window, 6.3);
LOWERLIMIT(_window, 0.2);
break;
case 2: // thermostat mode
_thermoMode += dir;
ROLLLOWERLIMIT(_thermoMode, 0, 2);
ROLLUPPERLIMIT(_thermoMode, 2, 0);
break;
case 3:
_cyclicMode += dir;
UPPERLIMIT(_cyclicMode, 10);
LOWERLIMIT(_cyclicMode, 0);
break;
}
}

View file

@ -1,49 +0,0 @@
/*
* 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 __EXPERIMENTALSETTINGSSCREEN_H__
#define __EXPERIMENTALSETTINGSSCREEN_H__
#include <stdint.h>
#include "PasswordScreen.h"
class C128x64_OLED;
class CScreenManager;
class CExperimentalSettingsScreen : public CPasswordScreen
{
int _rowSel;
void _adjust(int dir);
float _window;
int _thermoMode;
int _cyclicMode;
int _animateCount;
int _startChar;
void _initUI();
public:
CExperimentalSettingsScreen(C128x64_OLED& display, CScreenManager& mgr);
bool show();
bool animate();
bool keyHandler(uint8_t event);
void onSelect();
};
#endif

View file

@ -97,7 +97,7 @@ CFontDumpScreen::keyHandler(uint8_t event)
}
// CENTRE press
if(event & key_Centre) {
_ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::ExperimentalUI); // force return to prior menu
_ScreenManager.selectMenu(CScreenManager::UserSettingsLoop, CScreenManager::ExThermostatUI); // force return to prior menu
}
_ScreenManager.reqUpdate();
}

View file

@ -31,10 +31,11 @@
#include "RebootScreen.h"
#include "HeaterSettingsScreen.h"
#include "SettingsScreen.h"
#include "ExperimentalSettingsScreen.h"
#include "ThermostatModeScreen.h"
#include "FontDumpScreen.h"
#include "TimerChartScreen.h"
#include "InheritSettingsScreen.h"
#include "GPIOScreen.h"
#include <Wire.h>
#include "../cfg/pins.h"
#include "../cfg/BTCConfig.h"
@ -204,11 +205,15 @@ CScreenManager::begin(bool bNoClock)
menuloop.push_back(new CFuelMixtureScreen(*_pDisplay, *this)); // tuning
menuloop.push_back(new CHeaterSettingsScreen(*_pDisplay, *this)); // tuning
_Screens.push_back(menuloop);
// create User Settings screens loop
menuloop.clear();
menuloop.push_back(new CThermostatModeScreen(*_pDisplay, *this)); // experimental settings screen
menuloop.push_back(new CGPIOScreen(*_pDisplay, *this)); // GPIO settings screen
_Screens.push_back(menuloop);
// create branch screens
menuloop.clear();
menuloop.push_back(new CSetClockScreen(*_pDisplay, *this)); // clock set branch screen
menuloop.push_back(new CInheritSettingsScreen(*_pDisplay, *this)); // inherit OEM settings branch screen
menuloop.push_back(new CExperimentalSettingsScreen(*_pDisplay, *this)); // experimental settings branch screen
menuloop.push_back(new CFontDumpScreen(*_pDisplay, *this)); // font dump branch screen
_Screens.push_back(menuloop);

View file

@ -43,12 +43,13 @@ class CScreenManager {
void _leaveScreen();
void _changeSubMenu(int dir);
public:
enum eUIMenuSets { RootMenuLoop, TimerMenuLoop, TuningMenuLoop, BranchMenu };
enum eUIMenuSets { RootMenuLoop, TimerMenuLoop, TuningMenuLoop, UserSettingsLoop, BranchMenu };
enum eUIRootMenus { DetailedControlUI, BasicControlUI, ClockUI, ModeUI, CommsUI, SettingsUI };
enum eUITimerMenus { TimerOverviewUI, Timer1UI, Timer2UI, Timer3UI, Timer4UI, Timer5UI, Timer6UI, Timer7UI,
Timer8UI, Timer9UI, Timer10UI, Timer11UI, Timer12UI, Timer13UI, Timer14UI };
enum eUITuningMenus { MixtureUI, HeaterSettingsUI };
enum eUIBranchMenus { SetClockUI, InheritSettingsUI, ExperimentalUI, FontDumpUI };
enum eUIUserSettingsMenus { ExThermostatUI, GPIOUI };
enum eUIBranchMenus { SetClockUI, InheritSettingsUI, FontDumpUI };
public:
CScreenManager();
~CScreenManager();

View file

@ -167,7 +167,8 @@ CSettingsScreen::keyHandler(uint8_t event)
}
// press DOWN
if(event & key_Down) {
_ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::ExperimentalUI);
// _ScreenManager.selectMenu(CScreenManager::BranchMenu, CScreenManager::ExperimentalUI);
_ScreenManager.selectMenu(CScreenManager::UserSettingsLoop, CScreenManager::ExThermostatUI);
}
}
}

View file

@ -56,6 +56,9 @@ extern bool hasOEMLCDcontroller();
extern int getBlueWireStat();
extern int getSmartError();
extern bool isCyclicActive();
extern void setupGPIO();
extern void setGPIO(int channel, bool state);
extern bool getGPIO(int channel);

View file

@ -22,7 +22,7 @@
#include "GPIO.h"
#include "../Protocol/helpers.h"
const int BREATHINTERVAL = 30;
const int BREATHINTERVAL = 45;
const int FADEAMOUNT = 3;
const int FLASHPERIOD = 2000;
const int ONFLASHINTERVAL = 50;
@ -156,6 +156,8 @@ CGPIOout::CGPIOout()
_breatheDelay = 0;
_statusState = 0;
_statusDelay = 0;
_userState = 0;
_prevState = -1;
}
void
@ -166,32 +168,33 @@ CGPIOout::begin(int pin1, int pin2, GPIOoutModes mode)
if(pin1) {
pinMode(pin1, OUTPUT); // GPIO output pin #1
digitalWrite(pin1, LOW);
ledcSetup(0, 500, 8); // create PWM channel for GPIO1
ledcSetup(0, 500, 8); // create PWM channel for GPIO1: 500Hz, 8 bits
}
if(pin2) {
pinMode(pin2, OUTPUT); // GPIO output pin #2
digitalWrite(pin2, LOW);
ledcSetup(1, 500, 8); // create PWM channel for GPIO2
ledcAttachPin(pin2, 1); // attach PWM to GPIO line
ledcSetup(1, 500, 8); // create PWM channel for GPIO2: 500Hz, 8 bits
}
setMode(mode);
}
void
CGPIOout::setMode(GPIOoutModes mode)
{
_Mode = mode;
_prevState = -1;
ledcDetachPin(_pins[0]); // ensure PWM detached from IO line
ledcDetachPin(_pins[1]); // ensure PWM detached from IO line
};
void
CGPIOout::manage()
{
switch (_Mode) {
case GPIOoutNone:
break;
case GPIOoutStatus:
_doStatus();
break;
case GPIOoutUser:
_doUser();
break;
case GPIOoutNone: break;
case GPIOoutStatus: _doStatus(); break;
case GPIOoutUser: _doUser(); break;
}
}
@ -201,12 +204,10 @@ CGPIOout::_doStatus()
if(_pins[0] == 0)
return;
// DebugPort.println("GPIOout::_doStatus()");
int runstate = getHeaterInfo().getRunStateEx();
int statusMode = 0;
switch(runstate) {
case 0:
statusMode = 0;
break;
case 1:
case 2:
case 3:
@ -232,6 +233,9 @@ CGPIOout::_doStatus()
statusMode = 4;
break;
}
// change of mode typically requires changing from simple digital out
// to PWM or vice versa
if(_prevState != statusMode) {
_prevState = statusMode;
_statusState = 0;
@ -244,7 +248,7 @@ CGPIOout::_doStatus()
case 1:
ledcAttachPin(_pins[0], 0); // attach PWM to GPIO line
ledcWrite(0, _statusState);
_breatheDelay = millis() + BREATHINTERVAL;
_breatheDelay = millis() + BREATHINTERVAL;
break;
case 2:
ledcDetachPin(_pins[0]); // detach PWM from IO line
@ -254,7 +258,7 @@ CGPIOout::_doStatus()
ledcAttachPin(_pins[0], 0); // attach PWM to GPIO line
_statusState = 255;
ledcWrite(0, _statusState);
_breatheDelay = millis() + BREATHINTERVAL;
_breatheDelay = millis() + BREATHINTERVAL;
break;
case 4:
ledcDetachPin(_pins[0]); // detach PWM from IO line
@ -273,7 +277,13 @@ CGPIOout::_doStatus()
void
CGPIOout::_doUser()
{
// DebugPort.println("GPIOout::_doUser()");
if(_pins[0]) {
digitalWrite(_pins[0], (_userState & 0x01) ? HIGH : LOW);
}
if(_pins[1]) {
digitalWrite(_pins[1], (_userState & 0x02) ? HIGH : LOW);
}
}
void
@ -282,8 +292,10 @@ CGPIOout::_doStartMode() // breath up PWM
long tDelta = millis() - _breatheDelay;
if(tDelta >= 0) {
_breatheDelay += BREATHINTERVAL;
_statusState += FADEAMOUNT;
ledcWrite(0, _statusState & 0xff);
int expo = ((_statusState >> 5) + 1);
_statusState += expo;
_statusState &= 0xff;
ledcWrite(0, _statusState);
}
}
@ -293,8 +305,11 @@ CGPIOout::_doStopMode() // breath down PWM
long tDelta = millis() - _breatheDelay;
if(tDelta >= 0) {
_breatheDelay += BREATHINTERVAL;
_statusState -= FADEAMOUNT;
ledcWrite(0, _statusState & 0xff);
int expo = ((_statusState >> 5) + 1);
_statusState -= expo;
_statusState &= 0xff;
ledcWrite(0, _statusState);
}
}
@ -313,4 +328,21 @@ CGPIOout::_doSuspendMode() // brief flash
digitalWrite(_pins[0], LOW);
}
}
}
void
CGPIOout::setState(int channel, bool state)
{
int mask = 0x01 << (channel & 0x01);
if(state)
_userState |= mask;
else
_userState &= ~mask;
}
bool
CGPIOout::getState(int channel)
{
int mask = 0x01 << (channel & 0x01);
return (_userState & mask) != 0;
}

View file

@ -19,6 +19,9 @@
*
*/
#ifndef __BTCGPIO_H__
#define __BTCGPIO_H__
#include <stdint.h>
enum GPIOinModes {
@ -63,12 +66,17 @@ class CGPIOout {
int _statusState;
int _statusDelay;
unsigned long _breatheDelay;
uint8_t _userState;
void _doStartMode();
void _doStopMode();
void _doSuspendMode();
public:
CGPIOout();
void setMode(GPIOoutModes mode) { _Mode = mode; };
void setMode(GPIOoutModes mode);
void begin(int pin1, int pin2, GPIOoutModes mode);
void manage();
void setState(int channel, bool state);
bool getState(int channel);
};
#endif // __BTCGPIO_H__

View file

@ -284,6 +284,55 @@ CHeaterStorage::setCyclicMode(unsigned char val)
save();
}
GPIOinModes
CHeaterStorage::getGPIOinMode()
{
GPIOinModes inMode = GPIOinNone;
switch(_calValues.Options.GPIOinMode) {
case 0: inMode = GPIOinNone; break;
case 1: inMode = GPIOinOn1Off2; break;
case 2: inMode = GPIOinOnHold1; break;
case 3: inMode = GPIOinOn1Off1; break;
}
return inMode;
}
void
CHeaterStorage::setGPIOinMode(unsigned char val)
{
_calValues.Options.GPIOinMode = val;
}
GPIOoutModes
CHeaterStorage::getGPIOoutMode()
{
GPIOoutModes outMode = GPIOoutNone;
switch(_calValues.Options.GPIOoutMode) {
case 0: outMode = GPIOoutNone; break;
case 1: outMode = GPIOoutStatus; break;
case 2: outMode = GPIOoutUser; break;
}
return outMode;
}
void
CHeaterStorage::setGPIOoutMode(unsigned char val)
{
_calValues.Options.GPIOoutMode = val;
}
unsigned char
CHeaterStorage::getGPIOalgMode()
{
return _calValues.Options.GPIOalgMode;
}
void
CHeaterStorage::setGPIOalgMode(unsigned char val)
{
_calValues.Options.GPIOalgMode = val;
}
///////////////////////////////////////////////////////////////////////////////////////
// ESP32
//
@ -403,6 +452,9 @@ CESP32HeaterStorage::loadUI()
validatedLoad("enableWifi", _calValues.Options.enableWifi, 1, u8inBounds, 0, 1);
validatedLoad("enableOTA", _calValues.Options.enableOTA, 1, u8inBounds, 0, 1);
validatedLoad("cyclicMode", _calValues.Options.cyclicMode, 0, u8inBounds, 0, 10);
validatedLoad("GPIOinMode", _calValues.Options.GPIOinMode, 0, u8inBounds, 0, 3);
validatedLoad("GPIOoutMode", _calValues.Options.GPIOoutMode, 0, u8inBounds, 0, 2);
validatedLoad("GPIOalgMode", _calValues.Options.GPIOalgMode, 0, u8inBounds, 0, 2);
preferences.end();
}
@ -416,6 +468,9 @@ CESP32HeaterStorage::saveUI()
preferences.putUChar("enableWifi", _calValues.Options.enableWifi);
preferences.putUChar("enableOTA", _calValues.Options.enableOTA);
preferences.putUChar("cyclicMode", _calValues.Options.cyclicMode);
preferences.putUChar("GPIOinMode", _calValues.Options.GPIOinMode);
preferences.putUChar("GPIOoutMode", _calValues.Options.GPIOoutMode);
preferences.putUChar("GPIOalgMode", _calValues.Options.GPIOalgMode);
preferences.end();
}

View file

@ -23,6 +23,7 @@
#define __BTC_NV_STORAGE_H__
#include "../RTC/Timers.h" // for sTimer
#include "GPIO.h"
struct sHeater {
uint8_t Pmin;
@ -68,6 +69,10 @@ struct sBTCoptions {
uint8_t enableWifi;
uint8_t enableOTA;
uint8_t cyclicMode;
uint8_t GPIOinMode;
uint8_t GPIOoutMode;
uint8_t GPIOalgMode;
bool valid() {
bool retval = true;
retval &= (DimTime >= 0) && (DimTime < 300000); // 5 mins
@ -76,6 +81,8 @@ struct sBTCoptions {
retval &= (enableWifi == 0) || (enableWifi == 1);
retval &= (enableOTA == 0) || (enableOTA == 1);
retval &= cyclicMode < 10;
retval &= GPIOinMode < 4;
retval &= GPIOoutMode < 3;
return retval;
}
void init() {
@ -85,6 +92,9 @@ struct sBTCoptions {
enableWifi = 1;
enableOTA = 1;
cyclicMode = 0;
GPIOinMode = 0;
GPIOoutMode = 0;
GPIOalgMode = 0;
};
};
@ -139,6 +149,9 @@ public:
unsigned char getWifiEnabled();
unsigned char getOTAEnabled();
unsigned char getCyclicMode();
GPIOinModes getGPIOinMode();
GPIOoutModes getGPIOoutMode();
unsigned char getGPIOalgMode();
void setPmin(float);
void setPmax(float);
@ -156,12 +169,16 @@ public:
void setWifiEnabled(unsigned char val);
void setOTAEnabled(unsigned char val);
void setCyclicMode(unsigned char val);
void setGPIOinMode(unsigned char val);
void setGPIOoutMode(unsigned char val);
void setGPIOalgMode(unsigned char val);
void getTimerInfo(int idx, sTimer& timerInfo);
void setTimerInfo(int idx, const sTimer& timerInfo);
};
#ifdef ESP32
#include <Preferences.h>