Skip to content

Add OLED Display example #142

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions examples/TextDisplay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## OLED Display WebThings example

In order to use this example you have to install the WebThings Arduino Library.

Change the ssid and password in order to connect to your router

```c++
const char *ssid = "";
const char *password = "";
```

Connect the SSD1306 OLED display to your ESP32.
If it has a different I2C address, change the address accordingly.

```c++
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
```

If your display has a different resolution, you can change that as well.
```c++
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
```

You also need to change the length of the body, headline and subheadline, if your display has a wider size.
This makes it possible to display longer text, if possible.

```c++
#define HEADLINE_MAX_LENGHT 10
#define SUBHEAD_MAX_LENGTH 23
#define BODY_MAX_LENGTH 20
```
248 changes: 158 additions & 90 deletions examples/TextDisplay/TextDisplay.ino
Original file line number Diff line number Diff line change
@@ -1,126 +1,194 @@
/*********************************************************************
Web Thing which draws text provided as a property.
Adapted from the Adafruit SSD1306 example:

This is an example for our Monochrome OLEDs based on SSD1306 drivers

Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using SPI to communicate
4 or 5 pins are required to inteface

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <Arduino.h>
#include <Thing.h>
#include <WebThingAdapter.h>

const char *ssid = "...";
const char *password = "...";

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define LARGE_JSON_BUFFERS 1
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// TODO: Hardcode your wifi credentials here (and keep it private)
const char *ssid = "";
const char *password = "";

#if defined(LED_BUILTIN)
const int ledPin = LED_BUILTIN;
#else
const int ledPin = 13; // manually configure LED pin
#endif

// If using software SPI (the default case):
#define OLED_MOSI 2
#define OLED_CLK 16
#define OLED_DC 0
#define OLED_CS 13
#define OLED_RESET 15
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, (int8_t)OLED_DC, OLED_RESET,
OLED_CS);

/* Uncomment this block to use hardware SPI
#define OLED_DC 6
#define OLED_CS 7
#define OLED_RESET 8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, (int8_t)OLED_CS);
*/

const int textHeight = 8;
const int textWidth = 6;
const int width = 128;
const int height = 64;

ThingActionObject *action_generator(DynamicJsonDocument *);
WebThingAdapter *adapter;

const char *textDisplayTypes[] = {"TextDisplay", nullptr};
ThingDevice textDisplay("textDisplay", "Text display", textDisplayTypes);
ThingProperty text("text", "", STRING, nullptr);
const char *oledTypes[] = {"OLED Display", nullptr};
ThingDevice oledThing("oled", "OLED Display", oledTypes);

String lastText = "moz://a iot";
StaticJsonDocument<256> oledInput;
JsonObject oledInputObj = oledInput.to<JsonObject>();
ThingAction displayAction("display", "Display text", "display a text on OLED",
"displayAction", &oledInputObj, action_generator);

void displayString(const String &str) {
int len = str.length();
int strWidth = len * textWidth;
int strHeight = textHeight;
int scale = width / strWidth;
if (strHeight > strWidth / 2) {
scale = height / strHeight;
}
int x = width / 2 - strWidth * scale / 2;
int y = height / 2 - strHeight * scale / 2;

display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(scale);
display.setCursor(x, y);
display.println(str);
display.display();
}

void setup() {
void setup(void) {
Serial.begin(115200);

// by default, we'll generate the high voltage from the 3.3v line internally!
// (neat!)
display.begin(SSD1306_SWITCHCAPVCC);

// display the splashscreen as requested :)
Serial.println("Initialize...");
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
delay(2000);
Serial.println("Clear display...");

pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
Serial.println("");
Serial.print("Connecting to \"");
Serial.print(ssid);
Serial.println("\"");
#if defined(ESP8266) || defined(ESP32)
WiFi.mode(WIFI_STA);
#endif
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection

bool blink = true;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
digitalWrite(ledPin, blink ? LOW : HIGH);
blink = !blink;
}
digitalWrite(ledPin, HIGH);

Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
adapter = new WebThingAdapter("textdisplayer", WiFi.localIP());

displayString(lastText);
adapter = new WebThingAdapter("oled-display", WiFi.localIP());
oledThing.description = "A web connected oled display";


oledInputObj["type"] = "object";
JsonObject oledInputProperties =
oledInputObj.createNestedObject("properties");


JsonObject headlineInput =
oledInputProperties.createNestedObject("headline");
headlineInput["type"] = "string";

JsonObject subheadlineInput =
oledInputProperties.createNestedObject("subheadline");
subheadlineInput["type"] = "string";

ThingPropertyValue value;
value.string = &lastText;
text.setValue(value);
JsonObject bodyInput =
oledInputProperties.createNestedObject("body");
bodyInput["type"] = "string";


textDisplay.addProperty(&text);
adapter->addDevice(&textDisplay);
oledThing.addAction(&displayAction);

adapter->addDevice(&oledThing);
adapter->begin();

Serial.println("HTTP server started");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.print("/things/");
Serial.println(oledThing.id);

}

#define HEADLINE_MAX_LENGHT 10
#define SUBHEAD_MAX_LENGTH 23
#define BODY_MAX_LENGTH 20

char headline[HEADLINE_MAX_LENGHT];
char subheadline[SUBHEAD_MAX_LENGTH];
char body[BODY_MAX_LENGTH];

void clear_buffer(){
memset(headline, 0, HEADLINE_MAX_LENGHT);
memset(subheadline, 0, SUBHEAD_MAX_LENGTH);
memset(body, 0, BODY_MAX_LENGTH);
}

int rounds = 0;

void loop()
{
if(strlen(headline) > 0 || strlen(subheadline) > 0 || strlen(body) > 0){
display.clearDisplay();
delay(250);
display.display();
display.setCursor(0,0);
display.setTextSize(2);
display.setTextColor(WHITE);
display.println(headline);

display.setCursor(0,15);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println(subheadline);
display.setCursor(0,30);
display.setTextSize(2);
display.setTextColor(WHITE);
display.println(body);
delay(250);
display.display();
clear_buffer();
rounds = 1;
}else if(rounds > 0){
//To avoid burning, clear after 30 seconds.
if(rounds == 300){
display.clearDisplay();
delay(250);
display.display();
rounds = 0;
}else{
delay(100);
rounds++;
}
}
}

void do_display(const JsonVariant &input) {
Serial.println("do display...");

JsonObject inputObj = input.as<JsonObject>();
display.clearDisplay();
display.display();
String headline_tmp = inputObj["headline"];
String subheadline_tmp = inputObj["subheadline"];
String body_tmp = inputObj["body"];
clear_buffer();

size_t length = strlen(headline_tmp.c_str());
if(length > HEADLINE_MAX_LENGHT){
Serial.println("Headline is too long");
return;
}else{
memcpy(headline, headline_tmp.c_str(), length);
}
length = strlen(subheadline_tmp.c_str());
if(length > SUBHEAD_MAX_LENGTH){
Serial.println("Subheadline is too long");
return;
}else{
memcpy(subheadline, subheadline_tmp.c_str(), length);
}
length = strlen(body_tmp.c_str());
if(length > BODY_MAX_LENGTH){
Serial.println("Body is too long");
return;
}else{
memcpy(body, body_tmp.c_str(), length);
}
}

void loop() {
adapter->update();
displayString(lastText);
ThingActionObject *action_generator(DynamicJsonDocument *input) {
return new ThingActionObject("display", input, do_display, nullptr);
}