Added Screen2 - simple presentation with ability to toggle thermostat and change set point (keypad)

This commit is contained in:
rljonesau 2018-11-23 21:34:37 +11:00
parent fc23538ceb
commit efe8afeff3
13 changed files with 385 additions and 53 deletions

View File

@ -44,7 +44,31 @@ size_t C128x64_OLED::write(uint8_t c)
#endif
}
void C128x64_OLED::getTextExtents(const char* str, uint16_t& w, uint16_t& h)
{
w = 0;
h = 0;
if(m_pFontInfo) {
while(*str) {
unsigned char c = (unsigned char)*str++;
if(c >= m_pFontInfo->StartChar && c <= m_pFontInfo->EndChar) {
const FONT_CHAR_INFO* pCharInfo = &m_pFontInfo->pCharInfo[c - m_pFontInfo->StartChar];
// and extract info from flash (program) storage
int xsize = pgm_read_byte(&pCharInfo->Width);
int ysize = pgm_read_byte(&pCharInfo->Height);
if(ysize > h)
h = ysize;
w += xsize;
}
if(*str) // check if next character exists, if so include space size
w += m_pFontInfo->SpaceWidth;
}
}
else {
int16_t x1, y1;
Adafruit_SH1106::getTextBounds(str, 0, 0, &x1, &y1, &w, &h);
}
}
void
C128x64_OLED::drawDotFactoryChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, const FONT_INFO* pFontDescriptor, int& xsize, int& ysize)

View File

@ -13,6 +13,8 @@ public:
cursor_x += x;
cursor_y += y;
};
void getTextExtents(const char* str, uint16_t& w, uint16_t& h);
void printRightJustify(const char* str, int yPos, int RHS=127);
size_t write(uint8_t c);

View File

@ -55,4 +55,4 @@
#define TEMPERATURE_INTERVAL 1000
#define SUPPORT_OEM_CONTROLLER 0
#define SUPPORT_OEM_CONTROLLER 1

View File

@ -80,6 +80,7 @@
#include <OneWire.h>
#include <DallasTemperature.h>
#include "keypad.h"
#include "helpers.h"
#define FAILEDSSID "BTCESP32"
@ -112,6 +113,7 @@ static HardwareSerial& BlueWireSerial(Serial1);
void initBlueWireSerial();
bool validateFrame(const CProtocol& frame, const char* name);
void checkDisplayUpdate();
// DS18B20 temperature sensor support
OneWire ds(DS18B20_Pin); // on pin 5 (a 4.7K resistor is necessary)
@ -139,7 +141,7 @@ const CProtocol* pRxFrame = NULL;
const CProtocol* pTxFrame = NULL;
unsigned long moderator;
bool bUpdateDisplay = false;
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Bluetooth instantiation
@ -409,13 +411,6 @@ void loop()
moderator = 50;
// only update OLED when not processing blue wire
tDelta = timenow - lastAnimationTime;
if(tDelta >= 100) {
lastAnimationTime += 100;
animateOLED();
}
#if RX_LED == 1
digitalWrite(LED_Pin, LOW);
#endif
@ -448,9 +443,11 @@ void loop()
//
}
else {
checkDisplayUpdate();
break; // only break if we fail all Idle state tests
}
#else
checkDisplayUpdate();
break;
#endif
@ -638,15 +635,14 @@ void loop()
fFilteredTemperature = fFilteredTemperature * fAlpha + (1-fAlpha) * fTemperature;
DefaultBTCParams.setTemperature_Actual((unsigned char)(fFilteredTemperature + 0.5)); // update [BTC] frame to send
TempSensor.requestTemperatures(); // prep sensor for future reading
updateOLED(*pTxFrame, *pRxFrame);
reqDisplayUpdate();
}
CommState.set(CommStates::Idle);
break;
} // switch(CommState)
BlueWireData.reset(); // ensure we flush any used data
} // loop
void DebugReportFrame(const char* hdr, const CProtocol& Frame, const char* ftr)
@ -780,7 +776,9 @@ bool validateFrame(const CProtocol& frame, const char* name)
int getRunState()
{
return pRxFrame->getRunState();
if(pRxFrame)
return pRxFrame->getRunState();
return 0;
}
void requestOn()
@ -810,3 +808,72 @@ void ToggleOnOff()
}
void reqTempChange(int val)
{
unsigned char curTemp = getSetTemp();
curTemp += val;
unsigned char max = DefaultBTCParams.getTemperature_Max();
unsigned char min = DefaultBTCParams.getTemperature_Min();
if(curTemp >= max)
curTemp = max;
if(curTemp <= min)
curTemp = min;
pNVStorage->setTemperature(curTemp);
reqDisplayUpdate();
}
int getSetTemp()
{
// pTxFrame->getTemperature_Desired(); // sluggish - delays until new packet goes out!
return pNVStorage->getTemperature();
}
float getFixedHz()
{
if(pRxFrame) {
return float(pRxFrame->getPump_Fixed()) / 10.f;
}
return 0.0;
}
void reqThermoToggle()
{
setThermostatMode(getThermostatMode() ? 0 : 1);
}
void setThermostatMode(unsigned char val)
{
pNVStorage->setThermostatMode(val);
}
bool getThermostatMode()
{
return pNVStorage->getThermostatMode() != 0;
}
void reqDisplayUpdate()
{
bUpdateDisplay = true;
}
void checkDisplayUpdate()
{
// only update OLED when not processing blue wire
if(bUpdateDisplay) {
if(pTxFrame && pRxFrame) {
updateOLED(*pTxFrame, *pRxFrame);
bUpdateDisplay = false;
}
}
unsigned long tDelta = millis() - lastAnimationTime;
if(tDelta >= 100) {
lastAnimationTime += 100;
animateOLED();
}
}

