Skip to content

Commit

Permalink
Inverted position shifting idle logo (#1484)
Browse files Browse the repository at this point in the history
* Inverted idle logo

Back on white background start-up logo.
Inverted idle logo with random positioning.

* Idle Logo display default true

DISPLAY_IDLE_LOGO true as burn-in screens saver, especially fo the constant heading and line

* Display Brightness added

* SSD1306toMQTT / MQTTtoSSD1306

Additional "onstate" and "brightness" setting and regular display state reporting

Docs - separate Displays section
  • Loading branch information
DigiH authored Mar 1, 2023
1 parent ecd23b9 commit a6e0f60
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 105 deletions.
1 change: 1 addition & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ module.exports = {
'use/sensors',
'use/actuators',
'use/boards',
'use/displays',
'use/gateway'
]
},
Expand Down
62 changes: 0 additions & 62 deletions docs/use/boards.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,65 +84,3 @@ OpenMQTTGateway support a low power mode for ESP32, this mode can be set by MQTT

The low power mode can be changed also with a push to button B when the board is processing (top button on M5stickC, M5stickC Plus and middle button of M5stack).
If you are already in low power mode 1 or 2 with M5Stack you can wake up the board by pressing the red button.

## SSD1306 Display boards ( Heltec SX127X 433Mhz boards and LILYGO® LoRa32 V2.1_1.6.1 433 Mhz )

Several options are available for the display of information on the SSD1306 Display. These options include display of the OMG logo and setup messages, redirecting of the log output to the display, and display of various module messages on the display. These options are exclusive to each other, and when a different option is enabled, the current option is disabled.

### Setting the log output

The display of serial log messages to the display can be enabled via compiler directive `-DLOG_TO_LCD=true` or via MQTT commands.

For example if you want to set the serial log to LCD

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306 -m '{"log-lcd":true}'`

you can also revert it back to the serial monitor:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306 -m '{"log-lcd":false}'`

The log level of the messages displayed is Errors and Warnings, and this can only be changed via the compiler directive `-DLOG_LEVEL_LCD=LOG_LEVEL_NOTICE`.

### Displaying Module json messages ( default )

The display of messages from various modules is also supported. Currently supported modules include `ZgatewayRTL_433` and `ZsensorBME280`.

This can be enabled with the compiler directive `-DJSON_TO_LCD=true`.

You can also change it by MQTT. For example if you want to display module json messages:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306 -m '{"json-lcd":true}'`

And to disable the display of module json messages:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306 -m '{"display-json":false}'`

### Units for display, Metric or Imperial

By default the display uses metric units, and this can be changed either by compiler directive or mqtt command.

The compiler directive is `-DDISPLAY_METRIC=true`

The mqtt command to change the units is:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306 -m '{"display-metric":false}'`

Please note that it may take several seconds/display updates for the units to change. This is due to the queueing of messages for display.

### Flip Display 180 degrees

This allows you to rotate the display 180 degrees. Can be set at compile time or during use, defaults to true.

The compiler directive is `-DDISPLAY_FLIP=false`

The mqtt command to change display orientation is:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306 -m '{"display-flip":false}'`

Please note that it may take several seconds/display updates for the display to change. This is due to the queueing of messages for display.

### Display OpenMQTTGateway Logo when Idle

When this option is enabled the OLED display will show the OpenMQTTGateway Logo when it is idle. Defaults to false

The compiler directive is `-DDISPLAY_IDLE_LOGO=true`
86 changes: 86 additions & 0 deletions docs/use/displays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Displays

## SSD1306 Display (Heltec SX127X and LILYGO® LoRa32 boards)
Several options are available for the display of information on the SSD1306 display. Some options are exclusive to each other, and when a different option is enabled, the current option is disabled.

The current SSD1306 display states are being published to the `SSD1306toMQTT` topic, e.g.

`{"onstate":true,"brightness":50,"display-metric":true,"display-flip":true,"idlelogo":true,"log-lcd":false,"json-lcd":true}`

