Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement support for st7735 display #2319

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
2 changes: 2 additions & 0 deletions code/espurna/button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
#include "light.h"
#include "ws.h"
#include "mcp23s08.h"
#include "thermostat.h"

#include "button_config.h"

#include "libs/DebounceEvent.h"


BrokerBind(ButtonBroker);

// TODO: if we are using such conversion helpers across the codebase, should convert() be in internal ns?
Expand Down
20 changes: 20 additions & 0 deletions code/espurna/config/general.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,26 @@
#define THERMOSTAT_DISPLAY_SUPPORT 0
#endif

#ifndef THERMOSTAT_DISPLAY_SSD1306_SDA
#define THERMOSTAT_DISPLAY_SSD1306_SDA 1
#endif

#ifndef THERMOSTAT_DISPLAY_SSD1306_SCL
#define THERMOSTAT_DISPLAY_SSD1306_SCL 3
#endif

#ifndef THERMOSTAT_DISPLAY_ST7735_CS
#define THERMOSTAT_DISPLAY_ST7735_CS 15
#endif

#ifndef THERMOSTAT_DISPLAY_ST7735_DC
#define THERMOSTAT_DISPLAY_ST7735_DC 2
#endif

#ifndef THERMOSTAT_DISPLAY_ST7735_RST
#define THERMOSTAT_DISPLAY_ST7735_RST -1
#endif

#ifndef THERMOSTAT_DISPLAY_OFF_INTERVAL // Interval in seconds after which display will be switched off
#define THERMOSTAT_DISPLAY_OFF_INTERVAL 0 // This will prevent it from burnout
#endif // 0 - newer switch display off
Expand Down
432 changes: 432 additions & 0 deletions code/espurna/static/Roboto_Thin9pt8b.h

Large diffs are not rendered by default.

179 changes: 167 additions & 12 deletions code/espurna/thermostat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ THERMOSTAT MODULE

Copyright (C) 2017 by Dmitry Blinov <dblinov76 at gmail dot com>

https://github.com/xoseperez/espurna/pull/1603#issuecomment-469256254
*/

#include "thermostat.h"
Expand All @@ -16,6 +17,17 @@ Copyright (C) 2017 by Dmitry Blinov <dblinov76 at gmail dot com>
#include "mqtt.h"
#include "ws.h"

#if THERMOSTAT_DISPLAY_SUPPORT
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
#include <gfxfont.h>
#include <static/Roboto_Thin9pt8b.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#else
#include <SSD1306.h> // alias for `#include "SSD1306Wire.h"`
#endif
#endif

const char* NAME_THERMOSTAT_ENABLED = "thermostatEnabled";
const char* NAME_THERMOSTAT_MODE = "thermostatMode";
const char* NAME_TEMP_RANGE_MIN = "tempRangeMin";
Expand Down Expand Up @@ -488,36 +500,69 @@ void resetBurnCounters() {

#define wifi_on_width 16
#define wifi_on_height 16
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
const char wifi_on_bits[] PROGMEM = {
0x00, 0x00, 0x70, 0x00, 0x7E, 0x00, 0x7F, 0x80, 0x07, 0xC0, 0x01, 0xE0,
0x40, 0xF0, 0x78, 0x78, 0x7C, 0x38, 0x1E, 0x1C, 0x07, 0x1C, 0x03, 0x8C,
0x63, 0x8E, 0x71, 0x8E, 0x71, 0xCE, 0x00, 0x00, };
#else
const char wifi_on_bits[] PROGMEM = {
0x00, 0x00, 0x0E, 0x00, 0x7E, 0x00, 0xFE, 0x01, 0xE0, 0x03, 0x80, 0x07,
0x02, 0x0F, 0x1E, 0x1E, 0x3E, 0x1C, 0x78, 0x38, 0xE0, 0x38, 0xC0, 0x31,
0xC6, 0x71, 0x8E, 0x71, 0x8E, 0x73, 0x00, 0x00, };
#endif

#define mqtt_width 16
#define mqtt_height 16
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
const char mqtt_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x1C, 0x57, 0xFE, 0x57, 0xFE,
0x00, 0x1C, 0x08, 0x18, 0x18, 0x10, 0x38, 0x00, 0x7F, 0xEA, 0x7F, 0xEA,
0x38, 0x00, 0x18, 0x00, 0x08, 0x00, 0x00, 0x00, };
#else
const char mqtt_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x38, 0xEA, 0x7F, 0xEA, 0x7F,
0x00, 0x38, 0x10, 0x18, 0x18, 0x08, 0x1C, 0x00, 0xFE, 0x57, 0xFE, 0x57,
0x1C, 0x00, 0x18, 0x00, 0x10, 0x00, 0x00, 0x00, };
#endif

#define remote_temp_width 16
#define remote_temp_height 16
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
const char remote_temp_bits[] PROGMEM = {
0x00, 0x00, 0x07, 0x18, 0x08, 0xA4, 0x08, 0xA4, 0x09, 0x98, 0x0A, 0x80,
0x0A, 0x80, 0x0B, 0x80, 0x0A, 0x80, 0x0A, 0x80, 0x0B, 0x80, 0x0A, 0x80,
0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00
};
#else
const char remote_temp_bits[] PROGMEM = {
0x00, 0x00, 0xE0, 0x18, 0x10, 0x25, 0x10, 0x25, 0x90, 0x19, 0x50, 0x01,
0x50, 0x01, 0xD0, 0x01, 0x50, 0x01, 0x50, 0x01, 0xD0, 0x01, 0x50, 0x01,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00, 0x00, };
#endif

#define server_width 16
#define server_height 16
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
const char server_bits[] PROGMEM = {
0x00, 0x00, 0x1F, 0xF8, 0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C,
0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE,
0x78, 0x1E, 0x7F, 0xFE, 0x3F, 0xFC, 0x00, 0x00, };
#else
const char server_bits[] PROGMEM = {
0x00, 0x00, 0xF8, 0x1F, 0xFC, 0x3F, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30,
0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0xF8, 0x1F, 0xFC, 0x3F, 0xFE, 0x7F,
0x1E, 0x78, 0xFE, 0x7F, 0xFC, 0x3F, 0x00, 0x00, };
#endif

#define LOCAL_TEMP_UPDATE_INTERVAL 60000
#define LOCAL_HUM_UPDATE_INTERVAL 61000

SSD1306 display(0x3c, 1, 3);
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
Adafruit_ST7735 display = Adafruit_ST7735(THERMOSTAT_DISPLAY_ST7735_CS, THERMOSTAT_DISPLAY_ST7735_DC, THERMOSTAT_DISPLAY_ST7735_RST);
#else
SSD1306 display(0x3c, THERMOSTAT_DISPLAY_SSD1306_SDA, THERMOSTAT_DISPLAY_SSD1306_SCL);
#endif

unsigned long _local_temp_last_update = 0xFFFF;
unsigned long _local_hum_last_update = 0xFFFF;
Expand All @@ -532,11 +577,22 @@ bool _display_need_refresh = true;
bool _temp_range_need_update = true;

//------------------------------------------------------------------------------
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
dpeddi marked this conversation as resolved.
Show resolved Hide resolved

void drawIco(int16_t x, int16_t y, const char *ico, bool on = true) {
display.drawBitmap(x, y, (const uint8_t*) ico, 16, 16, ((on == true) ? ST7735_WHITE : ST77XX_BLACK));
_display_need_refresh = true;
}

#else

void drawIco(int16_t x, int16_t y, const char *ico, bool on = true) {
display.drawIco16x16(x, y, ico, !on);
display.drawIco16x16(x, y, ico, !on); //FIXME
_display_need_refresh = true;
}

#endif

//------------------------------------------------------------------------------
void display_wifi_status(bool on) {
_display_wifi_status = on;
Expand All @@ -562,6 +618,22 @@ void display_remote_temp_status(bool on) {
}

//------------------------------------------------------------------------------
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT

void display_temp_range() {
_temp_range.need_display_update = false;
display.fillRect(68, 0, ST7735_TFTHEIGHT_160 - 60, 16, ST7735_BLACK);
display.setTextColor(ST77XX_WHITE);
display.setTextWrap(true);
display.setCursor(90, 0 + 13);
display.setFont(&Roboto_Thin9pt8b);
String temp_range = String(_temp_range.min) + "\xB0- " + String(_temp_range.max) + "\xB0";
display.print(temp_range);
_display_need_refresh = true;
}

#else

void display_temp_range() {
_temp_range.need_display_update = false;
display.setColor(BLACK);
Expand All @@ -570,60 +642,119 @@ void display_temp_range() {
display.setTextAlignment(TEXT_ALIGN_RIGHT);
display.setFont(ArialMT_Plain_16);
String temp_range = String(_temp_range.min) + "°- " + String(_temp_range.max) + "°";
display.drawString(128, 0, temp_range);
display.drawString(128 /*x*/, 0/*y*/, temp_range);
_display_need_refresh = true;
}

#endif

//------------------------------------------------------------------------------
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT

void display_remote_temp() {
_remote_temp.need_display_update = false;
display.fillRect(0, 16, ST7735_TFTHEIGHT_160, 16, ST77XX_BLACK);

display.setTextColor(ST77XX_WHITE);
display.setTextWrap(true);
display.setFont(&Roboto_Thin9pt8b);

display.setCursor(0, 16 + 13);
display.print(F("Remote t"));

display.setCursor(75, 16 + 13);
String temp_range_vol = String("= ") + (_display_remote_temp_status ? String(_remote_temp.temp, 1) : String("?")) + "\xB0";
display.print(temp_range_vol);
_display_need_refresh = true;
}

#else

void display_remote_temp() {
_remote_temp.need_display_update = false;
display.setColor(BLACK);
display.fillRect(0, 16, 128, 16);
display.setColor(WHITE);
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_LEFT);
String temp_range_title = String("Remote t");
display.drawString(0, 16, temp_range_title);
display.drawString(0, 16, F("Remote t"));

String temp_range_vol = String("= ") + (_display_remote_temp_status ? String(_remote_temp.temp, 1) : String("?")) + "°";
display.drawString(75, 16, temp_range_vol);

_display_need_refresh = true;
}
#endif

//------------------------------------------------------------------------------
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT

void display_local_temp() {
display.fillRect(0, 32, ST7735_TFTHEIGHT_160, 16, ST77XX_BLACK);

display.setTextColor(ST77XX_WHITE);
display.setTextWrap(true);
display.setFont(&Roboto_Thin9pt8b);

display.setCursor(0, 32 + 13);
display.print(F("Local t"));

display.setCursor(75, 32 + 13);
String local_temp_vol = String("= ") + (getLocalTemperature() != DBL_MIN ? String(getLocalTemperature(), 1) : String("?")) + "\xB0";
display.print(local_temp_vol);
_display_need_refresh = true;
}

#else

void display_local_temp() {
display.setColor(BLACK);
display.fillRect(0, 32, 128, 16);
display.setColor(WHITE);
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_LEFT);

String local_temp_title = String("Local t");
display.drawString(0, 32, local_temp_title);
display.drawString(0, 32, F("Local t"));

String local_temp_vol = String("= ") + (getLocalTemperature() != DBL_MIN ? String(getLocalTemperature(), 1) : String("?")) + "°";
display.drawString(75, 32, local_temp_vol);

_display_need_refresh = true;
}
#endif

//------------------------------------------------------------------------------
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT

void display_local_humidity() {
display.fillRect(0, 48, ST7735_TFTHEIGHT_160, 16, ST77XX_BLACK);

display.setTextColor(ST77XX_WHITE);
display.setTextWrap(true);

display.setCursor(0, 48 + 13);
display.print(F("Local h "));

display.setCursor(75, 48 + 13);
String local_hum_vol = String("= ") + (getLocalHumidity() != DBL_MIN ? String(getLocalHumidity(), 0) : String("?")) + "%";
display.print(local_hum_vol);
_display_need_refresh = true;
}

#else

void display_local_humidity() {
display.setColor(BLACK);
display.fillRect(0, 48, 128, 16);
display.setColor(WHITE);
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_LEFT);

String local_hum_title = String("Local h ");
display.drawString(0, 48, local_hum_title);
display.drawString(0, 48, F("Local h "));

String local_hum_vol = String("= ") + (getLocalHumidity() != DBL_MIN ? String(getLocalHumidity(), 0) : String("?")) + "%";
display.drawString(75, 48, local_hum_vol);

_display_need_refresh = true;
}
#endif

//------------------------------------------------------------------------------
void displayOn() {
Expand All @@ -644,6 +775,21 @@ void displayOn() {
//------------------------------------------------------------------------------
// Setup
//------------------------------------------------------------------------------
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT

void displaySetup() {
display.initR(INITR_BLACKTAB); // Initialize ST7735R screen
display.setRotation(1);
display.fillScreen(ST77XX_BLACK);
display.cp437(true);

displayOn();

espurnaRegisterLoop(displayLoop);
}

#else

void displaySetup() {
display.init();
display.flipScreenVertically();
Expand All @@ -652,14 +798,19 @@ void displaySetup() {

espurnaRegisterLoop(displayLoop);
}
#endif

//------------------------------------------------------------------------------
void displayLoop() {
if (THERMOSTAT_DISPLAY_OFF_INTERVAL > 0 && millis() - _thermostat_display_on_time > _thermostat_display_off_interval) {
if (_thermostat_display_is_on) {
DEBUG_MSG_P(PSTR("[THERMOSTAT] Display Off by timeout\n"));
_thermostat_display_is_on = false;
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
//FIXME
#else
display.resetDisplay();
#endif
}
return;
}
Expand Down Expand Up @@ -731,7 +882,11 @@ void displayLoop() {
//------------------------------------------------------------------------------
if (_display_need_refresh) {
yield();
#if THERMOSTAT_DISPLAY_ST7735_SUPPORT
//FIXME
#else
display.display();
#endif
_display_need_refresh = false;
}
}
Expand Down
14 changes: 10 additions & 4 deletions code/espurna/thermostat.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ Copyright (C) 2017 by Dmitry Blinov <dblinov76 at gmail dot com>

#include "espurna.h"

#if THERMOSTAT_SUPPORT

#include <ArduinoJson.h>
#include <float.h>

#if THERMOSTAT_DISPLAY_SUPPORT
#include <SSD1306.h> // alias for `#include "SSD1306Wire.h"`
#endif

#define ASK_TEMP_RANGE_INTERVAL_INITIAL 15000 // ask initially once per every 15 seconds
#define ASK_TEMP_RANGE_INTERVAL_REGULAR 60000 // ask every minute to be sure
#define MILLIS_IN_SEC 1000
Expand Down Expand Up @@ -64,3 +62,11 @@ void thermostatModeCooler(bool cooler);
bool thermostatModeCooler();

void thermostatSetup();

#if THERMOSTAT_DISPLAY_SUPPORT
void displayOn();
void displaySetup();
void displayLoop();
#endif

#endif
Loading