Welcome to the 2nd part of the Temperature / Humidity display building. Make sure to check out the 1st part too.

In this 2nd part we are going to change the setup so that it runs on 4xAA batteries, we will create a case for it by 3d-prining, and we will modify the code to post the data to a server.

Please note that there is no protection for over-discharging the batteries, which could result into some dangerous situations. Build it at your own responsibility!

Parts required

Changes to wiring

Connect the battery holder as follows:

  • red wire (positive) to the 5V on the D1 Mini
  • black wire (negative) to the GND pin on the D1 Mini

IMG_1100

Now you can power up the thing by 4xAA batteries (1.5v each). I'm using rechargeable Eneloop batteries. The board should be able to handle 6.5v max if I recall correctly, and we are now putting in about 6v.

The case

For the case I used my own design which I 3d-printed using my Anet A8 3d-printer. If you are thinking about buying one, read some reviews online to see if it suits you.

The case can be found on Thingiverse. All required files for 3d-printing are available there.

IMG_1108

I used some hot glue to fix all the parts inside the case.
IMG_1106

The case comes with a backplate, intented to be used for wall mounting.
IMG_1105

This is how it looks with backplate on. You might need to sand it a bit to make it align correctly with the case.
IMG_1104

The code

The full code is in the bottom of this blog post, if you don't want to post the data anywhere, you can remove the WiFi related lines from the setup()

  WiFi.begin("YOURWIFISSID", "YOURWIFIPASSWORD");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }

and also the posting function call from the loop():

postDataToInflux(temperature, humidity);

You might also want to remove the library imports for those, but that requires also removal of some other bits here and there to avoid issues in compiling.

// Wifi
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

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

// Wifi
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

#define DHTPIN D1
#define DHTTYPE DHT22

#define SLEEPSECONDS 300

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

  WiFi.begin("YOURWIFISSID", "YOURWIFIPASSWORD");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  // Wait for a moment for the DHT sensor to be in a working state  
  delay(2500);
}

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);
  postDataToInflux(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_DEFAULT);
}

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

  // TODO: Feels like display
//  display.setFont(f_small);
//  display.println("FEELS LIKE");
//  display.println(dht.computeHeatIndex(temperature, humidity, false));

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

void postDataToInflux(float temperature, float humidity) {
  postTemperature(temperature);
  postHumidity(humidity);
}

void postTemperature(float temperature) {
  if(WiFi.status() == WL_CONNECTED) {
    HTTPClient http; 
    http.begin("http://raspberrypi.local:8086/write?db=mydb");
    http.addHeader("Content-Type", "text/plain");
    int httpCode = http.POST("temp,tag=1 value=" + String(temperature));
    String payload = http.getString();
    http.end();
  }
}

void postHumidity(float humidity) {
  if(WiFi.status() == WL_CONNECTED) {
    HTTPClient http; 
    http.begin("http://raspberrypi.local:8086/write?db=mydb");
    http.addHeader("Content-Type", "text/plain");
    int httpCode = http.POST("humi,tag=1 value=" + String(humidity));
    String payload = http.getString();
    http.end();
  }
}