View File

@ -1,20 +1,19 @@
#include "128x64OLED.h"
#include "MiniFont.h"
#include "display.h"
#include "tahoma16.h"
#include "OLEDconsts.h"
#include "BluetoothAbstract.h"
#include "Screen1.h"
#include "BTCWifi.h"
#include "KeyPad.h"
#include "helpers.h"
#include "Protocol.h"
bool animatePump = false;
bool animateRPM = false;
bool animateGlow = false;
extern float fFilteredTemperature;
void showThermometer(C128x64_OLED& display, float desired, float actual);
void showBodyThermometer(C128x64_OLED& display, int actual);
void showGlowPlug(C128x64_OLED& display, int power);
@ -22,11 +21,6 @@ void showFan(C128x64_OLED& display, int RPM);
void showFuel(C128x64_OLED& display, float rate);
void showRunState(C128x64_OLED& display, int state, int errstate);
extern void ToggleOnOff();
extern void requestOn();
extern void requestOff();
extern int getRunState();
#define MAXIFONT tahoma_16ptFontInfo
#define MINIFONT miniFontInfo
@ -95,14 +89,6 @@ void showScreen1(C128x64_OLED& display, const CProtocol& CtlFrame, const CProtoc
showRunState(display, runstate, errstate);
#ifdef DEMO_LARGEFONT
display.fillRect(20,20, 80,16, BLACK);
display.setCursor(20,20);
display.setFontInfo(&MAXIFONT); // Dot Factory Font
display.print("25.6`");
display.setFontInfo(NULL); // standard 5x7 font
#endif
}
@ -332,6 +318,12 @@ void keyhandlerScreen1(uint8_t event)
static int repeatCount = -1;
if(event & keyPressed) {
repeatCount = 0; // unlock tracking of repeat events
if(event & key_Left) {
prevScreen();
}
if(event & key_Right) {
nextScreen();
}
}
// require hold to turn ON or OFF
if(event & keyRepeat) {
@ -358,4 +350,3 @@ void keyhandlerScreen1(uint8_t event)
}
}

View File