### Display ON/OFF
To turn the SSD1306 display on or off.

This can be enabled with the compiler directive `-DDISPLAY_STATE=true`.

MQTT Display OFF command:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m {"onstate":false}`

MQTT Display ON command:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m {"onstate":true}`

### Brightness
The display brightness can be set between 0-100%.

It is recommended to set a value lower than 100 to extend the life of the OLED display. The default setting is 50.

This can be set with the compiler directive `-DDISPLAY_BRIGHTNESS=50`.

or with the runtime command

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m {"brightness":50}`

### Metric or Imperial property units
To have applicable device properties displayed in Imperial units, e.g. °F for temperature.

This can be set with the compiler directive `-DDISPLAY_METRIC=false`.

or with the runtime command

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m {"display-metric":false}`

### Rotating the display by 180 degrees

This can be set with the compiler directive `-DDISPLAY_FLIP=false`.

or with the runtime command

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m {"display-flip":false}`

### Display idle Logo
To display the OpenMQTTGateway logo during device display idle time. This reduces the likelihood of burn-in.

This can be set with the compiler directive `-DDISPLAY_IDLE_LOGO=true`.

or at runtime with

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m {"idlelogo":true}`

### Setting the log output

The display of serial log messages to the display can be enabled via compiler directive `-DLOG_TO_LCD=true` or via MQTT commands.

For example if you want to set the serial log to LCD

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m '{"log-lcd":true}'`

you can also revert it back to the serial monitor:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m '{"log-lcd":false}'`

The log level of the messages displayed is Errors and Warnings, and this can only be changed via the compiler directive `-DLOG_LEVEL_LCD=LOG_LEVEL_NOTICE`.

### Displaying Module json messages (default)

The display of messages from various modules is also supported. Currently supported modules include `ZgatewayRTL_433`, `ZgatewayBT` and `ZsensorBME280`.

This can be enabled with the compiler directive `-DJSON_TO_LCD=true`.

