Added under/over temperature threshold for GPIO outputs
This commit is contained in:
parent
96b3cecdb0
commit
f2af9c3fda
Binary file not shown.
After Width: | Height: | Size: 190 B |
|
@ -1585,6 +1585,8 @@ void setupGPIO()
|
|||
GPIOout2_pin,
|
||||
NVstore.getUserSettings().GPIO.out1Mode,
|
||||
NVstore.getUserSettings().GPIO.out2Mode);
|
||||
GPIOout.setThresh(NVstore.getUserSettings().GPIO.thresh[0],
|
||||
NVstore.getUserSettings().GPIO.thresh[1]);
|
||||
|
||||
// ### MAJOR ISSUE WITH ADC INPUTS ###
|
||||
//
|
||||
|
@ -1592,7 +1594,7 @@ void setupGPIO()
|
|||
// This is ADC2 channel (#9).
|
||||
// Unfortunately it was subsequently discovered that any ADC2 input cannot be
|
||||
// used if Wifi is enabled.
|
||||
// THIS ISSUE IS NOT RESOLBVABLE IN SOFTWARE.
|
||||
// THIS ISSUE IS NOT RESOLVABLE IN SOFTWARE.
|
||||
// *** It is not possible to use ANY of the 10 ADC2 channels if Wifi is enabled :-( ***
|
||||
//
|
||||
// Fix is to cut traces to GPIO33 & GPIO26 and swap the connections.
|
||||
|
|
|
@ -127,6 +127,10 @@ CGPIOInfoScreen::animate()
|
|||
_drawBitmap(99, 15, UserIconInfo);
|
||||
_drawBitmap(110, 13, bulbmode ? BulbOnIconInfo : BulbOffIconInfo);
|
||||
break;
|
||||
case CGPIOout1::Thresh:
|
||||
_drawBitmap(99, 15, threshIconInfo);
|
||||
_drawBitmap(110, 13, bulbmode ? BulbOnIconInfo : BulbOffIconInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
#if USE_JTAG == 0
|
||||
|
@ -138,6 +142,10 @@ CGPIOInfoScreen::animate()
|
|||
_drawBitmap(99, 27, UserIconInfo);
|
||||
_drawBitmap(110, 26, bulbmode ? BulbOnIconInfo : BulbOffIconInfo);
|
||||
break;
|
||||
case CGPIOout2::Thresh:
|
||||
_drawBitmap(99, 27, threshIconInfo);
|
||||
_drawBitmap(110, 26, bulbmode ? BulbOnIconInfo : BulbOffIconInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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"
|
||||
|
@ -31,6 +31,14 @@ extern CGPIOout GPIOout;
|
|||
extern CGPIOin GPIOin;
|
||||
extern CGPIOalg GPIOalg;
|
||||
|
||||
int8_t s8abs(int8_t val)
|
||||
{
|
||||
if(val >= 0)
|
||||
return val;
|
||||
else
|
||||
return -val;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGPIOSetupScreen
|
||||
|
@ -53,6 +61,8 @@ CGPIOSetupScreen::CGPIOSetupScreen(C128x64_OLED& display, CScreenManager& mgr) :
|
|||
_GPIOparams.out1Mode = CGPIOout1::Disabled;
|
||||
_GPIOparams.out2Mode = CGPIOout2::Disabled;
|
||||
_GPIOparams.algMode = CGPIOalg::Disabled;
|
||||
_GPIOparams.thresh[0] = 0;
|
||||
_GPIOparams.thresh[1] = 0;
|
||||
_ExtHold = 0;
|
||||
}
|
||||
|
||||
|
@ -63,6 +73,7 @@ CGPIOSetupScreen::onSelect()
|
|||
_initUI();
|
||||
_GPIOparams = NVstore.getUserSettings().GPIO;
|
||||
_ExtHold = NVstore.getUserSettings().ExtThermoTimeout;
|
||||
_repeatCount = -1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -75,6 +86,8 @@ CGPIOSetupScreen::_initUI()
|
|||
bool
|
||||
CGPIOSetupScreen::show()
|
||||
{
|
||||
char msg[16];
|
||||
|
||||
_display.clearDisplay();
|
||||
|
||||
static bool animated = false;
|
||||
|
@ -138,6 +151,17 @@ CGPIOSetupScreen::show()
|
|||
case CGPIOout1::Disabled: msgText = "---"; break;
|
||||
case CGPIOout1::Status: msgText = "Status"; break;
|
||||
case CGPIOout1::User: msgText = "User"; break;
|
||||
case CGPIOout1::Thresh:
|
||||
if(_rowSel == 6) {
|
||||
sprintf(msg, " %dC", s8abs(_GPIOparams.thresh[0]));
|
||||
_printMenuText(Column2, Line3, msg, false);
|
||||
_printMenuText(Column2, Line3, _GPIOparams.thresh[0] >= 0 ? ">" : "<", true);
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "%s %dC", _GPIOparams.thresh[0] >= 0 ? ">" : "<", s8abs(_GPIOparams.thresh[0]));
|
||||
_printMenuText(Column2, Line3, msg, _rowSel == 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(msgText)
|
||||
_printMenuText(Column2, Line3, msgText, _rowSel == 6);
|
||||
|
@ -149,6 +173,17 @@ CGPIOSetupScreen::show()
|
|||
switch(_GPIOparams.out2Mode) {
|
||||
case CGPIOout2::Disabled: msgText = "---"; break;
|
||||
case CGPIOout2::User: msgText = "User"; break;
|
||||
case CGPIOout2::Thresh:
|
||||
if(_rowSel == 5) {
|
||||
sprintf(msg, " %d`C", s8abs(_GPIOparams.thresh[1]));
|
||||
_printMenuText(Column2, Line2, msg, false);
|
||||
_printMenuText(Column2, Line2, _GPIOparams.thresh[1] >= 0 ? ">" : "<", true);
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "%s %d`C", _GPIOparams.thresh[1] >= 0 ? ">" : "<", s8abs(_GPIOparams.thresh[1]));
|
||||
_printMenuText(Column2, Line2, msg, _rowSel == 7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(msgText)
|
||||
_printMenuText(Column2, Line2, msgText, _rowSel == 5);
|
||||
|
@ -227,6 +262,12 @@ CGPIOSetupScreen::animate()
|
|||
switch(_GPIOparams.out2Mode) {
|
||||
case CGPIOout2::Disabled: pMsg = " Output 2: DISABLED. "; break;
|
||||
case CGPIOout2::User: pMsg = " Output 2: User controlled. "; break;
|
||||
case CGPIOout2::Thresh:
|
||||
if(_GPIOparams.thresh[1] >= 0)
|
||||
pMsg = " Output 2: Active if over temperature. Hold LEFT to set under. Hold RIGHT to set over. ";
|
||||
else
|
||||
pMsg = " Output 2: Active if under temperature. Hold LEFT to set under. Hold RIGHT to set over. ";
|
||||
break;
|
||||
}
|
||||
if(pMsg)
|
||||
_scrollMessage(56, pMsg, _scrollChar);
|
||||
|
@ -237,10 +278,32 @@ CGPIOSetupScreen::animate()
|
|||
case CGPIOout1::Disabled: pMsg = " Output 1: DISABLED. "; break;
|
||||
case CGPIOout1::Status: pMsg = " Output 1: LED status indicator. "; break;
|
||||
case CGPIOout1::User: pMsg = " Output 1: User controlled. "; break;
|
||||
case CGPIOout1::Thresh:
|
||||
if(_GPIOparams.thresh[0] >= 0)
|
||||
pMsg = " Output 1: Active if over temperature. Hold LEFT to set under. Hold RIGHT to set over. ";
|
||||
else
|
||||
pMsg = " Output 1: Active if under temperature. Hold LEFT to set under. Hold RIGHT to set over. ";
|
||||
break;
|
||||
}
|
||||
if(pMsg)
|
||||
_scrollMessage(56, pMsg, _scrollChar);
|
||||
break;
|
||||
case 7:
|
||||
_display.drawFastHLine(0, 52, 128, WHITE);
|
||||
if(_GPIOparams.thresh[1] >= 0)
|
||||
pMsg = " Output 2: Active if over temperature. CENTRE to accept. Hold LEFT to set under. ";
|
||||
else
|
||||
pMsg = " Output 2: Active if under temperature. CENTRE to accept. Hold RIGHT to set over. ";
|
||||
_scrollMessage(56, pMsg, _scrollChar);
|
||||
break;
|
||||
case 8:
|
||||
_display.drawFastHLine(0, 52, 128, WHITE);
|
||||
if(_GPIOparams.thresh[0] >= 0)
|
||||
pMsg = " Output 1: Active if over temperature. Centre to accept. Hold LEFT to set under. ";
|
||||
else
|
||||
pMsg = " Output 1: Active if under temperature. Centre to accept. Hold RIGHT to set over. ";
|
||||
_scrollMessage(56, pMsg, _scrollChar);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -251,109 +314,164 @@ CGPIOSetupScreen::animate()
|
|||
bool
|
||||
CGPIOSetupScreen::keyHandler(uint8_t event)
|
||||
{
|
||||
|
||||
sUserSettings us;
|
||||
if(event & keyPressed) {
|
||||
// press LEFT to select previous screen
|
||||
if(event & key_Left) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.prevMenu();
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
_scrollChar = 0;
|
||||
_adjust(-1);
|
||||
break;
|
||||
case 10:
|
||||
_rowSel = 0; // abort save
|
||||
break;
|
||||
_repeatCount = 0;
|
||||
}
|
||||
|
||||
if(event & keyRepeat) {
|
||||
if(_repeatCount >= 0) {
|
||||
_repeatCount++;
|
||||
// hold LEFT to toggle GPIO output #1
|
||||
if(event & key_Left) {
|
||||
if(_repeatCount > 1) {
|
||||
_repeatCount = -1; // prevent double handling
|
||||
if((_rowSel == 6 || _rowSel == 8) && _GPIOparams.out1Mode == CGPIOout1::Thresh) {
|
||||
_GPIOparams.thresh[0] = -s8abs(_GPIOparams.thresh[0]);
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[0], -50, -1);
|
||||
_rowSel = 8;
|
||||
}
|
||||
if((_rowSel == 5 || _rowSel == 7) && _GPIOparams.out2Mode == CGPIOout2::Thresh) {
|
||||
_GPIOparams.thresh[1] = -s8abs(_GPIOparams.thresh[1]);
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[1], -50, -1);
|
||||
_rowSel = 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event & key_Right) {
|
||||
if(_repeatCount > 1) {
|
||||
_repeatCount = -1; // prevent double handling
|
||||
if((_rowSel == 6 || _rowSel == 8) && _GPIOparams.out1Mode == CGPIOout1::Thresh) {
|
||||
_GPIOparams.thresh[0] = s8abs(_GPIOparams.thresh[0]);
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[0], 0, 50);
|
||||
_rowSel = 8;
|
||||
}
|
||||
if((_rowSel == 5 || _rowSel == 7) && _GPIOparams.out2Mode == CGPIOout2::Thresh) {
|
||||
_GPIOparams.thresh[1] = s8abs(_GPIOparams.thresh[1]);
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[1], 0, 50);
|
||||
_rowSel = 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// press RIGHT to select next screen
|
||||
if(event & key_Right) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.nextMenu();
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
_scrollChar = 0;
|
||||
_adjust(+1);
|
||||
break;
|
||||
case 10:
|
||||
_rowSel = 0; // abort save
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(event & key_Down) {
|
||||
if(_rowSel == 10) {
|
||||
_rowSel = 0; // abort save
|
||||
}
|
||||
else {
|
||||
_scrollChar = 0;
|
||||
_rowSel--;
|
||||
if((_rowSel == 3) && (_GPIOparams.in2Mode != CGPIOin2::Thermostat))
|
||||
_rowSel--; // force skip if not set to external thermostat
|
||||
if((_rowSel == 1) && ((getBoardRevision() == BRD_V2_GPIO_NOALG) || (getBoardRevision() == BRD_V3_GPIO_NOALG))) // GPIO but NO analog support
|
||||
_rowSel--; // force skip if analog input is not supported by PCB
|
||||
LOWERLIMIT(_rowSel, 0);
|
||||
}
|
||||
}
|
||||
// UP press
|
||||
if(event & key_Up) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
if((getBoardRevision() == BRD_V2_GPIO_NOALG) || (getBoardRevision() == BRD_V3_GPIO_NOALG)) // GPIO but NO Analog support
|
||||
_rowSel++; // force skip if analog input is not supported by PCB
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
_scrollChar = 0;
|
||||
_rowSel++;
|
||||
if((_rowSel == 3) && (_GPIOparams.in2Mode != CGPIOin2::Thermostat))
|
||||
_rowSel++; // force skip if not set to external thermostat
|
||||
UPPERLIMIT(_rowSel, 6);
|
||||
break;
|
||||
case 10: // confirmed save
|
||||
_enableStoringMessage();
|
||||
us = NVstore.getUserSettings();
|
||||
us.GPIO = _GPIOparams;
|
||||
us.ExtThermoTimeout = _ExtHold;
|
||||
NVstore.setUserSettings(us);
|
||||
saveNV();
|
||||
}
|
||||
|
||||
setupGPIO();
|
||||
|
||||
_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:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
_rowSel = 10;
|
||||
break;
|
||||
if(event & keyReleased) {
|
||||
// press LEFT to select previous screen
|
||||
if(_repeatCount == 0) {
|
||||
if(event & key_Left) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.prevMenu();
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
_scrollChar = 0;
|
||||
_adjust(-1);
|
||||
break;
|
||||
case 10:
|
||||
_rowSel = 0; // abort save
|
||||
break;
|
||||
}
|
||||
}
|
||||
// press RIGHT to select next screen
|
||||
if(event & key_Right) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
_ScreenManager.nextMenu();
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
_scrollChar = 0;
|
||||
_adjust(+1);
|
||||
break;
|
||||
case 10:
|
||||
_rowSel = 0; // abort save
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(event & key_Down) {
|
||||
if(_rowSel == 10) {
|
||||
_rowSel = 0; // abort save
|
||||
}
|
||||
else {
|
||||
_scrollChar = 0;
|
||||
_rowSel--;
|
||||
if((_rowSel == 3) && (_GPIOparams.in2Mode != CGPIOin2::Thermostat))
|
||||
_rowSel--; // force skip if not set to external thermostat
|
||||
if((_rowSel == 1) && ((getBoardRevision() == BRD_V2_GPIO_NOALG) || (getBoardRevision() == BRD_V3_GPIO_NOALG))) // GPIO but NO analog support
|
||||
_rowSel--; // force skip if analog input is not supported by PCB
|
||||
LOWERLIMIT(_rowSel, 0);
|
||||
}
|
||||
}
|
||||
// UP press
|
||||
if(event & key_Up) {
|
||||
switch(_rowSel) {
|
||||
case 0:
|
||||
if((getBoardRevision() == BRD_V2_GPIO_NOALG) || (getBoardRevision() == BRD_V3_GPIO_NOALG)) // GPIO but NO Analog support
|
||||
_rowSel++; // force skip if analog input is not supported by PCB
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
_scrollChar = 0;
|
||||
_rowSel++;
|
||||
if((_rowSel == 3) && (_GPIOparams.in2Mode != CGPIOin2::Thermostat))
|
||||
_rowSel++; // force skip if not set to external thermostat
|
||||
UPPERLIMIT(_rowSel, 6);
|
||||
break;
|
||||
case 10: // confirmed save
|
||||
_enableStoringMessage();
|
||||
us = NVstore.getUserSettings();
|
||||
us.GPIO = _GPIOparams;
|
||||
us.ExtThermoTimeout = _ExtHold;
|
||||
NVstore.setUserSettings(us);
|
||||
saveNV();
|
||||
|
||||
setupGPIO();
|
||||
|
||||
_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:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
_rowSel = 10;
|
||||
break;
|
||||
case 7:
|
||||
_rowSel = 5;
|
||||
break;
|
||||
case 8:
|
||||
_rowSel = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_repeatCount = -1;
|
||||
_ScreenManager.reqUpdate();
|
||||
}
|
||||
|
||||
|
@ -400,15 +518,35 @@ CGPIOSetupScreen::_adjust(int dir)
|
|||
case 5: // outputs mode
|
||||
tVal = _GPIOparams.out2Mode;
|
||||
tVal += dir;
|
||||
WRAPLIMITS(tVal, 0, 1);
|
||||
WRAPLIMITS(tVal, 0, 2);
|
||||
_GPIOparams.out2Mode = (CGPIOout2::Modes)tVal;
|
||||
break;
|
||||
case 6: // outputs mode
|
||||
tVal = _GPIOparams.out1Mode;
|
||||
tVal += dir;
|
||||
WRAPLIMITS(tVal, 0, 2);
|
||||
WRAPLIMITS(tVal, 0, 3);
|
||||
_GPIOparams.out1Mode = (CGPIOout1::Modes)tVal;
|
||||
break;
|
||||
case 7:
|
||||
if(_GPIOparams.thresh[1] < 0) {
|
||||
_GPIOparams.thresh[1] += -dir;
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[1], -50, -1);
|
||||
}
|
||||
else {
|
||||
_GPIOparams.thresh[1] += dir;
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[1], 0, 50);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if(_GPIOparams.thresh[0] < 0) {
|
||||
_GPIOparams.thresh[0] += -dir;
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[0], -50, -1);
|
||||
}
|
||||
else {
|
||||
_GPIOparams.thresh[0] += dir;
|
||||
BOUNDSLIMIT(_GPIOparams.thresh[0], 0, 50);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ class CGPIOSetupScreen : public CPasswordScreen
|
|||
unsigned long _ExtHold;
|
||||
int _animateCount;
|
||||
int _scrollChar;
|
||||
int _repeatCount;
|
||||
void _initUI();
|
||||
public:
|
||||
CGPIOSetupScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
|
|
|
@ -1373,3 +1373,22 @@ const uint8_t PROGMEM passwordIcon[] =
|
|||
const BITMAP_INFO passwordIconInfo(11, 17, passwordIcon);
|
||||
|
||||
|
||||
//
|
||||
// Image data for thresh
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM threshIcon[] =
|
||||
{
|
||||
0xAA, 0x80, // # # # # #
|
||||
0x00, 0x00, //
|
||||
0x30, 0x00, // ##
|
||||
0x49, 0x00, // # # #
|
||||
0xFF, 0x80, // #########
|
||||
0x49, 0x00, // # # #
|
||||
0x06, 0x00, // ##
|
||||
0x00, 0x00, //
|
||||
0xAA, 0x80, // # # # # #
|
||||
};
|
||||
|
||||
const BITMAP_INFO threshIconInfo(9, 9, threshIcon);
|
||||
|
||||
|
|
|
@ -158,3 +158,4 @@ extern const BITMAP_INFO _2IconInfo;
|
|||
extern const BITMAP_INFO algIconInfo;
|
||||
|
||||
extern const BITMAP_INFO passwordIconInfo;
|
||||
extern const BITMAP_INFO threshIconInfo;
|
||||
|
|
|
@ -48,11 +48,13 @@ const char* GPIOin2Names[] = {
|
|||
const char* GPIOout1Names[] = {
|
||||
"Disabled",
|
||||
"Status",
|
||||
"User"
|
||||
"User",
|
||||
"Thresh"
|
||||
};
|
||||
const char* GPIOout2Names[] = {
|
||||
"Disabled",
|
||||
"User"
|
||||
"User",
|
||||
"Thresh"
|
||||
};
|
||||
|
||||
const char* GPIOalgNames[] = {
|
||||
|
@ -307,8 +309,105 @@ CGPIOin::simulateKey(uint8_t newKey)
|
|||
_Input2.manage((newKey & 0x02) != 0);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** GPIO out root
|
||||
** GPIO out base class
|
||||
*********************************************************************************************************/
|
||||
CGPIOoutBase::CGPIOoutBase()
|
||||
{
|
||||
_pin = 0;
|
||||
_thresh = 0;
|
||||
_userState = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOoutBase::begin(int pin)
|
||||
{
|
||||
_pin = pin;
|
||||
if(pin) {
|
||||
pinMode(pin, OUTPUT); // GPIO output pin #1
|
||||
digitalWrite(pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOoutBase::setThresh(int thresh)
|
||||
{
|
||||
_thresh = thresh;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOoutBase::setState(bool state)
|
||||
{
|
||||
_userState = state;
|
||||
}
|
||||
|
||||
bool
|
||||
CGPIOoutBase::_getUserState()
|
||||
{
|
||||
return _userState;
|
||||
};
|
||||
|
||||
void
|
||||
CGPIOoutBase::_setPinState(int state)
|
||||
{
|
||||
digitalWrite(_pin, state);
|
||||
}
|
||||
|
||||
int
|
||||
CGPIOoutBase::_getPinState()
|
||||
{
|
||||
return digitalRead(_pin);
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
CGPIOoutBase::_doUser()
|
||||
{
|
||||
// DebugPort.println("GPIOout::_doUser2()");
|
||||
if(_pin) {
|
||||
digitalWrite(_pin, _userState ? HIGH : LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CGPIOoutBase::_doThresh()
|
||||
{
|
||||
if(_thresh) {
|
||||
float tAct = getTemperatureSensor(0);
|
||||
if(digitalRead(_pin)) {
|
||||
// output is currently active
|
||||
if(_thresh > 0) { // active when OVER threshold mode
|
||||
if((tAct + 0.1) < _thresh) { // test if under threshold +0.1deg hysteresis
|
||||
digitalWrite(_pin, LOW); // deactivate output when less than threshold
|
||||
}
|
||||
}
|
||||
else { // active if UNDER threshold mode
|
||||
if(tAct > -_thresh) { // inactive if over threshold
|
||||
digitalWrite(_pin, LOW); // deactivate output when over threshold
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// output is not currently active
|
||||
if(_thresh > 0) { // active when OVER threshold mode
|
||||
if(tAct > _thresh) { // test if over threshold
|
||||
digitalWrite(_pin, HIGH); // activate output when over threshold
|
||||
}
|
||||
}
|
||||
else { // active if UNDER threshold mode
|
||||
if((tAct + 0.1) < -_thresh) { // test if under threshold +0.1deg hysteresis
|
||||
digitalWrite(_pin, HIGH); // activate output when under threshold
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** GPIO out manager
|
||||
*********************************************************************************************************/
|
||||
|
||||
|
||||
|
@ -330,6 +429,13 @@ CGPIOout::setMode(CGPIOout1::Modes mode1, CGPIOout2::Modes mode2)
|
|||
_Out2.setMode(mode2);
|
||||
};
|
||||
|
||||
void
|
||||
CGPIOout::setThresh(int op1, int op2)
|
||||
{
|
||||
_Out1.setThresh(op1);
|
||||
_Out2.setThresh(op2);
|
||||
}
|
||||
|
||||
CGPIOout1::Modes
|
||||
CGPIOout::getMode1() const
|
||||
{
|
||||
|
@ -374,26 +480,21 @@ CGPIOout::getState(int channel)
|
|||
*********************************************************************************************************/
|
||||
|
||||
|
||||
CGPIOout1::CGPIOout1()
|
||||
CGPIOout1::CGPIOout1() : CGPIOoutBase()
|
||||
{
|
||||
_Mode = Disabled;
|
||||
_pin = 0;
|
||||
_breatheDelay = 0;
|
||||
_statusState = 0;
|
||||
_statusDelay = 0;
|
||||
_userState = 0;
|
||||
_prevState = -1;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout1::begin(int pin, CGPIOout1::Modes mode)
|
||||
CGPIOout1::begin(int pin, CGPIOout1::Modes mode)
|
||||
{
|
||||
_pin = pin;
|
||||
if(pin) {
|
||||
pinMode(pin, OUTPUT); // GPIO output pin #1
|
||||
digitalWrite(pin, LOW);
|
||||
ledcSetup(0, 500, 8); // create PWM channel for GPIO1: 500Hz, 8 bits
|
||||
}
|
||||
CGPIOoutBase::begin(pin);
|
||||
|
||||
ledcSetup(0, 500, 8); // create PWM channel for GPIO1: 500Hz, 8 bits
|
||||
|
||||
setMode(mode);
|
||||
}
|
||||
|
@ -401,10 +502,11 @@ CGPIOout1::begin(int pin, CGPIOout1::Modes mode)
|
|||
void
|
||||
CGPIOout1::setMode(CGPIOout1::Modes mode)
|
||||
{
|
||||
if(mode >= Disabled && mode <= User)
|
||||
if(mode >= Disabled && mode <= Thresh)
|
||||
_Mode = mode;
|
||||
_prevState = -1;
|
||||
ledcDetachPin(_pin); // ensure PWM detached from IO line
|
||||
if(_getPin())
|
||||
ledcDetachPin(_getPin()); // ensure PWM detached from IO line
|
||||
};
|
||||
|
||||
CGPIOout1::Modes CGPIOout1::getMode() const
|
||||
|
@ -416,16 +518,18 @@ void
|
|||
CGPIOout1::manage()
|
||||
{
|
||||
switch (_Mode) {
|
||||
case Disabled: break;
|
||||
case Status: _doStatus(); break;
|
||||
case User: _doUser(); break;
|
||||
case CGPIOout1::Disabled: break;
|
||||
case CGPIOout1::Status: _doStatus(); break;
|
||||
case CGPIOout1::User: _doUser(); break;
|
||||
case CGPIOout1::Thresh: _doThresh(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout1::_doStatus()
|
||||
{
|
||||
if(_pin == 0)
|
||||
int pin = _getPin();
|
||||
if(pin == 0)
|
||||
return;
|
||||
|
||||
// DebugPort.println("GPIOout::_doStatus()");
|
||||
|
@ -466,30 +570,30 @@ CGPIOout1::_doStatus()
|
|||
_statusDelay = millis() + BREATHINTERVAL;
|
||||
switch(statusMode) {
|
||||
case 0:
|
||||
ledcDetachPin(_pin); // detach PWM from IO line
|
||||
digitalWrite(_pin, LOW);
|
||||
ledcDetachPin(pin); // detach PWM from IO line
|
||||
_setPinState(LOW);
|
||||
_ledState = 0;
|
||||
break;
|
||||
case 1:
|
||||
ledcAttachPin(_pin, 0); // attach PWM to GPIO line
|
||||
ledcAttachPin(pin, 0); // attach PWM to GPIO line
|
||||
ledcWrite(0, _statusState);
|
||||
_breatheDelay = millis() + BREATHINTERVAL;
|
||||
break;
|
||||
case 2:
|
||||
ledcDetachPin(_pin); // detach PWM from IO line
|
||||
digitalWrite(_pin, HIGH);
|
||||
ledcDetachPin(pin); // detach PWM from IO line
|
||||
_setPinState(HIGH);
|
||||
_ledState = 1;
|
||||
break;
|
||||
case 3:
|
||||
ledcAttachPin(_pin, 0); // attach PWM to GPIO line
|
||||
ledcAttachPin(pin, 0); // attach PWM to GPIO line
|
||||
_statusState = 255;
|
||||
ledcWrite(0, _statusState);
|
||||
_breatheDelay = millis() + BREATHINTERVAL;
|
||||
break;
|
||||
case 4:
|
||||
ledcDetachPin(_pin); // detach PWM from IO line
|
||||
ledcDetachPin(pin); // detach PWM from IO line
|
||||
_breatheDelay += (FLASHPERIOD - ONFLASHINTERVAL); // extended off
|
||||
digitalWrite(_pin, LOW);
|
||||
_setPinState(LOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -500,14 +604,6 @@ CGPIOout1::_doStatus()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout1::_doUser()
|
||||
{
|
||||
// DebugPort.println("GPIOout::_doUser2()");
|
||||
if(_pin) {
|
||||
digitalWrite(_pin, _userState ? HIGH : LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout1::_doStartMode() // breath up PWM
|
||||
|
@ -547,12 +643,12 @@ CGPIOout1::_doSuspendMode() // brief flash
|
|||
_statusState++;
|
||||
if(_statusState & 0x01) {
|
||||
_breatheDelay += ONFLASHINTERVAL; // brief flash on
|
||||
digitalWrite(_pin, HIGH);
|
||||
_setPinState(HIGH);
|
||||
stretch = (millis() + 250) | 1; // pulse extend for UI purposes, ensure non zero
|
||||
}
|
||||
else {
|
||||
_breatheDelay += (FLASHPERIOD - ONFLASHINTERVAL); // extended off
|
||||
digitalWrite(_pin, LOW);
|
||||
_setPinState(LOW);
|
||||
}
|
||||
}
|
||||
if(stretch) {
|
||||
|
@ -563,41 +659,34 @@ CGPIOout1::_doSuspendMode() // brief flash
|
|||
_ledState = stretch ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout1::setState(bool state)
|
||||
{
|
||||
_userState = state;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CGPIOout1::getState()
|
||||
{
|
||||
switch(_Mode) {
|
||||
case User: return _userState;
|
||||
case Status: return _ledState; // special pulse extender for suspend mode
|
||||
default: return 0;
|
||||
}
|
||||
case User:
|
||||
case Thresh:
|
||||
return _getPinState();
|
||||
case Status:
|
||||
return _ledState; // special pulse extender for suspend mode
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************************
|
||||
** GPIO2
|
||||
*********************************************************************************************************/
|
||||
CGPIOout2::CGPIOout2()
|
||||
CGPIOout2::CGPIOout2() : CGPIOoutBase()
|
||||
{
|
||||
_Mode = Disabled;
|
||||
_pin = 0;
|
||||
_userState = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout2::begin(int pin, Modes mode)
|
||||
{
|
||||
_pin = pin;
|
||||
if(pin) {
|
||||
pinMode(pin, OUTPUT); // GPIO output pin #2
|
||||
digitalWrite(pin, LOW);
|
||||
ledcSetup(1, 500, 8); // create PWM channel for GPIO2: 500Hz, 8 bits
|
||||
}
|
||||
CGPIOoutBase::begin(pin);
|
||||
|
||||
ledcSetup(1, 500, 8); // create PWM channel for GPIO2: 500Hz, 8 bits
|
||||
|
||||
setMode(mode);
|
||||
}
|
||||
|
@ -605,10 +694,11 @@ CGPIOout2::begin(int pin, Modes mode)
|
|||
void
|
||||
CGPIOout2::setMode(CGPIOout2::Modes mode)
|
||||
{
|
||||
if(mode >= Disabled && mode <= User)
|
||||
if(mode >= Disabled && mode <= Thresh)
|
||||
_Mode = mode;
|
||||
if(_pin)
|
||||
ledcDetachPin(_pin); // ensure PWM detached from IO line
|
||||
int pin = _getPin();
|
||||
if(pin)
|
||||
ledcDetachPin(pin); // ensure PWM detached from IO line
|
||||
};
|
||||
|
||||
CGPIOout2::Modes CGPIOout2::getMode() const
|
||||
|
@ -622,27 +712,21 @@ CGPIOout2::manage()
|
|||
switch (_Mode) {
|
||||
case CGPIOout2::Disabled: break;
|
||||
case CGPIOout2::User: _doUser(); break;
|
||||
case CGPIOout2::Thresh: _doThresh(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout2::_doUser()
|
||||
{
|
||||
if(_pin) {
|
||||
digitalWrite(_pin, _userState ? HIGH : LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGPIOout2::setState(bool state)
|
||||
{
|
||||
_userState = state;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
CGPIOout2::getState()
|
||||
{
|
||||
return _userState;
|
||||
switch (_Mode) {
|
||||
case CGPIOout2::User:
|
||||
case CGPIOout2::Thresh:
|
||||
return _getPinState();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// expected external analogue circuit is a 10k pot.
|
||||
|
|
|
@ -102,54 +102,66 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class CGPIOout1 {
|
||||
class CGPIOoutBase {
|
||||
int _thresh;
|
||||
bool _userState;
|
||||
int _pin;
|
||||
protected:
|
||||
void _doThresh();
|
||||
void _doUser();
|
||||
bool _getUserState();
|
||||
int _getPin() { return _pin; };
|
||||
void _setPinState(int state);
|
||||
int _getPinState();
|
||||
public:
|
||||
CGPIOoutBase();
|
||||
void setState(bool state);
|
||||
void setThresh(int val);
|
||||
void begin(int pin);
|
||||
};
|
||||
|
||||
class CGPIOout1 : public CGPIOoutBase {
|
||||
public:
|
||||
enum Modes {
|
||||
Disabled,
|
||||
Status,
|
||||
User
|
||||
User,
|
||||
Thresh
|
||||
};
|
||||
CGPIOout1();
|
||||
void begin(int pin, Modes mode);
|
||||
void setMode(Modes mode);
|
||||
void manage();
|
||||
void setState(bool state);
|
||||
uint8_t getState();
|
||||
Modes getMode() const;
|
||||
private:
|
||||
Modes _Mode;
|
||||
int _pin;
|
||||
void _doStatus();
|
||||
void _doUser();
|
||||
int _prevState;
|
||||
int _statusState;
|
||||
int _statusDelay;
|
||||
unsigned long _breatheDelay;
|
||||
bool _userState;
|
||||
uint8_t _ledState;
|
||||
void _doStartMode();
|
||||
void _doStopMode();
|
||||
void _doSuspendMode();
|
||||
};
|
||||
|
||||
class CGPIOout2 {
|
||||
class CGPIOout2 : public CGPIOoutBase {
|
||||
public:
|
||||
enum Modes {
|
||||
Disabled,
|
||||
User
|
||||
User,
|
||||
Thresh
|
||||
};
|
||||
CGPIOout2();
|
||||
void begin(int pin, Modes mode);
|
||||
void setMode(Modes mode);
|
||||
void manage();
|
||||
void setState(bool state);
|
||||
uint8_t getState();
|
||||
Modes getMode() const;
|
||||
private:
|
||||
Modes _Mode;
|
||||
int _pin;
|
||||
bool _userState;
|
||||
void _doUser();
|
||||
};
|
||||
|
||||
class CGPIOout {
|
||||
|
@ -161,6 +173,7 @@ public:
|
|||
void begin(int pin1, int pin2, CGPIOout1::Modes mode1, CGPIOout2::Modes mode2);
|
||||
void manage();
|
||||
void setState(int channel, bool state);
|
||||
void setThresh(int thr1, int thr2);
|
||||
uint8_t getState(int channel);
|
||||
CGPIOout1::Modes getMode1() const;
|
||||
CGPIOout2::Modes getMode2() const;
|
||||
|
@ -190,6 +203,7 @@ struct sGPIOparams {
|
|||
CGPIOout1::Modes out1Mode;
|
||||
CGPIOout2::Modes out2Mode;
|
||||
CGPIOalg::Modes algMode;
|
||||
int8_t thresh[2];
|
||||
};
|
||||
|
||||
struct sGPIO {
|
||||
|
|
|
@ -414,8 +414,10 @@ sUserSettings::load()
|
|||
preferences.putUChar("GPIOout1Mode", GPIO.out1Mode); // set new
|
||||
preferences.putUChar("GPIOout2Mode", GPIO.out2Mode); // set new
|
||||
}
|
||||
validatedLoad("GPIOout1Mode", tVal, 0, u8inBounds, 0, 2); GPIO.out1Mode = (CGPIOout1::Modes)tVal;
|
||||
validatedLoad("GPIOout2Mode", tVal, 0, u8inBounds, 0, 1); GPIO.out2Mode = (CGPIOout2::Modes)tVal;
|
||||
validatedLoad("GPIOout1Mode", tVal, 0, u8inBounds, 0, 3); GPIO.out1Mode = (CGPIOout1::Modes)tVal;
|
||||
validatedLoad("GPIOout2Mode", tVal, 0, u8inBounds, 0, 2); GPIO.out2Mode = (CGPIOout2::Modes)tVal;
|
||||
validatedLoad("GPIOout1Thresh", GPIO.thresh[0], 0, s8inBounds, -50, 50);
|
||||
validatedLoad("GPIOout2Thresh", GPIO.thresh[1], 0, s8inBounds, -50, 50);
|
||||
validatedLoad("GPIOalgMode", tVal, 0, u8inBounds, 0, 2); GPIO.algMode = (CGPIOalg::Modes)tVal;
|
||||
validatedLoad("MenuOnTimeout", HomeMenu.onTimeout, 0, u8inBounds, 0, 3);
|
||||
validatedLoad("MenuonStart", HomeMenu.onStart, 0, u8inBounds, 0, 3);
|
||||
|
@ -450,6 +452,8 @@ sUserSettings::save()
|
|||
preferences.putUChar("GPIOin2Mode", GPIO.in2Mode);
|
||||
preferences.putUChar("GPIOout1Mode", GPIO.out1Mode);
|
||||
preferences.putUChar("GPIOout2Mode", GPIO.out2Mode);
|
||||
preferences.putChar("GPIOout1Thresh", GPIO.thresh[0]);
|
||||
preferences.putChar("GPIOout2Thresh", GPIO.thresh[1]);
|
||||
preferences.putUChar("GPIOalgMode", GPIO.algMode);
|
||||
preferences.putUChar("MenuOnTimeout", HomeMenu.onTimeout);
|
||||
preferences.putUChar("MenuonStart", HomeMenu.onStart);
|
||||
|
|
|
@ -332,6 +332,8 @@ struct sUserSettings : public CESP32_NVStorage {
|
|||
GPIO.out1Mode = CGPIOout1::Disabled;
|
||||
GPIO.out2Mode = CGPIOout2::Disabled;
|
||||
GPIO.algMode = CGPIOalg::Disabled;
|
||||
GPIO.thresh[0] = 0;
|
||||
GPIO.thresh[1] = 0;
|
||||
FrameRate = 1000;
|
||||
cyclic.init();
|
||||
HomeMenu.init();
|
||||
|
@ -357,6 +359,8 @@ struct sUserSettings : public CESP32_NVStorage {
|
|||
GPIO.out1Mode = rhs.GPIO.out1Mode;
|
||||
GPIO.out2Mode = rhs.GPIO.out2Mode;
|
||||
GPIO.algMode = rhs.GPIO.algMode;
|
||||
GPIO.thresh[0] = rhs.GPIO.thresh[0];
|
||||
GPIO.thresh[1] = rhs.GPIO.thresh[1];
|
||||
FrameRate = rhs.FrameRate;
|
||||
cyclic = rhs.cyclic;
|
||||
HomeMenu = rhs.HomeMenu;
|
||||
|
|
Loading…
Reference in New Issue