Welcome to the 1st part of the temperature / humidity display guide.

The aim of the 1st part is to build a working temperature / humidity display using an e-ink display, Lolin D1 mini and a DHT22 sensor. At this point the device will be powered via micro-usb cable.

I decided to call this the part 1, as the aim is to modify the device to run on battery power, and to make it send the data to a database (InfluxDB) from where it is then accessible for example by Apple HomeKit / HomeBridge. After making it run on battery power, next step would be to 3d-print a case for it to allow mounting it on a wall.

Disclaimer

I'm not a professional, and the purpose of this blog/post is just to describe how I did this project and how I reached a result that was working for me. I take no responsibility for any errors that I have made in designing this, and I don't guarantee the safety of the devices you end up creating. Build it at your own risk!

Parts required for this part

The part list for part 1:

See part 2 for more required parts if you plan on going for that too.

Building it

I began by wiring the display to the Lolin D1 Mini. I used the cable that came with the display at this point, but later on I soldered it instead into the Lolin. It's a good idea to first test the components that they actually work before going forward with the final build.

Wiring it

There are quite many cables to be connected. Here is a schematic showing how they should be connected:
temp-humi-1

I personally first connected the display with the cables that came with it to my Lolin D1 Mini which had the legs soldered into it. This allowed testing the display and the connections easily.
IMG_0821

But later on I decided to solder all the cables directly to the Lolin, also don't forget the jumper cable between D0 and RST which allows the Lolin to wake up from the deepSleep we are going to put it in between updates:
IMG_0844

This is what the data looks like on the screen:
IMG_0822

I also soldered the 10k pull-up resistor directly to the DHT22 sensor:
IMG_0833

Here is also an image to hopefully clear up the wiring on the DHT22, the red one being the 3.3v, the yellow one being the data, and the blue one being the ground.
IMG_0823

I also ended up soldering the display cables to the back of the display instead of using the connector, like this (the cables I used came from a CAT6 network cable):
IMG_0830

Coding it

Install libraries

First to get things working, you will need to install several libraries in Arduino IDE:

Then you also need to install boards and drivers for the Lolin D1 mini. if you haven't used one before. See this project in Github for that. You might also need a driver for your board, see the Lolin homepage for that.

I had issues with the libraries I had installed through the library manager in Arduino IDE, but they worked fine when installed using the import from .zip file.

Actual code

Here is the code I created and used. The definitions are the easiest way to customize it if needed, but the code is rather simple too if you are at all familiar with coding.

For example if you would like to change the language of humidity text to finnish, you would edit the line

#define HUMIDITYTEXT "HUMIDITY %"

to something like

#define HUMIDITYTEXT "KOSTEUS %"

Here is the complete code, which can also be found from Github.

By default the display updates every 60 seconds. On startup the values might be "nan", but after that they should work just fine. There will be better revisions of the code that will handle things like that in the coming parts.

EDIT: See part 2 for improved code.

// Temperature display using DHT22 sensor, Waveshare 2.9" e-ink display and Lolin D1 mini

#include <GxEPD.h>
#include <DHT.h>

// 2.9inch black/white/red display from Waveshare
#include <GxGDEW029Z10/GxGDEW029Z10.cpp>

// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>

#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>

#define DHTPIN D1
#define DHTTYPE DHT22

#define SLEEPSECONDS 60

#define TEMPERATUREHEADERXPOS 3
#define TEMPERATUREHEADERYPOS 20
#define TEMPERATUREVALUEXPOS 5
#define TEMPERATUREVALUEYPOS 90
#define TEMPERATURETEXT "TEMPERATURE"

#define DIVIDERXPOS 0
#define DIVIDERYPOS 147
#define DIVIDERXSIZE 148
#define DIVIDERYSIZE 2

#define HUMIDITYHEADERXPOS 8
#define HUMIDITYHEADERYPOS 170
#define HUMIDITYVALUEXPOS 5
#define HUMIDITYVALUEYPOS 240
#define HUMIDITYTEXT "HUMIDITY %"

GxIO_Class io(SPI, SS, 0, 2);
GxEPD_Class display(io);
DHT dht(DHTPIN, DHTTYPE);

const GFXfont* f_small = &FreeMonoBold9pt7b;
const GFXfont* f_large = &FreeMonoBold24pt7b;

void setup() {
  display.init(115200);
  display.setRotation(0);
  display.setTextColor(GxEPD_BLACK);
  dht.begin();
}

void loop() {
  // Reads the temperature as celcius. Set the parameter to true for Fahrenheit.
  float temperature = dht.readTemperature(false);
  float humidity = dht.readHumidity();
  fullScreenUpdate(temperature, humidity);

  /* 
   * This requires pins 16 (D0) and rst to be connected to each other.
   * If you want you could change the time to sleep to a small value,
   * and add a button between the pins to only update when button is pressed.
   */
  ESP.deepSleep(SLEEPSECONDS * 1000 * 1000, WAKE_RF_DISABLED);
}

// fullScreenUpdate takes the values as parameters and prints them on the screen
void fullScreenUpdate(float temperature, float humidity) {
  // Clear the screen
  display.fillScreen(GxEPD_WHITE);

  // Print the temperature header
  display.setCursor(TEMPERATUREHEADERXPOS, TEMPERATUREHEADERYPOS);
  display.setFont(f_small);
  display.println(TEMPERATURETEXT);

  // Print the temperature value
  display.setFont(f_large);
  display.setCursor(TEMPERATUREVALUEXPOS, TEMPERATUREVALUEYPOS);
  // Print temperature value with 1 decimal
  display.println(temperature, 1);

  // Print the divider
  display.fillRect(DIVIDERXPOS, DIVIDERYPOS, DIVIDERXSIZE, DIVIDERYSIZE, GxEPD_BLACK);

  // Print the humidity header
  display.setCursor(HUMIDITYHEADERXPOS, HUMIDITYHEADERYPOS);
  display.setFont(f_small);
  display.println(HUMIDITYTEXT);

  // Print the humidity value
  display.setFont(f_large);
  display.setCursor(HUMIDITYVALUEXPOS, HUMIDITYVALUEYPOS);
  // Print humidity value with 1 decimal
  display.println(humidity, 1);

  // Update the display
  display.update();
}

See part 2 for more.