You can also change it by MQTT. For example if you want to display module json messages:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m '{"json-lcd":true}'`

And to disable the display of module json messages:

`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoSSD1306/config -m '{"display-json":false}'`
1 change: 1 addition & 0 deletions environments.ini
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ build_flags =
; '-DJSON_TO_LCD=true'
; '-DLOG_LEVEL_LCD=LOG_LEVEL_NOTICE'
; '-DDISPLAY_IDLE_LOGO=false'
; '-DDISPLAY_BRIGHTNESS=100'
; '-DDISPLAY_METRIC=false'
custom_description = For ESP32, Gateway using RTL_433_ESP and RadioLib
custom_hardware = ESP32 LILYGO LoRa32 V2.1
Expand Down
114 changes: 75 additions & 39 deletions main/ZdisplaySSD1306.ino
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ boolean logToLCDDisplay = LOG_TO_LCD;
boolean jsonDisplay = JSON_TO_LCD;
boolean displayMetric = DISPLAY_METRIC;
boolean displayFlip = DISPLAY_FLIP;
boolean displayState = DISPLAY_STATE;
boolean idlelogo = DISPLAY_IDLE_LOGO;
uint8_t displayBrightness = round(DISPLAY_BRIGHTNESS * 2.55);

/*
Toogle log display
Expand Down Expand Up @@ -99,20 +102,17 @@ void loopSSD1306() {
}
free(message);
nextDisplayPage = uptime() + DISPLAY_PAGE_INTERVAL;
logoDisplayed = false;
}
}
/*
Display logo if it has been more than DISPLAY_PAGE_INTERVAL
*/
# if DISPLAY_IDLE_LOGO
if (uptime() > nextDisplayPage + 1 && !logoDisplayed) {
Oled.fillScreen(WHITE);
Oled.drawLogo();
if (uptime() > nextDisplayPage + 1 && !logoDisplayed && idlelogo) {
Oled.fillScreen(BLACK);
Oled.drawLogo(rand() % 13 - 5, rand() % 32 - 13);
logoDisplayed = true;
} else {
logoDisplayed = false;
}
# endif
}

/*
Expand All @@ -125,7 +125,21 @@ void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object dec
if (cmpToMainTopic(topicOri, subjectMQTTtoSSD1306set)) {
Log.trace(F("MQTTtoSSD1306 json set" CR));
// Log display set between SSD1306 lcd (true) and serial monitor (false)
if (SSD1306data.containsKey("log-lcd")) {
if (SSD1306data.containsKey("onstate")) {
if (displayState != SSD1306data["onstate"]) {
displayState = SSD1306data["onstate"];
Oled.begin();
}
displayState = SSD1306data["onstate"];
Log.notice(F("Set display state: %T" CR), logToLCDDisplay);
success = true;
} else if (SSD1306data.containsKey("brightness")) {
displayBrightness = SSD1306data["brightness"];
displayBrightness = round(displayBrightness * 2.55);
Oled.display->setBrightness(displayBrightness);
Log.notice(F("Set brightness: %d" CR), displayBrightness);
success = true;
} else if (SSD1306data.containsKey("log-lcd")) {
logToLCDDisplay = SSD1306data["log-lcd"];
Log.notice(F("Set lcd log: %T" CR), logToLCDDisplay);
logToLCD(logToLCDDisplay);
Expand All @@ -145,6 +159,9 @@ void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object dec
displayMetric = SSD1306data["display-metric"];
Log.notice(F("Set display-metric: %T" CR), displayMetric);
success = true;
} else if (SSD1306data.containsKey("idlelogo")) {
idlelogo = SSD1306data["idlelogo"];
success = true;
} else if (SSD1306data.containsKey("display-flip")) {
displayFlip = SSD1306data["display-flip"];
Log.notice(F("Set display-flip: %T" CR), displayFlip);
Expand All @@ -156,9 +173,9 @@ void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object dec
success = true;
}
if (success) {
pub(subjectSSD1306toMQTTset, SSD1306data);
stateSSD1306Display();
} else {
pub(subjectSSD1306toMQTTset, "{\"Status\": \"Error\"}"); // Fail feedback
pub(subjectSSD1306toMQTT, "{\"Status\": \"Error\"}"); // Fail feedback
Log.error(F("[ SSD1306 ] MQTTtoSSD1306 Fail json" CR), SSD1306data);
}
}
Expand All @@ -182,6 +199,9 @@ void ssd1306PubPrint(const char* topicori, JsonObject& data) {
strlcpy(message->title, strtok(topic, "/"), OLED_TEXT_WIDTH);
free(topic);

Oled.display->normalDisplay();
// Oled.display->normalDisplay();

switch (hash(message->title)) {
case hash("SYStoMQTT"): {
// {"uptime":456356,"version":"lilygo-rtl_433-test-A-v1.1.1-25-g574177d[lily-cloud]","freemem":125488,"mqttport":"1883","mqttsecure":false,"freestack":3752,"rssi":-36,"SSID":"The_Beach","BSSID":"64:A5:C3:69:C3:38","ip":"192.168.1.239","mac":"4C:75:25:A8:D5:D8","actRec":3,"mhz":433.92,"RTLRssiThresh":-98,"RTLRssi":-108,"RTLAVGRssi":-107,"RTLCnt":121707,"RTLOOKThresh":90,"modules":["LILYGO_OLED","CLOUD","rtl_433"]}
Expand Down Expand Up @@ -486,18 +506,21 @@ void OledSerial::begin() {
xSemaphoreGive(semaphoreOLEDOperation);

display->init();
if (displayFlip) {
display->flipScreenVertically();
if (displayState) {
if (displayFlip) {
display->flipScreenVertically();
} else {
display->resetOrientation();
}
display->setFont(ArialMT_Plain_10);
display->setBrightness(displayBrightness);
drawLogo(0, 0);
display->invertDisplay();
display->setLogBuffer(OLED_TEXT_ROWS, OLED_TEXT_BUFFER);
delay(1000);
} else {
display->resetOrientation();
display->displayOff();
}
display->setFont(ArialMT_Plain_10);
display->setColor(WHITE);
display->fillRect(0, 0, OLED_WIDTH, OLED_HEIGHT);
display->display();
drawLogo();
display->setLogBuffer(OLED_TEXT_ROWS, OLED_TEXT_BUFFER);
delay(1000);
}

/*
Expand Down Expand Up @@ -543,6 +566,7 @@ size_t OledSerial::write(const uint8_t* buffer, size_t size) {
if (xPortGetCoreID() == CONFIG_ARDUINO_RUNNING_CORE) {
if (xSemaphoreTake(semaphoreOLEDOperation, pdMS_TO_TICKS(30000)) == pdTRUE) {
nextDisplayPage = uptime() + DISPLAY_PAGE_INTERVAL;
display->normalDisplay();
display->clear();
display->setColor(WHITE);
display->setFont(ArialMT_Plain_10);
Expand Down Expand Up @@ -590,38 +614,50 @@ boolean OledSerial::displayPage(displayQueueMessage* message) {
/*
Primitives behind OpenMQTTGateway logo
*/
void OledSerial::drawLogo() {
void OledSerial::drawLogo(int xshift, int yshift) {
if (xSemaphoreTake(semaphoreOLEDOperation, pdMS_TO_TICKS(30000)) == pdTRUE) {
display->setColor(BLACK);

display->setColor(WHITE);
// line 1
display->drawLine(15, 28, 20, 31);
display->drawLine(15, 29, 20, 32);
display->drawLine(15 + xshift, 28 + yshift, 20 + xshift, 31 + yshift);
display->drawLine(15 + xshift, 29 + yshift, 20 + xshift, 32 + yshift);
// line 2
display->drawLine(25, 29, 22, 21);
display->drawLine(26, 29, 23, 21);
display->drawLine(25 + xshift, 29 + yshift, 22 + xshift, 21 + yshift);
display->drawLine(26 + xshift, 29 + yshift, 23 + xshift, 21 + yshift);
// circle 1
display->fillCircle(25, 35, 7);
display->setColor(WHITE);
display->fillCircle(25, 35, 5);
// circle 2
display->fillCircle(25 + xshift, 35 + yshift, 7);
display->setColor(BLACK);
display->fillCircle(23, 18, 4);
display->fillCircle(25 + xshift, 35 + yshift, 5);
// circle 2
display->setColor(WHITE);
display->fillCircle(23, 18, 2);
// circle 3
display->fillCircle(23 + xshift, 18 + yshift, 4);
display->setColor(BLACK);
display->fillCircle(11, 25, 5);
display->fillCircle(23 + xshift, 18 + yshift, 2);
// circle 3
display->setColor(WHITE);
display->fillCircle(11, 25, 3);
// name
display->fillCircle(11 + xshift, 25 + yshift, 5);
display->setColor(BLACK);
display->drawString(32, 32, "penMQTTGateway");
display->fillCircle(11 + xshift, 25 + yshift, 3);
// name
display->setColor(WHITE);
display->drawString(32 + xshift, 32 + yshift, "penMQTTGateway");

display->display();
delay(50);
xSemaphoreGive(semaphoreOLEDOperation);
}
}

void stateSSD1306Display() {
//Publish display state
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
JsonObject DISPLAYdata = jsonBuffer.to<JsonObject>();
DISPLAYdata["onstate"] = (bool)displayState;
DISPLAYdata["brightness"] = (int)round(displayBrightness / 2.55);
DISPLAYdata["display-metric"] = (bool)displayMetric;
DISPLAYdata["display-flip"] = (bool)displayFlip;
DISPLAYdata["idlelogo"] = (bool)idlelogo;
DISPLAYdata["log-lcd"] = (bool)logToLCDDisplay;
DISPLAYdata["json-lcd"] = (bool)jsonDisplay;
pub(subjectSSD1306toMQTT, DISPLAYdata);
}

#endif
Loading

0 comments on commit a6e0f60

Please sign in to comment.