Collect data from sensors using Raspberry Pi 4 model B.

George Soloupis
9 min readFeb 23, 2022

Written by George Soloupis ML GDE.

This is a tutorial on how to collect data from sensors with the help of a Raspberry single board computer. We will power it up, connect the cables, put the sensors on the breadboard and execute python scripts to collect the data and save them into a .csv file.

First power up the machine and install the Linux software.

With a small starter kit of the Raspberry Pi you will have the opportunity to power the single board computer up and get ready to use it in one hour. You will need:

  1. The Raspberry Pi
  2. A power supply
  3. A microSD card
  4. A keyboard, a mouse and an HDMI cable
  5. A computer screen

Optional extras:

  1. A case
  2. An ethernet cable

We are not going to share specific details of installing the OS into the Raspberry as there are numerous online tutorials online explaining with details the procedure. You can find one at the official guide here.

Second connect the 40 pins GPIO cable and the Wedge.

The magnificent thing about the Raspberry Pi is the 40 pins GPIO header.

Inputs and outputs of a Raspberry Pi model 4.

This header provides 2 of 5V outputs, 2 of 3,3V , 8 ground pins and a lot of General Purpose Input Output pins

GPIO Header pin numbers.

At the 40 pins GPIO header we can connect an extension cable, a wedge and a breadboard where we can put our final sensors.

Raspberry, extension cable and a wedge.

Breadboards are one of the most fundamental pieces when learning how to build circuits. Take some time to read the instructions and what is a breadboard so you can be fully prepared for the experiment.

Third use some very popular sensors to collect data.

One of the most popular sensors for single board computers is the DHT11 which is a basic, ultra low-cost digital temperature and humidity sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and spits out a digital signal on the data pin (no analog input pins needed).

DHT11 sensor

Specifications:

  • Operating Voltage: 3.5V to 5.5V
  • Operating current: 0.3mA (measuring) 60uA (standby)
  • Output: Serial data
  • Temperature Range: 0°C to 50°C
  • Humidity Range: 20% to 90%
  • Resolution: Temperature and Humidity both are 16-bit
  • Accuracy: ±1°C and ±1%

This sensor has 3 pins (VCC, Data, Ground). VCC is for power suply 3.5 to 5.5V, Data pin outputs both temperature and humidity through serial data and the last one is connected to the ground of the circuit.

Second sensor is the HC-SR04 which is an ultrasonic distance measuring sensor. It is a 4 pin module, whose pin names are Vcc, Trigger, Echo and Ground respectively. This sensor is a very popular sensor used in many applications where measuring distance or sensing objects are required. The module has two eyes like projects in the front which forms the Ultrasonic transmitter and Receiver. The sensor works with the simple high school formula that

Distance = Speed × Time

The Ultrasonic transmitter transmits an ultrasonic wave, this wave travels in air and when it gets objected by any material it gets reflected back toward the sensor this reflected wave is observed by the Ultrasonic receiver module.

HC-SR04 sensor

Specifications:

  • Operating voltage: +5V
  • Theoretical Measuring Distance: 2cm to 450cm
  • Practical Measuring Distance: 2cm to 80cm
  • Accuracy: 3mm
  • Measuring angle covered: <15°
  • Operating Current: <15mA
  • Operating Frequency: 40Hz

This sensor has 4 pins (VCC, Trigger, Echo, Ground). VCC for power supply 5V, Trigger pin is an Input pin that has to be kept high for 10us to initialize measurement by sending US wave, Echo pin is an Output pin that goes high for a period of time which will be equal to the time taken for the US wave to return back to the sensor and the last one is connected to the ground of the circuit.

Fourth connect the sensors to the breadboard and the Raspberry.

Below is the diagram where it is displayed how the DHT11 sensor is placed on the breadboard and it is connected to the Raspberry:

If the Data pin of the sensor is in the middle then the blue cable is going into the middle one and at GPIO4 of the Raspberry. VCC is connected with 3.3V and the GND to the similar one. This sensor has also a red LED so when you power it up you will see that the led is ON.

Then we have to install a library to use the sensor. You can see several tutorials that they are using

https://github.com/adafruit/Adafruit_Python_DHT.git

but inside the github repo it is stated that this library is deprecated. So we can go and use the CircuitPython library.

https://github.com/adafruit/Adafruit_CircuitPython_DHT.git

There is a superb example here that demonstrates how to install and use the sensor. You execute commands:

pip3 install adafruit-circuitpython-dht

and

sudo apt-get install libgpiod2

and after that you are ready to use python code to get info frome the sensor. Inside the Raspberry you can use directly the terminal or one of the Python IDEs that come pre-installed inside the single board computer. I prefer the Thonny Python IDE. So open a datasheet at the IDE and write:

import time
import datetime
import board
import adafruit_dht
import RPi.GPIO as gpio

# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT11(board.D4, use_pulseio=False)

filename = "temp_log.csv"

# Create header row in new CSV file
csv = open(filename, 'w')
csv.write("Timestamp,Temperature\n")
csv.close

for i in range(4):
try:
# Print the values to the serial port
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = dhtDevice.humidity
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)

temp_c = str(temperature_c)
entry = str(datetime.datetime.now())
entry = entry + "," + temp_c + "\n"

# Log (append) entry into file
csv = open(filename, 'a')
try:
csv.write(entry)
finally:
csv.close()

except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just # keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
dhtDevice.exit()
raise error

time.sleep(2.0)

#print csv
csv = open(filename, 'r')
print(csv.read())
csv.close()

#cleanup gpio
gpio.cleanup()

At the above code you have to pay attention to:

A. We use board.D4 to tell the library that the data cable is connected to GPIO 04 of the board.

B. use_pulseio=False is used as this is neccessary for the Raspberry Pi.

C. We use a csv file with a specific name that values are stored as they are fetched from the sensor. When the for loop stops we print all the saved values.

D. Errors happen fairly often, DHT’s are hard to read so we exit the device and we start again reading.

E. Finally we clean up the GPIO.

The .csv will be like this:

Temp: 60.8 F / 16.0 C    Humidity: 68%
Temp: 60.8 F / 16.0 C Humidity: 67%
Temp: 60.8 F / 16.0 C Humidity: 67%
Temp: 60.8 F / 16.0 C Humidity: 67%
Timestamp,Temperature
2022-02-22 09:20:58.192588,16
2022-02-22 09:21:00.567850,16
2022-02-22 09:21:02.939780,16
2022-02-22 09:21:05.311523,16

Below is the diagram where it is displayed how the HC-SR04 sensor is placed on the breadboard and it is connected to the Raspberry:

There are four pins on the ultrasound module that are connected to the Raspberry. Follow the pins number also if your Raspberry has 40 pins GPIO:

  • VCC to Pin 2 (VCC)
  • GND to Pin 6 (GND)
  • TRIG to Pin 12 (GPIO18)
  • connect the 330Ω resistor to ECHO. On its end you connect it to Pin 18 (GPIO24) and through a 470Ω resistor you connect it also to Pin6 (GND).

We do this because the GPIO pins only tolerate maximal 3.3V. The connection to GND is to have a obvious signal on GPIO24. If no pulse is sent, the signal is 0 (through the connection with GND), else it is 1. If there would be no connection to GND, the input would be undefined if no signal is sent (randomly 0 or 1), so ambiguous.

Open a new python script and place code:

# import libraries
import RPi.GPIO as GPIO
import time

#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)

#set GPIO Pins
GPIO_TRIGGER = 18
GPIO_ECHO = 24

#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

def distance():
# set Trigger to HIGH
GPIO.output(GPIO_TRIGGER, True)

# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)

StartTime = time.time()
StopTime = time.time()

# save StartTime
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()

# save time of arrival
while GPIO.input(GPIO_ECHO) == 1:
StopTime = time.time()

# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2

return distance

if __name__ == '__main__':
try:
while True:
dist = distance()
print ("Measured Distance = %.1f cm" % dist)
time.sleep(1)

# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()

Executing it you will have results every 1 second:

Measured Distance = 18.1 cm
Measured Distance = 19.5 cm
Measured Distance = 18.1 cm
Measured Distance = 18.1 cm
Measured Distance = 19.0 cm
Measured Distance = 18.2 cm
...

At the above code you have to pay attention to:

A. We are setting GPIO mode to BCM.

The GPIO.BOARD option specifies that you are referring to the pins by the number of the pin on the plug .

The GPIO.BCM option means that you are referring to the pins by the “Broadcom SOC channel” number.

Check above diagram with GPIO pin numbers.

B. We are setting GPIO pin 18 to OUT and GPIO pin 24 to IN.

C. Finally we clean up the GPIO.

You can find a marvelous explanation of how the sensor works at this article.

If you want to combine both sensors (DHT11 and HC-SR04) then the setup will be like this:

Combining the 2 sensors on the breadboard.

Both sensors are wired the exact same way we talked before using VCC, GND and GPIO04 for DHT11 while for the other sensor GPIO18 and 24.

At last we created a script that gets the values from both sensors and stores it inside a .csv file:

# Combine 2 sensors
# first get temperature and humidity
# second get distance
import time
import datetime
import board
import adafruit_dht
import RPi.GPIO as GPIO

#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)

#set GPIO Pins
GPIO_TRIGGER = 18
GPIO_ECHO = 24

#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT11(board.D4, use_pulseio=False)

# give a name to csv file
filename = "temp_log.csv"

# Create header row in new CSV file
csv = open(filename, 'w')
csv.write("Timestamp,Temperature,Humidity,Distance\n")
csv.close

def get_values_from_two_sensors():
# Get the value from DHT11 sensor.
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = dhtDevice.humidity

# Get distance from HC-SR04
# set Trigger to HIGH
GPIO.output(GPIO_TRIGGER, True)

# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)

StartTime = time.time()
StopTime = time.time()

# save StartTime
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()

# save time of arrival
while GPIO.input(GPIO_ECHO) == 1:
StopTime = time.time()

# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2

temp_c = str(temperature_c)
humid = str(humidity)
entry = str(datetime.datetime.now())
dist = str(distance)
entry = entry + "," + temp_c + "," + humid + "," + dist + "\n"

# Log (append) entry into file
csv = open(filename, 'a')
try:
csv.write(entry)
finally:
csv.close()

return entry



if __name__ == '__main__':
try:
while True:
values = get_values_from_two_sensors()
print (values)
time.sleep(2.0)

except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just # keep going
print(error.args[0])
time.sleep(2.0)

except Exception as error:
dhtDevice.exit()
raise error
#continue

except KeyboardInterrupt:
# Reset by pressing CTRL + C
print("Measurement stopped by User")
# read the csv
csv = open(filename, 'r')
print(csv.read())
csv.close()
# clean up
GPIO.cleanup()

Conclusion

An introduction project that uses 2 really simple sensors on a breadboard that is connected to a Raspberry Pi model 4. The single board computers are really handy and with the 40 pin GPIO header are ready to be used for many purposes from simple projects to AI/ML ones. Stay tuned for more sophisticated solutions using Machine Learning at these embedded devices.

--

--

George Soloupis

I am a pharmacist turned android developer and machine learning engineer. Right now I’m a senior android developer at Invisalign, a ML & Android GDE.