Part 1: Temperature Display And Breakout Board

Rob Bell and Mike Hansell

Issue 9, March 2018

This article includes additional downloadable resources.
Please log in to access.

Log in

The 4D Systems’ IoD-09TH is a fantastic Wi-Fi-enabled display. We’ve put it to use as a web server-enabled temperature display.

BUILD TIME: 20 minutes


This project came to life as we wanted to keep an eye on the temperatures in our server room. We have two full racks of storage here at DIYODE - it’s like our own mini data centre! Of course, all that hardware provides substantial heat load in the room. Thankfully this is catered for by a powerful air conditioning system and the temperature, even in the peak of summer, rarely gets above 24°. However things happen. Air conditioners fail, circuit breakers trip, and other events happen that we can’t predict. We also aren’t around 24 hours a day to constantly monitor the temperature. Indeed, we do have a commercial thermometer unit inside the server room, which shows the temperature at the push of a button, but it’s terribly inconvenient.

So what we’ve come up with is a project that gives us temperature readings, a visual display using the IoD-09TH from 4D Systems, Wi-Fi-enabled web server to provide remote access to data, as well as a breakout board to automate some actions too. Understandably, this is a two-part project. In the first installment, we’ll get the display running, temperature measurements, as well as web server access to the data, and the breakout PCB (optional but recommended).


When we initially considered this idea, we were going to simply provide a nice large display, which we could put on the glass door of the server room to view at a glance. We started using the 4D Systems 430DCT-CLB that we used in the Function Generator project last month, but we thought about what was really important for this project, and being able to access readings ANY TIME, from anywhere, was considered fundamental.

Ultimately we determined that the visual display was less important for this project (indeed most server rooms don’t have glass doors either) and Wi-Fi was a great feature to have for access, so we turned to the IoD-09TH. The IoD-09 is based on the popular ESP8266 chip, so it’s like a fast Arduino (80MHz). However it also has a built-in four-line 64k colour display, integrated graphic accelerator. Wi-Fi chip, and several GPIO pins and an SD card slot. All this in a small 12-pin package. It can be programmed with the Arduino IDE and uses a small programming module to upload the compiled program. For advanced graphics, it’s necessary to use the 4D Systems WS4 IDE; however, for this project we’re keeping it simple with text display for now, so we only need the Arduino IDE. The IoD is programmed using the 4D Systems 4D-UPA programming adaptor, which provides USB interface for programming.


As many of you will know, there is a DHT11 library available for Arduino. Since we started our code in an environment that couldn’t use this, we had already started reading data from the DHT11 without the library. So the result of this exploration may be useful for implementing the DHT sensor in an environment where there’s no pre-built library. So we’ve retained that code here for you.

The DHT11 is a three-pin device using two pins for power and ground, which leaves one pin called “sense” for data transfer. The data transfer protocol for the DHT11 requires that a relatively long (30ms) low signal be applied to the sense pin. The DHT11 then responds with some level changes indicating it will start sending its data, one bit at a time. It provides a total of 40 bits of data but we are not interested in all of it. It transmits eight bits representing the integer part of the humidity reading first, followed by eight bits of the fractional part (if anybody is interested in that), the three set of eight bits is the integer part of the temperature, with the next eight bits being the fractional part of the temperature. There is then a further eight bits representing error-checking, which we don’t use. This timing is all a little tight. Consider that a 0 bit is transmitted as a high pulse of 26us to 28us and a one bit is around 70us. At around 50us, the timing between the bits is too tight. During development we found that there is a little leeway with the timing but not much. Getting a couple of microseconds one way or the other may result in the code hanging, waiting for signals that have already happened or are not going to happen.


As you’ll notice, we are using a few libraries to get our Wi-Fi connectivity, as well as the IoD library from 4D Systems, which allows us to easily control the display without too much fuss. We then start the display.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include "GFX4dIoD9.h"
GFX4dIoD9 gfx = GFX4dIoD9();

Then we set up our variables for the DHT sensor, and start functioning as a web server.

// This is in fact GPIO16 or pin 7 on the IoD09
byte DHpin = 16;     
// a small array to hold the 
// temp and humidity values        byte dat[5]; 
float humidity, temp_f;  // Value read from sensor
String webString="";  // String to display
const char* ssid    = "Your SSID here";
const char* password = "Your WiFi passphrase";
ESP8266WebServer server(80);

We won’t take you through each line, but the code for reading the DHT sensor manually is particularly interesting. The comments in the code tell the story along the way. Timing is rather specific, so there’s a lot of microsecond timing involved.

void trigger_DHT11()
  digitalWrite(DHpin, LOW);
  // DHT11 expects a low of > 18ms ...
  // ... to indicate user wants to read it.
  digitalWrite(DHpin, HIGH);
  // The end of our 30ms low going pulse.
  // Wait for DHT11 response.
  pinMode(DHpin, INPUT);
  // Get ready to receive data.
  while (digitalRead(DHpin) == HIGH) ;    
  // While the output is hi, do nothing. IE wait for low sig.
  // Wait 80us for the DHT11’s response.
  if (digitalRead(DHpin) == LOW) ;  
  // If its still low do nothing. IE Wait for a hi.
  // We’ve got the hi. Wait another 80us (due to DHT11 timing requirements and then ...
  for (int i = 0; i < 4; i++)  
  // ... get 4 bytes of data. There is a 5th byte which is for data checking but we ignore that.
    dat[i] = read_data();  
  // read_data() gets 1 byte of data.
  pinMode(DHpin, OUTPUT);  
  // Got the data. Set pin to not trigger another transfer.
  digitalWrite(DHpin, HIGH);
}  // End of trigger_DHT11()

You’ll notice “read_data” function toward the end of the code. This is a function to read the data streaming from the DHT sensor after we’ve triggered it. The code reads eight data bits into “data”. It would appear that nothing is done for a 0 bit. With the variable data is zeroed for every byte of data, when a 1 bit is detected, it is moved up the bits in the byte variable “data”. So what happens for a 0? Precisely nothing! The bit in “data” is already 0. Any 1 bits will be shifted a number of places as necessary.

byte read_data()
  int i = 0;
  byte data = 0;
  for (i = 0; i < 8; i++)              // 8 bits to read.
    if (digitalRead(DHpin) == LOW)
      while (digitalRead(DHpin) == LOW) ;  // Wait for sensor to respond with a hi ...
      delayMicroseconds(35);          // Data bit 0 and 1 are both indicated by a high going pulse. It’s the width of the pulse that carries the value of 0 or 1.
      if (digitalRead(DHpin) == HIGH)    // If the signal is still high then the data bit really is a 1.
        data |= (1 << (7 - i));        // If the data bit was a 1, move a 1 up thru the 8 bits of the variable data. If a 1 is not written a 0 will be left.
      while (digitalRead(DHpin) == HIGH) ; // ... wait for the sensor pin to go lo again.
  return data;
  }  // End of read_data()

Now that we have DHT readings happening successfully, our attention turns to the web server. It’s fairly straight forward, and there’s no graphics in the display - it’s just text, and an auto-refresh with the temperature and humidity values. The handle_root function is called as part of our web server startup shown in the first code block.

void handle_root() 
 webString = "<html>
    <meta http-equiv="refresh" content="2">
    <title>Data logger</title>
    <p>Temperature: " + String((int)dat[2]) + 
    <p>Humidity: " + String((int)dat[0]) 
+ "%</p>
  server.send(200, "text/html", webString);      // send to someones browser when asked);

  // End of handle_root()

This is about as simple as it gets with a web server. Next month we’ll update this code to provide structured data for processing and visualisation.

For the code, grab the Arduino sketch from the downloadable resources and compile it onto your IoD device (note: you could use this code with a regular ESP8266 chip and a different display, or no display at all - just modify the sketch accordingly). Of course, you’ll need to add the details for your own Wi-Fi credentials to the sketch before uploading.

DHT sensor module can mount straight to the board
DHT sensor module can mount straight to the board.
The IP address is displayed on boot.


Something else we wanted to achieve in this project was some hardware control. This could be an additional fan system, an audible siren, or anything else we feel like integrating with. For what is destined to be a permanent installation, a PCB breakout board seemed to be the best solution. We’ll mount it into a 3D printed case next month too.

The PCB is simple enough, and the requirements are relatively clear: provide mounting for the IoD itself (done with IC pins so we can extract it for programming), provide a reset button, and mount the DHT sensor. However, we want to be able to achieve more than this, so we’ve broken out each of the pins on the IoD to a free pad, so you can wire in all sorts of things too. For example, add PCB headers, or solder wires directly in as you see fit. Of course, if you prefer, there’s also a USB socket for power, which you can omit for a hard-wired 5V connection.

There seems to be two types of DHT sensors around. The pin-out seems to be universal, with 5V in the centre pin, but with GND and DATA pins that can be reversed. For this reason you can attach the sensor to the front or back of the PCB, to match the pin-out you have. There’s also room left deliberately on the front so you can lay the DHT against the board and use right-angled headers. Lots of options!

The PCB is a single-sided design; there’s no reason for a two-sided board here. We could have made some prototyping space below the IoD sensor however, which we may add in the next iteration.

Hardware on the PCB for this project, outside of headers, plugs and sockets, is a simple resistor for the reset circuit. Provision is provided for a resistor between the DHT sensor and IoD device as a “just in case” - but we’ve linked the connection with wire.


Parts Required:JaycarAltronics
1 x IoD-09TH Display - -
1 x 330Ω ResistorRR0560 R7546
1 x Tactile Momentary SPST SwitchSP0720 S1124
1 x USB Socket PS0916P1300
1 x Female Header Strip HM3230 P5390
1 x Male Header Pins HM3211 P5430
1 x Custom DIYODE PCB

Clean the PCB with some isopropyl alcohol or circuit board cleaner, and check the PCB for defects, shorted tracks, and anything else suspicious. Install the sockets for the IoD, the USB socket if you’re using it, as well as the reset switch and its associated resistor. You can add a wire link in place of R2 if you’re just using a standard DHT sensor also, as we have done. The PCB itself is so simple it really doesn’t need a lot more explanation, as it’s designed to expand upon.

Before you insert the IoD onto the PCB, you’ll need to programme it. Insert it into the 4D-UPA programming adapter, and compile/upload the sketch in the digital resources. This is done via the Arduino IDE, and not with the 4D Systems IDE. In the Arduino IDE, you’ll need to select ESP8266 as the board (add it via Boards Manager if required). The IoD device will be recognised as ESP8266, it will not show up as an IoD-09TH or anything similar. The major benefit here though, is not having to add a non-standard board to your Boards Manager.


Once your sketch has compiled onto the IoD, you can remove it from the programming adapter and insert it into the PCB. Apply 5V via USB or a lead if you’re hardwiring it, and your IoD should spring to life. If it doesn’t, check that the IoD is firmly seated into the sockets. Also check the switch doesn’t have any short circuits in the solder pads. If this is shorted you could force the chip into an endless reset loop.

If everything else checks out okay, use a multimeter to ensure that you truly have 5V on your PCB. The easiest and least confusing place to do this is where the DHT sensor connects. Probe the positive terminal (middle pin) of the DHT sensor, and a known ground (pin 1 of the IoD, or any other of the many ground sources). In our prototype the entire non-tracked surface of the PCB is made into a ground plane, however a solder-masked PCB won’t provide electrical connectivity to this.

The PCB is fairly straight forward, but makes mounting straight forward and we can expand easily.


Our code provides a few seconds delay on startup. Reading too quickly from the DHT sensor can provide erratic readings, so it gives everything time to stabilise before taking a reading. The is especially important if we try and act on out-of-range readings in the next version of the code - we could trigger alarms and hardware all because of a false trigger!

This delay gives us 10 seconds to connect to Wi-Fi and display the IP address. Note, we’re anticipating a DHCP-assigned IP address from your Wi-Fi network in the code. Once this IP address is displayed on screen, note it down so you can access it remotely.

After the IP address has been displayed, we take our first temperature/humidity reading and display it on the screen. This display is then constantly refreshed about every five seconds with the current data. Brilliant!


This is where all that hard work pays off. Go to your favourite web browser on a device connected to the same Wi-Fi network as your temperature monitor. Type in the IP address which flashed up on the IoD screen when it started up.

You should be greeted with a relatively crude display of the current temperature and humidity of wherever your device is located! It will automatically refresh every few seconds, so there’s no need to do it manually.

If you can’t connect to the IoD device’s web display, there are a few things you can check:

  1. Check that the WiFi connection initialised properly. If you didn’t see an IP address when it started up, this likely did not happen, so check your Wi-Fi credentials.
  2. Confirm that the device you’re trying to connect with is on the same network. If it’s a smartphone, check that you’re using the Wi-Fi connection rather than the cellular connection. If it’s a desktop computer, check that your network connection shares the same IP pool as your IoD device. Wired and wireless connections can be segregated sometimes, depending on your hardware setup - but this is usually only something found in more complex networks such as offices.


Next month in part 2, we’ll improve on the functionality of the IoD breakout board, and provide you with several ways to improve functionality. We’re also going to investigate returning structured data rather than a web page, so we can more easily poll and visualise the data for something a little more interesting!

Microsecond Timing

As mentioned in the article, we started project development with an Arduino Uno. To give us a real display, we looked at the 4D Systems 430DCT-CLB which we used in our Function Generator recently. This display has built-in intelligence so it looked like a no-brainer. Well, that’s until we found that it doesn’t have any timing facility less than 1ms. As we need microsecond timing we started experienting with software loops to effectively waste a small amount of time. It proved difficult. Floating point maths proved to be a waste of time (no pun intended) as it’s just too quick to produce an appreciable delay. A little later the idea of simply setting a digital pin hi and low again was tested. This came in at about 11us. So with experimentation we found that we could produce predictable microsecond delays. By that time we decided that broader access to the data was more important than a big display.

Part Two: Temperature Display and Breakout Board