@ -0,0 +1,187 @@
#include "128x64OLED.h"
#include "display.h"
#include "MiniFont.h"
#include "tahoma16.h"
#include "OLEDconsts.h"
#include "BluetoothAbstract.h"
#include "Screen2.h"
#include "BTCWifi.h"
#include "KeyPad.h"
#include "helpers.h"
#include "Protocol.h"
#define MAXIFONT tahoma_16ptFontInfo
#define MINIFONT miniFontInfo
unsigned long showSetTemp = 0;
unsigned long showMode = 0;
unsigned char nModeSel;
void showScreen2(C128x64_OLED& display, const CProtocol& CtlFrame, const CProtocol& HtrFrame)
{
char msg[20];
sprintf(msg, "%.1f`", fFilteredTemperature);
display.setFontInfo(&MAXIFONT); // Dot Factory Font
uint16_t width, height;
display.getTextExtents(msg, width, height);
int xPos = 64 - (width/2);
display.fillRect(xPos, 25, width, height, BLACK);
display.setCursor(xPos, 25);
display.print(msg);
display.setFontInfo(NULL); // standard 5x7 font
if(showMode) {
if(millis() < showMode) {
strcpy(msg, "Fixed Hz");
display.getTextExtents(msg, width, height);
int yPos = 63 - height - 2;
display.setCursor(2, yPos);
display.print(msg);
if(nModeSel == 0) {
display.drawRoundRect(0, yPos-2, width+4, height+4, 3, WHITE);
}
strcpy(msg, "Thermostat");
display.getTextExtents(msg, width, height);
int xPos = 127 - width - 2;
display.setCursor(xPos, yPos);
display.print(msg);
if(nModeSel == 1) {
display.drawRoundRect(xPos - 2, yPos-2, width+4, height+4, 3, WHITE);
}
}
else {
showMode = 0;
setThermostatMode(nModeSel);
}
}
else if(millis() < showSetTemp) {
if(getThermostatMode()) {
sprintf(msg, "Setpoint = %d`C", getSetTemp());
}
else {
sprintf(msg, "Setpoint = %.1fHz", getFixedHz());
}
display.getTextExtents(msg, width, height);
xPos = 64 - (width/2); // centre across
int yPos = 63 - height; // at bottom of screen
display.setCursor(xPos, yPos);
display.print(msg);
}
else {
int runState = getRunState();
if(runState) {
const char* pMsg;
if(runState < 5) {
pMsg = "Starting";
}
else if(runState == 5) {
pMsg = "Running";
}
else {
pMsg = "Shutting down";
}
display.getTextExtents(pMsg, width, height);
int xPos = 64 - (width/2); // centre across
int yPos = 63 - height; // at bottom of screen
display.setCursor(xPos, yPos);
display.print(pMsg);
}
}
}
void animateScreen2(C128x64_OLED& display)
{
display.display();
}
void keyhandlerScreen2(uint8_t event)
{
static int repeatCount = -1;
if(event & keyPressed) {
repeatCount = 0; // unlock tracking of repeat events
// press LEFT to select previous screen, or Fixed Hz mode when in mode select
if(event & key_Left) {
if(!showMode)
prevScreen();
else {
showMode = millis() + 5000;
nModeSel = 0;
reqDisplayUpdate();
}
}
// press RIGHT to selecxt next screen, or Thermostat mode when in mode select
if(event & key_Right) {
if(!showMode)
nextScreen();
else {
showMode = millis() + 5000;
nModeSel = 1;
reqDisplayUpdate();
}
}
// press UP & DOWN to toggle thermostat / fixed Hz mode
uint8_t doubleKey = key_Down | key_Up;
if((event & doubleKey) == doubleKey) {
reqThermoToggle();
showSetTemp = millis() + 2000;
}
// press CENTRE to accept new mode, and/or show current setting
if(event & key_Centre) {
if(showMode) {
setThermostatMode(nModeSel);
}
showMode = 0;
showSetTemp = millis() + 2000;
}
}
// use repeat function for key hold detection
if(event & keyRepeat) {
if(repeatCount >= 0) {
repeatCount++;
// hold DOWN to enter thermostat / fixed mode selection
if(event & key_Down) {
if(repeatCount > 2) {
repeatCount = -1; // prevent double handling
showMode = millis() + 5000;
nModeSel = getThermostatMode();
}
}
// hold CENTRE to turn ON or OFF
if(event & key_Centre) {
if(getRunState()) {
// running, request OFF
if(repeatCount > 5) {
repeatCount = -1; // prevent double handling
requestOff();
}
}
else {
// standby, request ON
if(repeatCount > 3) {
repeatCount = -1;
requestOn();
}
}
}
}
}
if(event & keyReleased) {
if(!showMode) {
// release DOWN key to reduce set demand, provided we are not in mode select
if(event & key_Down) {
reqTempChange(-1);
showSetTemp = millis() + 2000;
}
// release UP key to increase set demand, provided we are not in mode select
if(event & key_Up) {
reqTempChange(+1);
showSetTemp = millis() + 2000;
}
}
repeatCount = -1;
}
}

View File

@ -0,0 +1,9 @@
#include "stdint.h"
class C128x64_OLED;
class CProtocol;
void showScreen2(C128x64_OLED& display, const CProtocol& CtlFrame, const CProtocol& HtrFrame);
void animateScreen2(C128x64_OLED& display);
void keyhandlerScreen2(uint8_t event);

View File

