Added GPIO out user mode
This commit is contained in:
parent
7332d4e797
commit
aba5762c0c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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__
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue