Skip to content

Commit 2b20879

Browse files
committed
finished
1 parent 68e29e3 commit 2b20879

File tree

4 files changed

+312
-6
lines changed

4 files changed

+312
-6
lines changed
635 KB
Loading
4.25 KB
Loading
980 KB
Loading

content/hardware/03.nano/boards/nano-matter/tutorials/getting-started-matter-display/getting-started-matter-display.md

Lines changed: 312 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,8 @@ EPD.setOrientation(7);
871871
```
872872
![Screen Orientation](assets/orientation.gif)
873873

874+
***Test the library example called __Common_Orientation__***
875+
874876
#### Text
875877

876878
To display text on the E-ink screen you need to define different screen parameters such as **font**, **orientation**, the **string** to be shown and its **color**.
@@ -937,24 +939,328 @@ EPD.flush(); // update the screen to show the text on buffer
937939

938940
![Text display](assets/text.png)
939941

940-
- Forms
941-
- Refresh
942+
***Test the library example called __Common_Text__***
943+
944+
#### Graphics
945+
946+
The E-ink display API includes some predefined functions for basic geometrical shapes, here you find some:
947+
948+
- `EPD.line(<x1>, <y1>, <x2>, <y2>, <color>)`
949+
- `EPD.circle(<x0>, <y0>, <radius>, <color>)`
950+
- `EPD.triangle(<x1>, <y1>, <x2>, <y2>, <x3>, <y3>, <color>)`
951+
- `EPD.rectangle(<x1>, <y1>, <x2>, <y2>, <color>)`
952+
- `EPD.point(<x1>, <y1>, <color>)`
953+
954+
You can make them opaque or a wire frame using the `setPenSolid()` function as follows:
955+
956+
```arduino
957+
EPD.setPenSolid(true); // print opaque forms
958+
959+
EPD.setPenSolid(false); // print wire frame forms
960+
```
961+
962+
![Forms display](assets/forms.png)
963+
964+
***Follow the [Pervasive Displays documentation](https://pdls.pervasivedisplays.com/reference/html/de/d04/a01209.html) for advanced graphics.***
942965

943966
### RGB LED
944967

945-
- LED control
968+
The Nano Matter Display features an addressable WS2813C RGB LED that can be easily used for visual status feedback.
969+
970+
To control the onboard LED the `ezWS2812gpio.h` header is needed.
971+
972+
The LED object is configured using the `ezWS2812gpio` class as follows:
973+
974+
```arduino
975+
const pins_t myBoard = boardArduinoNanoMatter; // myBoard stores the Nano Matter pinout configuration
976+
ezWS2812gpio myRGB(1, myBoard.ledData); // (<LED_quantity>, <data_pin>)
977+
```
978+
979+
To control the LED color use the `set_pixel` function as follows:
980+
981+
```arduino
982+
myRGB.set_pixel(<R>, <G>, <B>); // pass the RGB color code in the (0 - 255) range
983+
```
984+
985+
![LED demo](assets/led-demo.jpg)
986+
987+
***Test the library example called __EXT4_WS2813C__***
946988

947989
### 3-axis Accelerometer
948990

949-
- Accel example
991+
The Nano Matter Display features a LIS2DH12 3-axis accelerometer that can be easily used with open-source libraries as the `SparkFun LIS2DH12`, install it by using the IDE Library Manager.
992+
993+
The following example code adapts the screen orientation to the physical board rotation just as your smartphone does.
994+
995+
```arduino
996+
#include <Wire.h>
997+
998+
// EPD Screen Library and Configuration
999+
#include "PDLS_EXT4_Basic_Matter.h"
1000+
#include "hV_Configuration.h"
1001+
1002+
// Accelerometer support library
1003+
#include "SparkFun_LIS2DH12.h" //Click here to get the library: http://librarymanager/All#SparkFun_LIS2DH12
1004+
1005+
SPARKFUN_LIS2DH12 accel; //Create instance
1006+
1007+
// PDLS
1008+
pins_t myBoard = boardArduinoNanoMatter;
1009+
1010+
Screen_EPD_EXT4_Fast EPD(eScreen_EPD_290_KS_0F, myBoard);
1011+
1012+
uint8_t orientation = 9;
1013+
uint8_t oldOrientation = 0;
1014+
int aX, aY, aZ;
1015+
1016+
void setup() {
1017+
Serial.begin(115200);
1018+
delay(500);
1019+
Serial.println();
1020+
1021+
// Start
1022+
EPD.begin();
1023+
EPD.regenerate(); // Clear buffer and screen
1024+
1025+
Wire.begin();
1026+
1027+
if (accel.begin() == false) {
1028+
Serial.println("Accelerometer no detected. Freezing...");
1029+
while (1)
1030+
;
1031+
}
1032+
accel.disableTemperature();
1033+
1034+
pinMode(myBoard.button, INPUT_PULLUP);
1035+
}
1036+
1037+
void loop() {
1038+
1039+
if (accel.available()) {
1040+
1041+
aX = accel.getX();
1042+
aY = accel.getY();
1043+
aZ = accel.getZ();
1044+
1045+
Serial.println();
1046+
Serial.printf("x: %d, y: %d, z: %d", aX, aY, aZ);
1047+
1048+
oldOrientation = orientation;
1049+
if (oldOrientation == 9) // Default
1050+
{
1051+
orientation = 3;
1052+
}
1053+
1054+
if (abs(aZ) < 900) {
1055+
if ((aX > 500) and (abs(aY) < 400)) {
1056+
orientation = 2;
1057+
} else if ((aX < -500) and (abs(aY) < 400)) {
1058+
orientation = 0;
1059+
} else if ((aY > 500) and (abs(aX) < 400)) {
1060+
orientation = 3;
1061+
} else if ((aY < -500) and (abs(aX) < 400)) {
1062+
orientation = 1;
1063+
}
1064+
}
1065+
Serial.printf(", o %i -> %i", oldOrientation, orientation);
1066+
1067+
if (orientation != oldOrientation) // Update display
1068+
{
1069+
EPD.clear();
1070+
EPD.setOrientation(orientation);
1071+
EPD.selectFont(Font_Terminal12x16);
1072+
EPD.gText(0, 0, "Orientation");
1073+
uint16_t dt = EPD.characterSizeY();
1074+
EPD.selectFont(Font_Terminal16x24);
1075+
EPD.gText(0, dt, formatString("%i", orientation));
1076+
EPD.gText(1, dt, formatString("%i", orientation));
1077+
1078+
uint16_t x = EPD.screenSizeX();
1079+
uint16_t y = EPD.screenSizeY();
1080+
uint16_t dx = x / 2;
1081+
uint16_t dy = y / 2;
1082+
uint16_t dz = min(dx, dy) / 3;
1083+
1084+
EPD.setPenSolid(true);
1085+
EPD.triangle(dx, dy - dz, dx + dz, dy, dx - dz, dy, myColours.black);
1086+
EPD.rectangle(dx + dz / 3, dy, dx - dz / 3, dy + dz, myColours.black);
1087+
1088+
EPD.setPenSolid(false);
1089+
EPD.circle(dx, dy, dz + 8, myColours.black);
1090+
1091+
EPD.flush();
1092+
Serial.print(" *");
1093+
}
1094+
} else {
1095+
Serial.print(".");
1096+
delay(8);
1097+
}
1098+
1099+
if (digitalRead(myBoard.button) == LOW) {
1100+
EPD.regenerate();
1101+
while (true) {
1102+
delay(1000);
1103+
}
1104+
}
1105+
1106+
delay(200);
1107+
}
1108+
```
1109+
1110+
If you rotate the Nano Matter Display you will notice how the screen orientation will change making the arrow always to point upward.
1111+
1112+
![Accelerometer controlling orientation](assets/accel.gif)
9501113

9511114
### Temperature and Humidity Sensor
9521115

953-
- How to
1116+
The Nano Matter Display features a HDC2080 temperature and relative humidity sensor that can be easily used with open-source libraries as the `Lime Labs HDC2080`, install it by using the IDE Library Manager.
1117+
1118+
```arduino
1119+
#include "PDLS_EXT4_Basic_Matter.h"
1120+
#include "hV_HAL_Peripherals.h"
1121+
#include "hV_Configuration.h"
1122+
#include "Wire.h"
1123+
#include <HDC2080.h>
1124+
1125+
pins_t nano_matter = boardArduinoNanoMatter;
1126+
1127+
Screen_EPD_EXT4_Fast EPD(eScreen_EPD_290_KS_0F, nano_matter);
1128+
1129+
#define MATTER_EXAMPLE_NAME "Matter Weather"
1130+
1131+
#define HDC_ADDR 0x40
1132+
HDC2080 sensor(HDC_ADDR);
1133+
1134+
unsigned long previousMillis = 0;
1135+
const long interval = 5000;
1136+
1137+
struct measure_s {
1138+
float value;
1139+
float oldValue = 999.9;
1140+
float minimum = 999.9;
1141+
float maximum = -999.9;
1142+
};
1143+
1144+
measure_s temperature;
1145+
measure_s humidity;
1146+
1147+
static uint8_t countFlush = 1; // Counter for global update
1148+
const uint8_t FAST_BEFORE_GLOBAL = 16; // Number of fast updates before global update
1149+
1150+
void setup() {
1151+
// Serial = Serial by default, otherwise edit hV_HAL_Peripherals.h
1152+
Serial.begin(115200);
1153+
delay(500);
1154+
1155+
// Start
1156+
EPD.begin();
1157+
EPD.setPowerProfile(POWER_MODE_AUTO, POWER_SCOPE_GPIO_ONLY);
1158+
EPD.setOrientation(3);
1159+
EPD.regenerate(); // Clear buffer and screen
1160+
1161+
sensor.begin();
1162+
sensor.reset();
1163+
1164+
// Configure Measurements
1165+
sensor.setMeasurementMode(TEMP_AND_HUMID); // Set measurements to temperature and humidity
1166+
sensor.setRate(ONE_HZ); // Set measurement frequency to 1 Hz
1167+
sensor.setTempRes(FOURTEEN_BIT);
1168+
sensor.setHumidRes(FOURTEEN_BIT);
1169+
1170+
sensor.triggerMeasurement();
1171+
}
1172+
1173+
void loop() {
1174+
1175+
unsigned long currentMillis = millis();
1176+
if (currentMillis - previousMillis >= interval) {
1177+
1178+
previousMillis = currentMillis;
1179+
1180+
// HDC2080
1181+
// Temperature
1182+
temperature.value = sensor.readTemp();
1183+
// Humidity
1184+
humidity.value = sensor.readHumidity();
1185+
1186+
countFlush %= FAST_BEFORE_GLOBAL;
1187+
1188+
if (countFlush == 0) {
1189+
EPD.regenerate();
1190+
}
1191+
1192+
displayValue(0, "Temperature", &temperature, "°C");
1193+
displayValue(1, "Humidity", &humidity, "%");
1194+
EPD.flush();
1195+
1196+
countFlush += 1;
1197+
1198+
// Serial
1199+
Serial.print(formatString("Temperature = %5.1f < %5.1f < %5.1f oC, Humidity= %5.1f < %5.1f < %5.1f %%",
1200+
temperature.minimum, temperature.value, temperature.maximum,
1201+
humidity.minimum, humidity.value, humidity.maximum));
1202+
Serial.println();
1203+
}
1204+
1205+
delay(1000);
1206+
1207+
}
1208+
1209+
bool displayValue(uint8_t slot, String name, measure_s* value, String unit) {
1210+
uint16_t x = EPD.screenSizeX();
1211+
uint16_t y = EPD.screenSizeY();
1212+
uint16_t dx, dy, x0, y0;
1213+
1214+
x0 = x * slot / 2;
1215+
dx = x / 8;
1216+
y0 = 0;
1217+
dy = y / 5;
1218+
1219+
(*value).value = ((int32_t)(10 * (*value).value + 5)) / 10.0;
1220+
bool result = ((*value).value != (*value).oldValue);
1221+
(*value).oldValue = (*value).value;
1222+
(*value).maximum = max((*value).maximum, (*value).value);
1223+
(*value).minimum = min((*value).minimum, (*value).value);
1224+
1225+
EPD.setPenSolid(true);
1226+
EPD.setFontSolid(true);
1227+
EPD.dRectangle(x0, y0, dx * 4, dy * 4, myColours.white);
1228+
1229+
EPD.selectFont(Font_Terminal12x16);
1230+
EPD.gText(x0, y0, name);
1231+
1232+
EPD.selectFont(Font_Terminal16x24);
1233+
EPD.gTextLarge(x0, y0 + 1 * dy, formatString("%5.1f", (*value).value));
1234+
1235+
EPD.selectFont(Font_Terminal12x16);
1236+
char unit_c[4] = { 0 };
1237+
strcpy(unit_c, utf2iso(unit).c_str());
1238+
EPD.gText(x0 + 3 * dx - EPD.characterSizeX() * 0, y0 + 1 * dy - EPD.characterSizeY(), formatString("%s", unit_c));
1239+
1240+
EPD.selectFont(Font_Terminal8x12);
1241+
EPD.gText(x0, y0 + 3 * dy, "Minimum");
1242+
EPD.gText(x0 + 2 * dx, y0 + 3 * dy, "Maximum");
1243+
1244+
EPD.selectFont(Font_Terminal12x16);
1245+
EPD.gText(x0, y0 + 4 * dy, formatString("%5.1f", (*value).minimum));
1246+
EPD.gText(x0 + 2 * dx, y0 + 4 * dy, formatString("%5.1f", (*value).maximum));
1247+
1248+
EPD.setPenSolid(false);
1249+
return result;
1250+
}
1251+
```
1252+
1253+
After uploading the example sketch you will be able to monitor the environment temperature and relative humidity alongside their historical minimum and maximums.
1254+
1255+
![Temperature and Humidity](assets/weather-c.jpg)
9541256

9551257
## Conclusion
9561258

1259+
In this tutorial you learned how to use the Nano Matter Display expansion kit, leveraging all its features like the E-ink screen to display high-contrast graphics with a low power consumption on a 2.9" (384x168) EPD. Other included features were explained like the built-in RGB LED, the 3-axis accelerometer and the temperature and humidity sensor. All these features were showcased using the user-friendly Arduino environment.
1260+
9571261
### Next Steps
9581262

959-
### Troubleshooting
1263+
- Extend your knowledge with E-ink displays following the [Pervasive Displays documentation](https://docs.pervasivedisplays.com/).
1264+
- Try all the examples included in the library for a deeper understanding on the API.
1265+
- Start creating your own graphics to display custom data on the screen.
9601266

0 commit comments

Comments
 (0)