Categories
TUTORIALS

Displaying Aggregated Data on an LCD

When using a sensor with an Arduino board there are many ways to communicate measurements such as printing to a serial monitor, displaying data on an LCD screen, shining a light, or making a sound to name a few.  But if multiple sensors are used in tandem an aggregate reading or a summary, might be most useful.  This tutorial will walk through how to take multiple readings, aggregate them, and display a simple result on an LCD.

This setup has many applications, but this tutorial focuses on ideal environmental conditions for saplings and young plants.  With that in mind, temperature and humidity will be used as inputs, but the same approach could work with any other sensor.  Furthermore, this tutorial is part of a broader project that will utilize several more sensors measuring soil moisture, particulate matter, and soil pH among others, but for the sake of this post only humidity and temperature will be used.

In the first section, measurements will print directly to the LCD
screen.  Then, the second section will walk through the code to print a
summary or aggregate using the same wiring. Finally, the third section will walkthrough custom characters as an alternative method for displaying an aggregate.

Section 1 – Printing Measurement to an LCD

Parts

  • 1 x Arduino Uno Board
  • 1 x 830 tie-points Breadboard
  • 1 x LCD1602 modeul
  • 1 x Potentiometer (10k)
  • 16 x M-M wires
  • 1 x DHT11 Temperature and Humidity module
  • 3 x F-M wires

Wiring

The LCD1602 module has 16 pins and must be wired carefully. Orienting the LCD with the pins on top, from left to right:

  • VSS: Connects to the ground
  • VDD: Connects to a power supply (+5V)
  • VO: Controls the contrast of the LCD. This is connected to the potentiometer.
  • RS: Register Select, which connects to pin 7 in this tutorial and determines where the LCD memory is written.
  • RW: Read/Write that selects read or writing mode, connected to the ground here.
  • E: Enable, which directs the LCD module. Connected to pin 8.
  • D0-7: Pins that read and write data. In this tutorial D4-D7 will be connected to pins 9-12 of the board.
  • A: Controls the backlight, connected to the power supply.
  • K: Controls the backlight, connected to the ground.

The DHT11 Temperature and Humidity module must also be wired carefully. It has three relevant pins from left to right:

  • VDD: Connects to a power supply (3.5~5.5 V)
  • DATA: Connects to a pin on the Ardunio, in this case pin 2
  • NC: An empty pin not used in this tutorial and not included on all models of the DHT11
  • GND: Ground
Image 1: DHT, LCD, Arduino wiring

Code

This sketch is quite simple. It just takes a measurement using the DHT and prints it directly to the LCD. This utilizes the DHT library, which can be downloaded here.

Section 2 – Calculating an aggregate and displaying it on an LCD

Next, we will adjust the code, but use the same components and wiring in order to display an aggregate.

As mentioned above, this Arduino setup is to determine how suitable an environment is for a plant that requires a temperate climate.  The following tables show the ideal temperature and humidity for a sapling.

TemperatureCondition
<40°FDangerously Cold
40-59°FColder than optimal
60-79°FIdeal
80-90°FHotter than optimal
>90°FDangerously hot
Table 1: Temperature Conditions for Sapling
HumidityCondition
0-39%Too dry
40-69%Ideal
70-100%Too moist
Table 2: Humidity Conditions for Sapling

It might be most helpful to have an LCD readout that simply says how suitable the environment is based on the given conditions.  With that in mind, these variables are combined to form a health score out of 100.

In this example we will assume that temperature and humidity are equally important; therefore, we will calculate their sub-scores out of 50 such that when totaled the health score will be out of 100. If a third measure was included that was also considered of equal importance each sub-score would be out of 33, a fourth equally important measure would make each sub-score out of 25 and so on. If, however, sunlight, for example, is twice as important as temperature and humidity the weights would be adjusted such that sunlight accounts for half or 50 points, and the other two would be out of 25 each. Clearly, the formula is dependent on what you’re measuring and what you consider most important.

Code

The following code replaces the print outs of the temperature and humidity readings with a sentence stem “This environment is”. Then an if statement determines which word completes the sentence: ideal, decent, poor, or dangerous, depending on the health score. The health score is calculated using the following steps:

  • Since 65 degrees is the optimal temperature in this example, any measurement over 65 is subtracted from 130 in order to make the measurements linear from dangerous to ideal.
  • Similarly, optimal humidity is 55%, so all measurements over 55 are subtracted from 110.
  • Both are constrained from 0 to 65 for temperature and 0 to 55 for humidity to eliminate any negative values.
  • Then the resulting values are mapped from 0 to 50 and totaled to determine the health score.

Like the temperature and humidity ranges, the health score categories are somewhat arbitrary for the sake of this tutorial.

  • Ideal: health score > 50
  • Decent: 25 < health score 50
  • Poor: 10 < health score 25
  • Dangerous: health core 10

For an actual application of this device the categories would be much more intentional.

Example

Image 2: Condition displayed as statement

Section 3 – Using custom characters to display an aggregate

Finally, for a fun additional feature a face will be printed on the LCD
screen that represents the condition. Ultimately this device, with several more sensors, is intended to be mounted publicly to show the health of a young tree. In order to make the display accessible, the face will communicate with children and any non-english readers. Plus, a face is a bit more fun than a simple sentence.

Image 3: Fun faces!

Code

This sketch is far more complex than the first two sections since creating custom characters take quite a few lines of code. The first addition to this sketch from the last, are the byte definitions which write the shape of the custom character for the faces.

The faces consist of a several custom characters displayed consecutively on the LCD.  The custom characters are created using the generator here.  Essentially, each space on the LCD is an 8×5 array, and the byte definitions are arrays of eight strings – one for each row – of 0s or 1s. 0 keeps the cell off and 1 turns the cell on.

Since the LCD memory can only handle 8 custom characters at a time, the bytes are defined globally, but the characters are created in separate functions and a customclear function is necessary to wipe the memory of the LCD.

The health score is calculated just the same as in section 2, but instead of printing the sentence immediately, an if statement runs separate functions for each condition category.

Each condition category creates the custom characters based on the byte definitions and prints the face. The face is displayed for eight seconds before the sentence appears for two seconds.  The following faces are used for each category:

  • Ideal (health score > 50): Smile
  • Decent (25 < health score 50): Indifferent (flat mouth)
  • Poor (10 < health score 25): Frown
  • Dangerous (health core 10): Frown and X eyes

Example

Image 4: Condition displayed as a face and a statement

References

  • ELEGOO Lesson 11 – DHT11 Temperature and Humidity Sensor
  • ELEGOO Lesson 14 – LCD Display
  • DHT Sensor library – https://www.circuitbasics.com/how-to-set-up-the-dht11-humidity-sensor-on-an-arduino/
  • LCD custom character generator – https://maxpromer.github.io/LCD-Character-Creator/
  • Minov’s Custom Character walkthrough – https://minov.in/how-to-create-custom-character-for-lcd/
  • Custom Character memory clear function posted in the Arduino forum – https://forum.arduino.cc/t/why-the-8-character-limit-with-liquidcrystal/48650/4

Leave a Reply

Your email address will not be published. Required fields are marked *