Merge pull request #401 from gh-fx2/ssd1306
simple SSD1306 (i2c) + Nokia5110 support for esp8266 added
|
@ -11,6 +11,14 @@
|
|||
#include "app.h"
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#ifdef ENA_NOKIA
|
||||
#include <U8g2lib.h>
|
||||
#endif
|
||||
#ifdef ENA_SSD1306
|
||||
#include <Wire.h>
|
||||
#include <SSD1306Wire.h>
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
app::app() {
|
||||
|
@ -27,10 +35,261 @@ app::app() {
|
|||
mShouldReboot = false;
|
||||
}
|
||||
|
||||
#ifdef ENA_SSD1306
|
||||
/* esp8266 : SCL = 5, SDA = 4 */
|
||||
/* ewsp32 : SCL = 22, SDA = 21 */
|
||||
SSD1306Wire display(0x3c, SDA, SCL);
|
||||
|
||||
static unsigned char bmp_arrow[] PROGMEM = {
|
||||
B00000000, B00011100, B00011100, B00001110, B00001110, B11111110, B01111111,
|
||||
B01110000, B01110000, B00110000, B00111000, B00011000, B01111111, B00111111,
|
||||
B00011110, B00001110, B00000110, B00000000, B00000000, B00000000, B00000000 } ;
|
||||
|
||||
void DataScreen( app* mApp, time_t ts )
|
||||
{
|
||||
static int extra = 0;
|
||||
String timeStr = mApp->getDateTimeStr(ts).substring(2,22);
|
||||
IPAddress ip = WiFi.localIP();
|
||||
float totalYield = 0.000, totalYieldToday = 0.000, totalActual = 0.0;
|
||||
char fmtText[32];
|
||||
int ucnt=0;
|
||||
|
||||
for (uint8_t id = 0; id < mApp->mSys->getNumInverters(); id++)
|
||||
{
|
||||
Inverter<> *iv = mApp->mSys->getInverterByPos(id);
|
||||
if (NULL != iv)
|
||||
{
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos;
|
||||
uint8_t list[] = {FLD_PAC, FLD_YT, FLD_YD};
|
||||
|
||||
if ( !iv->isProducing(ts,rec) )
|
||||
continue;
|
||||
|
||||
ucnt++;
|
||||
|
||||
for (uint8_t fld = 0; fld < 3; fld++)
|
||||
{
|
||||
pos = iv->getPosByChFld(CH0, list[fld],rec);
|
||||
|
||||
if(fld == 1){
|
||||
totalYield += iv->getValue(pos,rec);
|
||||
}
|
||||
|
||||
if(fld == 2){
|
||||
totalYieldToday += iv->getValue(pos,rec);
|
||||
}
|
||||
|
||||
if(fld == 0){
|
||||
totalActual += iv->getValue(pos,rec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
display.clear();
|
||||
|
||||
if(ucnt)
|
||||
{
|
||||
display.setBrightness(63);
|
||||
display.drawXbm(10,5,8,17,bmp_arrow);
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
sprintf(fmtText,"%3.0f",totalActual);
|
||||
display.drawString(25,0,String(fmtText)+F(" W"));
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
sprintf(fmtText,"%4.0f",totalYieldToday);
|
||||
display.drawString(5,22,F("today ")+String(fmtText)+F(" Wh"));
|
||||
sprintf(fmtText,"%.1f",totalYield);
|
||||
display.drawString(5,35,F("total ")+String(fmtText)+F(" kWh"));
|
||||
display.drawLine(2,23,123,23);
|
||||
}
|
||||
else
|
||||
{
|
||||
static int rx=50;
|
||||
static char up=1;
|
||||
if(up)
|
||||
{
|
||||
rx+=2;
|
||||
if(rx>=70)
|
||||
up=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rx-=2;
|
||||
if(rx<=50)
|
||||
up=1;
|
||||
}
|
||||
display.setBrightness(1);
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
display.drawString(rx,10,F("off"));
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
}
|
||||
if ( !(extra%20) )
|
||||
{
|
||||
display.drawString(5,49,ip.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
int w=display.getStringWidth(timeStr.c_str(),timeStr.length(),0);
|
||||
if ( w>127 )
|
||||
{
|
||||
String tt=timeStr.substring(9,17);
|
||||
w=display.getStringWidth(tt.c_str(),tt.length(),0);
|
||||
display.drawString(127-w,49,tt);
|
||||
}
|
||||
else
|
||||
display.drawString(0,49,timeStr);
|
||||
}
|
||||
|
||||
display.display();
|
||||
extra++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENA_NOKIA
|
||||
|
||||
U8G2_PCD8544_84X48_1_4W_HW_SPI u8g2(U8G2_R0,5,4,16);
|
||||
|
||||
void ShowInfoText( const char *txt )
|
||||
{
|
||||
/* u8g2_font_open_iconic_embedded_2x_t 'D' + 'G' + 'J' */
|
||||
u8g2.clear();
|
||||
u8g2.firstPage();
|
||||
do{
|
||||
const char *e;
|
||||
const char *p = txt;
|
||||
int y=10;
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
while(1)
|
||||
{
|
||||
for(e=p+1; (*e && (*e != '\n')); e++);
|
||||
size_t len=e-p;
|
||||
u8g2.setCursor(2,y);
|
||||
String res=((String)p).substring(0,len);
|
||||
u8g2.print(res);
|
||||
if ( !*e )
|
||||
break;
|
||||
p=e+1;
|
||||
y+=12;
|
||||
}
|
||||
u8g2.sendBuffer();
|
||||
} while( u8g2.nextPage() );
|
||||
}
|
||||
|
||||
static unsigned char bmp_arrow[] U8X8_PROGMEM = {
|
||||
B00000000, B00011100, B00011100, B00001110, B00001110, B11111110, B01111111,
|
||||
B01110000, B01110000, B00110000, B00111000, B00011000, B01111111, B00111111,
|
||||
B00011110, B00001110, B00000110, B00000000, B00000000, B00000000, B00000000 } ;
|
||||
|
||||
void DataScreen( app* mApp, time_t ts )
|
||||
{
|
||||
static int extra = 0;
|
||||
String timeStr = mApp->getDateTimeStr(ts).substring(2,22);
|
||||
IPAddress ip = WiFi.localIP();
|
||||
float totalYield = 0.000, totalYieldToday = 0.000, totalActual = 0.0;
|
||||
char fmtText[32];
|
||||
int ucnt=0;
|
||||
|
||||
for (uint8_t id = 0; id < mApp->mSys->getNumInverters(); id++)
|
||||
{
|
||||
Inverter<> *iv = mApp->mSys->getInverterByPos(id);
|
||||
if (NULL != iv)
|
||||
{
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos;
|
||||
uint8_t list[] = {FLD_PAC, FLD_YT, FLD_YD};
|
||||
|
||||
if ( !iv->isProducing(ts,rec) )
|
||||
continue;
|
||||
|
||||
ucnt++;
|
||||
|
||||
for (uint8_t fld = 0; fld < 3; fld++)
|
||||
{
|
||||
pos = iv->getPosByChFld(CH0, list[fld],rec);
|
||||
|
||||
if(fld == 1){
|
||||
totalYield += iv->getValue(pos,rec);
|
||||
}
|
||||
|
||||
if(fld == 2){
|
||||
totalYieldToday += iv->getValue(pos,rec);
|
||||
}
|
||||
|
||||
if(fld == 0){
|
||||
totalActual += iv->getValue(pos,rec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u8g2_font_open_iconic_embedded_2x_t 'D' + 'G' + 'J' */
|
||||
u8g2.clear();
|
||||
u8g2.firstPage();
|
||||
do{
|
||||
if(ucnt)
|
||||
{
|
||||
u8g2.drawXBMP(10,0,8,17,bmp_arrow);
|
||||
u8g2.setFont(u8g2_font_logisoso16_tr);
|
||||
u8g2.setCursor(25,16);
|
||||
sprintf(fmtText,"%3.0f",totalActual);
|
||||
u8g2.print(String(fmtText)+F(" W"));
|
||||
u8g2.drawHLine(2,20,78);
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
u8g2.setCursor(5,29);
|
||||
sprintf(fmtText,"%4.0f",totalYieldToday);
|
||||
u8g2.print(F("today ")+String(fmtText)+F(" Wh"));
|
||||
u8g2.setCursor(5,37);
|
||||
sprintf(fmtText,"%.1f",totalYield);
|
||||
u8g2.print(F("total ")+String(fmtText)+F(" kWh"));
|
||||
}
|
||||
else
|
||||
{
|
||||
u8g2.setFont(u8g2_font_logisoso16_tr);
|
||||
u8g2.setCursor(30,30);
|
||||
u8g2.print(F("off"));
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
}
|
||||
if ( !(extra%20) )
|
||||
{
|
||||
u8g2.setCursor(5,57);
|
||||
u8g2.print(ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8g2.setCursor(0,47);
|
||||
u8g2.print(timeStr);
|
||||
}
|
||||
|
||||
u8g2.sendBuffer();
|
||||
} while( u8g2.nextPage() );
|
||||
extra++;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::setup(uint32_t timeout) {
|
||||
DPRINTLN(DBG_VERBOSE, F("app::setup"));
|
||||
|
||||
#ifdef ENA_NOKIA
|
||||
u8g2.begin();
|
||||
ShowInfoText("booting...");
|
||||
#endif
|
||||
#ifdef ENA_SSD1306
|
||||
display.init();
|
||||
display.flipScreenVertically();
|
||||
display.setContrast(63);
|
||||
display.setBrightness(63);
|
||||
|
||||
display.clear();
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
|
||||
|
||||
display.drawString(64,22,"Starting...");
|
||||
display.display();
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
#endif
|
||||
|
||||
mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC);
|
||||
mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT) - (ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC);
|
||||
loadEEpconfig();
|
||||
|
@ -82,7 +341,15 @@ void app::loop(void) {
|
|||
mUtcTimestamp = mWifi->getNtpTime();
|
||||
DPRINTLN(DBG_INFO, F("[NTP]: ") + getDateTimeStr(mUtcTimestamp) + F(" UTC"));
|
||||
}
|
||||
|
||||
#if defined(ENA_NOKIA) || defined(ENA_SSD1306)
|
||||
static int lcnt=90000;
|
||||
if ( lcnt == 150000 )
|
||||
{
|
||||
DataScreen(this, mUtcTimestamp);
|
||||
lcnt=0;
|
||||
}
|
||||
lcnt++;
|
||||
#endif
|
||||
if (mFlagSendDiscoveryConfig) {
|
||||
mFlagSendDiscoveryConfig = false;
|
||||
sendMqttDiscoveryConfig();
|
||||
|
|
|
@ -32,16 +32,18 @@ extra_scripts =
|
|||
pre:html/convert.py
|
||||
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
knolleary/PubSubClient
|
||||
bblanchon/ArduinoJson
|
||||
;esp8266/DNSServer
|
||||
;esp8266/EEPROM
|
||||
;esp8266/ESP8266WiFi
|
||||
;esp8266/SPI
|
||||
;esp8266/Ticker
|
||||
;esp8266/DNSServer@1.1.0
|
||||
;esp8266/EEPROM@^1.0
|
||||
;esp8266/ESP8266HTTPUpdateServer@^1.0
|
||||
;esp8266/ESP8266WebServer@^1.0
|
||||
;esp8266/ESP8266WiFi@^1.0
|
||||
;esp8266/SPI@1.0
|
||||
;esp8266/Ticker@^1.0
|
||||
|
||||
[env:esp8266-release]
|
||||
platform = espressif8266
|
||||
|
@ -63,7 +65,7 @@ monitor_filters =
|
|||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
|
||||
|
||||
[env:esp8266-1m-release]
|
||||
platform = espressif8266
|
||||
board = esp8285
|
||||
|
@ -87,6 +89,41 @@ monitor_filters =
|
|||
time ; Add timestamp with milliseconds for each new line
|
||||
log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
|
||||
[env:esp8266-nokia5110]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
board_build.f_cpu = 80000000L
|
||||
build_flags = -D RELEASE -DU8X8_NO_HW_I2C -DENA_NOKIA
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
knolleary/PubSubClient
|
||||
bblanchon/ArduinoJson
|
||||
olikraus/U8g2
|
||||
|
||||
[env:esp8266-ssd1306]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
board_build.f_cpu = 80000000L
|
||||
build_flags = -D RELEASE -DENA_SSD1306
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
knolleary/PubSubClient
|
||||
bblanchon/ArduinoJson
|
||||
;https://github.com/pasko-zh/brzo_i2c.git
|
||||
https://github.com/ThingPulse/esp8266-oled-ssd1306.git
|
||||
|
||||
[env:esp32-wroom32-release]
|
||||
platform = espressif32
|
||||
board = lolin_d32
|
||||
|
@ -107,3 +144,21 @@ monitor_filters =
|
|||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
|
||||
[env:esp32-wroom32-ssd1306]
|
||||
platform = espressif32
|
||||
board = lolin_d32
|
||||
build_flags = -D RELEASE -std=gnu++14 -DENA_SSD1306
|
||||
build_unflags = -std=gnu++11
|
||||
monitor_filters =
|
||||
;default ; Remove typical terminal control codes from input
|
||||
time ; Add timestamp with milliseconds for each new line
|
||||
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
|
||||
|
||||
lib_deps =
|
||||
https://github.com/yubox-node-org/ESPAsyncWebServer
|
||||
nrf24/RF24
|
||||
paulstoffregen/Time
|
||||
knolleary/PubSubClient
|
||||
bblanchon/ArduinoJson
|
||||
https://github.com/ThingPulse/esp8266-oled-ssd1306.git
|
BIN
tools/pcb-nokia5110/1_Front.jpg
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
tools/pcb-nokia5110/2_Bottom.jpg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
tools/pcb-nokia5110/3_booting.jpg
Normal file
After Width: | Height: | Size: 232 KiB |
BIN
tools/pcb-nokia5110/4_runIP.jpg
Normal file
After Width: | Height: | Size: 285 KiB |
BIN
tools/pcb-nokia5110/5_runTime.jpg
Normal file
After Width: | Height: | Size: 253 KiB |
BIN
tools/pcb-nokia5110/6_Wiring_SSD1306.png
Normal file
After Width: | Height: | Size: 919 KiB |
BIN
tools/pcb-nokia5110/JLCPCB_Gerber_PCB_ahoy-dtu_2022-10-31.zip
Normal file
BIN
tools/pcb-nokia5110/Nokia5110-LCD.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
tools/pcb-nokia5110/Nokia5110-LCD2.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
tools/pcb-nokia5110/PCB-V1.jpg
Normal file
After Width: | Height: | Size: 181 KiB |
BIN
tools/pcb-nokia5110/SSD1306.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
52
tools/pcb-nokia5110/readme.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# PCB for Wemos D1 + Nokia5110-display + nRF24L01+
|
||||
|
||||
Simple pcb to plug a nRF24L01+ together with a Wemos D1 Mini / Pro and a NOKIA5110-display (known as PCD8544).
|
||||
One goal : You can power this pcb via USB-interface of D1-mini.
|
||||
|
||||
attached zip was created with easyeda. You can order easyly on jlcpcb.com.
|
||||
|
||||
## Attention
|
||||
Be sure you have the right type of nokia-display-pcb !
|
||||
Check pin-header-description (There are different versions avail)!
|
||||
( check picture : LIGHT (or BL) is placed between GND and VCC )
|
||||
|
||||
 or 
|
||||
|
||||
---
|
||||
|
||||
A picture of earlier version of pcb.
|
||||
|
||||

|
||||
|
||||
D1-mini and NRF placed on front side, nokia display will soldered bottom.
|
||||
You can use this PCB also without mounting a Nokia-display.
|
||||
|
||||
Actual version of PCB has mounting holes and additional 5V/Gnd -pin access.
|
||||
|
||||
## after soldering ...
|
||||
|
||||

|
||||
NRF & Wemos on Front
|
||||
|
||||

|
||||
Nokia Display soldered on bottom side
|
||||
|
||||

|
||||
while booting (wait for wifi, 1st data, ...)
|
||||
|
||||

|
||||
1st screen show most interesting info and IP in bottom line
|
||||
|
||||

|
||||
this is the normal screen with time in bottom line (refresh all 5 seconds)
|
||||
|
||||
# SSD1306
|
||||
|
||||
Some changes made possible to use SSD1306 (instead of NOKIA5110 display).
|
||||

|
||||
|
||||
You can use same PCB. You only have to connect GND (SSD:GND), VCC (SSD:VCC), D/C (SSD:SDA) and SCE (SSD:SCL)
|
||||

|
||||
|
||||
On other PCB-layouts, PIN wemos:D1 need connected to SSD:SCL and wemos:D2 has to be connected to SSD:SDA.
|
||||
much fun.
|