@ -10,7 +10,9 @@
#include "BTCWifi.h"
#include "BluetoothAbstract.h"
#include "Screen1.h"
#include "Screen2.h"
#include "KeyPad.h"
#include "helpers.h"
#define MAXIFONT tahoma_16ptFontInfo
#define MINIFONT miniFontInfo
@ -27,6 +29,10 @@
void showBTicon(C128x64_OLED& display);
void showWifiIcon(C128x64_OLED& display);
void showBatteryIcon(C128x64_OLED& display, float voltage);
void switchScreen();
static int currentScreen = 0;
const int maxScreens = 2;
//
// **** NOTE: There are two very lame libaries conspiring to make life difficult ****
@ -40,29 +46,12 @@ void showBatteryIcon(C128x64_OLED& display, float voltage);
// 128 x 64 OLED support
SPIClass SPI; // default constructor opens HSPI on standard pins : MOSI=13,CLK=14,MISO=12(unused)
//Adafruit_SH1106 display(OLED_DC_pin, -1, OLED_CS_pin);
C128x64_OLED display(OLED_DC_pin, -1, OLED_CS_pin);
/*bool animatePump = false;
bool animateRPM = false;
bool animateGlow = false;
*/
/*extern float fFilteredTemperature;
extern CBluetoothAbstract& getBluetoothClient();
void showThermometer(float desired, float actual);
void showBodyThermometer(int actual);
void showBTicon();
void showWifiIcon();
void showBatteryIcon(float voltage);
void showGlowPlug(int power);
void showFan(int RPM);
void showFuel(float rate);
void showRunState(int state, int errstate);
void printRightJustify(const char* str, int yPos, int RHS=128);
*/
void initOLED()
{
currentScreen = 0;
SPI.setFrequency(8000000);
// SH1106_SWITCHCAPVCC = generate display voltage from 3.3V internally
display.begin(SH1106_SWITCHCAPVCC, 0, false);
@ -77,7 +66,14 @@ void initOLED()
void animateOLED()
{
animateScreen1(display);
switch(currentScreen) {
case 0:
animateScreen1(display);
break;
case 1:
animateScreen2(display);
break;
}
}
@ -102,7 +98,14 @@ void updateOLED(const CProtocol& CtlFrame, const CProtocol& HtrFrame)
float voltage = HtrFrame.getVoltage_Supply() * 0.1f;
showBatteryIcon(display, voltage);
showScreen1(display, CtlFrame, HtrFrame);
switch(currentScreen) {
case 0:
showScreen1(display, CtlFrame, HtrFrame);
break;
case 1:
showScreen2(display, CtlFrame, HtrFrame);
break;
}
}
void showBTicon(C128x64_OLED& display)
@ -139,3 +142,34 @@ void showBatteryIcon(C128x64_OLED& display, float voltage)
if(Capacity > 11) Capacity = 11;
display.fillRect(X_BATT_ICON+2 + Capacity, Y_BATT_ICON+2, W_BATT_ICON-4-Capacity, 6, BLACK);
}
void nextScreen()
{
currentScreen++;
if(currentScreen >= maxScreens) {
currentScreen = 0;
}
switchScreen();
}
void prevScreen()
{
currentScreen--;
if(currentScreen < 0) {
currentScreen = maxScreens-1;
}
switchScreen();
}
void switchScreen()
{
switch(currentScreen) {
case 0:
KeyPad.setCallback(keyhandlerScreen1);
break;
case 1:
KeyPad.setCallback(keyhandlerScreen2);
break;
}
reqDisplayUpdate();
}

View File

@ -9,4 +9,8 @@ void initOLED();
void updateOLED(const CProtocol& CtlFrame, const CProtocol& HtrFrame);
void animateOLED();
void nextScreen();
void prevScreen();
#endif // __DISPLAY_H__

View File

@ -0,0 +1,14 @@
extern void ToggleOnOff();
extern void requestOn();
extern void requestOff();
extern int getRunState();
extern void reqTempChange(int val);
extern void tempDec();
extern int getSetTemp();
extern void reqDisplayUpdate();
extern void reqThermoToggle();
extern void setThermostatMode(unsigned char);
extern bool getThermostatMode();
extern float getFixedHz();
extern float fFilteredTemperature;

View File

@ -142,7 +142,7 @@ CKeyPad::update()
if(Press) {
if(_keyCallback != NULL)
_keyCallback(keyPressed | Press);
_keyCallback(keyPressed | Press | newKey);
return keyPressed | Press;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB