Reader small image

You're reading from  Practical Python Programming for IoT

Product typeBook
Published inNov 2020
Reading LevelIntermediate
PublisherPackt
ISBN-139781838982461
Edition1st Edition
Languages
Right arrow
Measuring Temperature, Humidity, and Light Levels

In the previous chapter, we explored two methods of making color with RGB LEDs – using a common RGB LED and with an addressable APA102 RGB LED strip. We also learned how to use a simple OLED display and how PWM can be used to play music using a passive buzzer.

In this chapter, we will be looking at some common components and circuits for collecting environmental data, including temperature, humidity, whether it's dark or light, and how to detect moisture.

The circuits and code examples we will learn will be useful for building and experimenting with your own environmental monitoring projects. These circuits can be considered input or sensor circuits that measure environmental conditions. By way of example, you could combine the circuit ideas and examples from Chapter 7, Turning Things On and Off, to switch on a pump...

Technical requirements

To perform the exercises in this chapter, you will need the following:

  • Raspberry Pi 4 Model B
  • Raspbian OS Buster (with desktop and recommended software)
  • Minimum Python version 3.5

These requirements are what the code examples in this book are based on. It's reasonable to expect that the code examples should work without modification on Raspberry Pi 3 Model B or a different version of Raspbian OS as long as your Python version is 3.5 or higher.

You will find this chapter's source code in the chapter09 folder in the GitHub repository available at https://github.com/PacktPublishing/Practical-Python-Programming-for-IoT.

You will need to execute the following commands in a terminal to set up a virtual environment and install the Python libraries required for the code in this chapter:

$ cd chapter09              # Change into this chapter's folder
$ python3 -m venv venv # Create Python Virtual Environment
$ source venv/bin/activate...

Measuring temperature and humidity

The measurement of temperature and related environmental properties is a common task, and there are many different types of sensors available for measuring these properties, including thermistors (a temperature-dependent resistor), sophisticated breakout modules that connect via SPI and I2C, and sensor varieties such as the DHT11 or DHT22 sensors, which we will be using for our example.

All sensors have their relative strengths and weaknesses when it comes to accuracy, response times (how fast we can rapidly get data from them), and cost.

DHT sensors, as illustrated in Figure 9.1, are inexpensive, durable, and easy to use:

Figure 9.1 – DHT11 and DHT22 temperature and humidity sensors

The DHT11 is a very common low-cost sensor. The DHT22 is its higher-accuracy cousin. Both are pin-compatible and will be suitable for our example. The pinouts of these sensors as illustrated in the preceding figure are as follows:

  • Vcc: 3- to 5-volt power source...

Creating the DHT11/DHT22 circuit

We will begin by creating the circuit illustrated in Figure 9.2 on our breadboard:

Figure 9.2 – DHT sensor schematic

The following is the breadboard layout for this circuit that we are about to build:

Figure 9.3 – DHT sensor circuit

Here are the steps to follow, which match the numbered black circles in Figure 9.3:

  1. Place your DHT11 or DHT22 sensor into your breadboard.
  2. Place the 10kΩ resistor (R1) into the breadboard. One end of the resistor shares the same row as the DHT sensor's DATA pin. We will discuss this resistor and why it's marked as optional in Figure 9.2 after we complete the circuit build.
  3. Connect a 3.3-volt pin on your Raspberry Pi to the positive rail of the power rail.
  4. Connect the 10kΩ resistor (R1) to the positive power rail.
  5. Connect the DHT Vcc pin to the positive power rail.
  6. Connect a GND pin on your Raspberry Pi to the negative power rail.
  7. Connect the GND pin on...

Running and exploring the DHT11/DHT22 code

Run the code found in the chapter09/dht_measure.py file, and the measured temperature and humidity will be printed to your terminal, similar to the following:

(venv) python DHT_Measure.py
{'temp_c': 21, 'temp_f': 69.8, 'humidity': 31, 'valid': True}

Here, we have the following:

  • temp_c is the temperature in degrees Celsius.
  • temp_f is the temperature in degrees Fahrenheit.
  • humidity is the relative humidity percentage.
  • valid indicates whether the reading is considered valid by way of an internal sensor checksum check. Readings where value == False must be abandoned.

The code in the source file is concise and is fully replicated here.

In line 1, we import the DHT sensor library and instantiate it in line 2. Update the line to match the DHT11 or DHT22 sensor you are using:

from pigpio_dht import DHT11, DHT22   # (1)

SENSOR_GPIO = 21
sensor = DHT11(SENSOR_GPIO) # (2)
#sensor = DHT22(SENSOR_GPIO...

Detecting light

Detecting the presence or absence of light is easily achieved with a special type of resistor known as an LDR. LDRs are a low-cost light sensor, and we find them in many applications, from light-activated switches and lamps or as part of the circuit that dims your alarm clock display when it's dark, to part of alarm circuits on cash boxes and safes.

You may also find LDRs referred to as photoresistors or photocells.

The following figure shows a typical LDR component, together with a few varieties of LDR schematic symbols. If you examine the symbols, you will notice that they are a resistor symbol with inward-pointing arrows. You can think of these arrows as representing light falling on the resistor:

Figure 9.4 – A physical LDR component and a variety of schematic symbols

An LDR varies its resistance with the relative light it detects. If you placed the terminals of your multimeter in Ohms mode across an LDR, you will find (roughly after a few seconds...

Creating an LDR light-detecting circuit

As discussed, an LDR varies its resistance in relation to the relative light it detects. To detect varying resistance with our Raspberry Pi, we need to take a few steps that were covered in previous chapters:

  • We need to turn the varying resistance into a varying voltage because our Raspberry Pi GPIO pins work on voltage, not resistance. This is an application of Ohms law and a voltage-divider circuit, which we learned about in Chapter 6, Electronics 101 for the Software Engineer.
  • Our Raspberry Pi GPIO pins can only read digital signals – for example, a high (~3.3 volts) or low (~0 volts) signal. To measure a varying voltage, we can attach an Analog-to-Digital Converter (ADC) such as an ADS1115. We covered the ADS1115 and accompanying Python code in Chapter 5, Connecting Your Raspberry Pi to the Physical World.

We are about to create the circuit illustrated in Figure 9.5 on your breadboard. This circuit and the accompanying code...

Running the LDR example code

We are about to run two programs:

  • chapter09/ldr_ads1115_calibrate.py, which will help us calibrate our LDR readings
  • chapter09/ldr_ads1115.py, which monitors the light level and switches on the LED when the light falls below a configurable level

First, we should check that the ADS1115 is connected correctly and can be seen by your Raspberry Pi. Run the i2cdetect command in a Terminal. If your output does not include a number (for example 48), then please verify your wiring:

$ i2cdetect -y 1
# ... truncated ...
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# ... truncated ...
We first covered the ADS1115 analog-to-digital converter and the i2cdetect utility in Chapter 5, Connecting Your Raspberry Pi to the Physical World.

Let's run the examples, starting with the calibration program:

  1. Run the code found in the chapter09/ldr_ads1115_calibrate...

LDR code walkthrough

A bulk of the code in both chapter09/ldr_ads1115_calibrate.py and chapter09/ldr_ads1115_calibrate.py is the boilerplate code to set up and configure the ADS1115 and set up the LED using PiGPIO. We will not recover the common code here. If you need a refresher on the ADS1115-related code, please review the exercise found in Chapter 5, Connecting Your Raspberry Pi to the Physical World.

Let's look at the Python code that makes our LDR work.

In line 1, we see that we are importing the ldr_calibration_config.py file that we created with our calibration program previously.

Next, in line 2, we are assigning the calibration values to the LIGHT_VOLTS (the voltage detected by the ADS1115 when the LDR was in the light) and DARK_VOLTS (the voltage detected when you covered up the LDR) variables:

import ldr_calibration_config as calibration                   # (1)

# ... truncated ...

LIGHT_VOLTS = calibration.MAX_VOLTS ...

LDR configuration summary

You may have realized while working with the LDR circuit and code that there are a few tunable parameters that influence how the circuit and code work, and did you wonder why we used a 10kΩ resistor?

No two LDRs will give the same resistance-to-light measurement and their resistance-to-light range is not linear. The implication of this is that your LDR, plus the lighting conditions you plan to use it in, can influence a suitable fixed resistor value.

Here is a rough guide to selecting an appropriate fixed resistor:

  • If you want the LDR to be more sensitive in darker conditions, use a higher value resistor (for example, try 100kΩ).
  • If you want your LDR to be more sensitive in brighter conditions, use a lower value resistor (for example, try 1kΩ).

Remember that these are just suggestions, so feel free to try different resistances for your own needs. Plus, whenever you change the value of the fixed resistor,...

Detecting moisture

Guess what...we have already done the grunt work to detect moisture! It's just another application of the LDR circuit and code, only we replace the LDR with probes.

For this exercise, you can create a set of probes using two pieces of wire (with the ends stripped), and attach them in place of the LDR, as shown in Figure 9.8. This is the same circuit we built in the previous section and showed in Figure 9.7, only this time, we have replaced the LDR with two wires. Let's make this slight change now:

Figure 9.8 – Moisture detection circuit

Here are the steps to follow, which match the numbered black circles in Figure 9.8:

  1. Remove the LDR from the breadboard.
  2. Place a wire (with both ends stripped) into a breadboard row that previously connected to one of the LDR's legs (in the illustration, this new wire connects back to 3.3 volts on your Raspberry Pi).
  3. Place another wire (with both ends stripped) into a breadboard row that previously...

Comparing detection options

How do our simple circuit and wire probes compare to a water/moisture detection module that you can find on retail sites such as eBay? These products typically contain a probe of some sort, plus a small electronic module. A picture of one of these modules, plus a few probes, are shown here:

Figure 9.9 – Moisture detection module and probes 

The three probes pictured each have two terminals and are simply an exposed copper trace on a circuit board, analogous to the exposed wires we saw in our circuit in Figure 9.8. A key difference is that these probes expose a larger surface area and are therefore more sensitive. Furthermore, they are also likely to be less prone to corrosion (at least in the short-to-medium term) than two stripped wires.

You can connect these probes directly to the exposed wires in our circuit shown in Figure 9.8 to expand and enhance the detection capabilities of the circuit!

Let's discuss the electronic...

Summary

In this chapter, we learned how to measure temperature and humidity using the common DHT11 and/or DHT22 sensors. We also looked at how to use an LDR to detect light, and this allowed us to explore voltage divider circuits and ADCs in greater detail. We concluded by retrofitting our LDR circuit so that we could detect moisture.

The example circuits and code we covered in this chapter provide practical examples of measuring environmental conditions with readily available sensors and simple circuits. Your understanding of these sensors and circuits now means you can adapt the examples for your own environmental monitoring projects, including using them as input triggers together with Python to control other circuits.

We also saw new practical applications of voltage divider circuits and how they are used in analog circuits to turn variable resistance into a variable voltage for use with an ADC. These examples and your understanding of them represent an important skill that you...

Questions

As we conclude, here is a list of questions for you to test your knowledge of this chapter's material. You will find the answers in the Assessments section of the book:

  1. Can you list two differences between a DHT11 and DHT22 temperature and humidity sensor?
  2. Why is the external 10kΩ pull-up resistor optional in our DHT11/22 circuit?
  3. Describe the basic electronic principle used with an LDR to measure light.
  4. How can you make an LDR more or less sensitive to certain lighting conditions?
  5. You have created an LDR circuit and calibrated the Python code. Now, you change the LDR and find that the voltages readings and in-code trigger point behave slightly differently. Why? 
  6. Why does placing two wires in water work as a basic moisture detector when used with a voltage divider and ADS1115 circuit?
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Practical Python Programming for IoT
Published in: Nov 2020Publisher: PacktISBN-13: 9781838982461
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime