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

Add matrixDisplay example #16

Merged
merged 2 commits into from
Oct 11, 2021
Merged
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
55 changes: 55 additions & 0 deletions examples/matrixDisplay/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/make -f
# SPDX-License-Identifier: MPL-2.0
#{
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/
#}

default: all
@echo "# $@: $^"

top_reldir?=../..
topdir?=${CURDIR}/${top_reldir}

-include ${topdir}/Makefile

AVR_TOOLS_DIR?=${ARDUINO_DIR}/hardware/tools/avr
ARDUINO_DIR?=/usr/share/arduino
ARDMK_DIR?=${ARDUINO_DIR}
arduino_mk?=${ARDMK_DIR}/Arduino.mk

#{ Config part
VARIANT?=mega
BOARD_TAG=mega2560
BOARD_SUB=
MCU?=at${BOARD_TAG}
F_CPU?=16000000L
MONITOR_PORT?=$(shell ls /dev/ttyUSB* 2> /dev/null \
|| ls /dev/ttyACM* 2> /dev/null \
|| echo "/dev/TODO/setup/monitor" \
| sort | head -n1)
#}

ARCHITECTURE=avr
AVRDUDE_ARD_BAUDRATE?=115200
MONITOR_BAUDRATE?=${AVRDUDE_ARD_BAUDRATE}
AVRDUDE_ARD_PROGRAMMER?=wiring

CPPFLAGS+=-I${top_reldir}

ARDUINO_LIBS += Ethernet SPI
ARDUINO_LIBS += ArduinoMDNS
ARDUINO_LIBS += ArduinoJson
ARDUINO_LIBS += WiFi101
ARDUINO_LIBS += Wire
ARDUINO_LIBS += Adafruit_GFX
ARDUINO_LIBS += Adafruit_SSD1306

-include ${arduino_mk}

rule/setup:
@echo "Please setup your env to use ${arduino_mk}"

%: rule/setup
@echo "Please run \"make $@\" again"
32 changes: 32 additions & 0 deletions examples/matrixDisplay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Matrix Display example

You need to install the WebThings Arduino library in order to use this example.

Change the ssid and password to connect to your router

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

If you want to use more than four matrix displays, you can just change the value of `MAX_DEVICES`

```c++
#define MAX_DEVICES 4
```

If you use another PIN than PIN 5 as CS, you have to change it in the code before

```c++
#define CS_PIN 5
```

The SPI matrix display has to be connected to VSPI of the ESP32.

| ESP32 Pin | | MAX7219 Matrix |
|-------------|---|----------------|
| VCC (3.3V) | → | VCC (VDD) |
| GND | → | GND |
| D23 (IO23) | → | DIN (MOSI) |
| D5 (IO5) | → | CS (SS) |
| D18 (IO18) | → | CLK |
149 changes: 149 additions & 0 deletions examples/matrixDisplay/matrixDisplay.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/**
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Arduino.h>
#include <Thing.h>
#include <WebThingAdapter.h>

#define LARGE_JSON_BUFFERS 1

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 5

MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// 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

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

const char *displayTypes[] = {"Matrix Display", nullptr};
ThingDevice displayThing("matrixDisplay", "Matrix Display", displayTypes);

StaticJsonDocument<256> displayInput;
JsonObject displayInputObj = displayInput.to<JsonObject>();
ThingAction displayAction("display", "Display text", "display a text on a Matrix display",
"displayAction", &displayInputObj, action_generator);

void setup() {
Serial.begin(115200);
Serial.println("Initialize...");
myDisplay.begin();
myDisplay.setIntensity(0);
Serial.println("Clear display...");
myDisplay.displayClear();

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);

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("matrix-display", WiFi.localIP());
displayThing.description = "A web connected matrix display";


displayInputObj["type"] = "object";
JsonObject displayInputProperties =
displayInputObj.createNestedObject("properties");


JsonObject bodyInput =
displayInputProperties.createNestedObject("body");
bodyInput["type"] = "string";

displayThing.addAction(&displayAction);

adapter->addDevice(&displayThing);
adapter->begin();
}

#define BODY_MAX_LENGTH 200
#define MAX_WO_SCROLLING 6

char body[BODY_MAX_LENGTH];
bool scrolling = false;

void clear_buffer(){
memset(body, 0, BODY_MAX_LENGTH);
scrolling = false;
}

int rounds = 0;

void loop()
{
if(strlen(body) > 0){
myDisplay.displayClear();
myDisplay.setTextAlignment(PA_LEFT);

myDisplay.print(body);
rounds = 1;
clear_buffer();
}else if(rounds > 0){
//To avoid burning, clear after 30 seconds.
if(rounds == 300){
myDisplay.displayClear();
rounds = 0;
}else{
delay(100);
rounds++;
}
}
}

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

JsonObject inputObj = input.as<JsonObject>();
myDisplay.displayClear();
String body_tmp = inputObj["body"];

size_t 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);
}
}

ThingActionObject *action_generator(DynamicJsonDocument *input) {
return new ThingActionObject("display", input, do_display, nullptr);
}