Experimenteren met een Arduino DHT 11 temperatuur en luchtvochtigheids sensor |
Datum: Mei 2024
Inleiding:
Experimenteren met Arduino en een eenvoudige sensor. Het primaire doel van dit experiment is het grafisch weergeven van de gemeten waardes in dit geval temperatuur en relatieve vochtigheid op een relatieve tijdschaal. |
Materiaal en uitvoering:
|
|
DHT 11
basic temperature-humidity sensor |
Uitvoering:
|
|
// Example
testing sketch for various DHT humidity/temperature sensors // Written by ladyada, public domain // Modified by Ruud Herold in September 2020 // REQUIRES the following Arduino libraries: // - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library #include "DHT.h" #define DHTPIN 2 // Digital pin connected to the DHT sensor #define DHTTYPE DHT11 // DHT 11 being used // Connect pin 1 (on the left) of the sensor to +5V // Connect pin 2 of the sensor to whatever your DHTPIN is // Connect pin 4 (on the right) of the sensor to GROUND // Initialize DHT sensor. DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); Serial.println(F("DHTxx test!")); dht.begin(); } void loop() { // Wait a few seconds between measurements. delay(2000); // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) float h = dht.readHumidity(); // Read temperature as Celsius (the default) float t = dht.readTemperature(); // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t) ) { Serial.println(F("Failed to read from DHT sensor!")); return; } Serial.print(F("Humidity: ")); Serial.print(h); Serial.print(F("% Temperature: ")); Serial.print(t); Serial.print(F("°C\r\n ")); // \r\n --> carriage return, line feed } |
|
|
|
// Example testing sketch for various DHT humidity/temperature
sensors |
|
|
Het schakelschema voor het LCD scherm: |
// REQUIRES the following Arduino libraries: //- "LiquidCrystal", "DHT_sensor_library" and "Adafruit_Sensor-master" // Libraries #include "DHT.h" #include <LiquidCrystal.h> // DHT11 Sensor #define DHTPIN 12 // Digital pin connected to the DHT sensor #define DHTTYPE DHT11 // DHT 11 DHT dht(DHTPIN, DHTTYPE); // LCD Dislay (LCD1602 Module) // Create an LCD object. Parameters: (RS, E, D4, D5, D6, D7): // Note: do not connect to 0 or 1, that creates gibberisch characters on the LCD LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7); void setup() { // LCD Display lcd.begin(16, 2); // LCD Display (Temp and Humidity) lcd.clear(); lcd.setCursor(0,0); lcd.print("Temp:"); lcd.setCursor(0,1); lcd.print("Humid:"); delay(1500); // DHT11 start Serial.begin(9600); dht.begin(); // Labels for Serial plotter while(!Serial); Serial.println("Temperature Humidity"); } void loop() { // Wait 2 seconds between measurements. delay(2000); // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) float h = dht.readHumidity(); // Read temperature as Celsius (the default) float t = dht.readTemperature(); // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } // LCD Display (Temp and Humidity) lcd.setCursor(10,0); lcd.print("oC"); lcd.setCursor(10,1); lcd.print("%"); // LCD Display (values), without decimals lcd.setCursor(7,0); lcd.print(t,0); lcd.setCursor(7,1); lcd.print(h,0); // Serial Plotter with labels Serial.print(t); Serial.print("\t"); Serial.println(h); } |
|
Het pythonprogramma kan men downloaden via de link: DHT11_plottingV3.py |
Resultaten:
Test 1: |
Testen van de sensor m.b.v. het geleverde voorbeeld en de serial monitor. |
|
|
Weergeven van de resultaten op de serial plotter. |
|
Weergeven
van de resultaten op het LCD scherm. |
De output van het Python programma |
Interactie aan het begin van het programma en rapportage eerste resultaten |
Het real-rime dta plotting window |
De grafiek die alle verzamelde data weergeeft. |
De eindrapportage in het terminal window. |
Die ook opgeslagen wordt in een tekstfile. |
Alle data wordt ook opgeslagen in een csv file. |
|
Discussie:
Voor mij was dit een leuk experiment om mijn programmeren weer eens te oefenen. Daarnaast wilde ik een basis pakket opbouwen dat ik kan gebruiken als ik andere sensoren aan een arduino wil koppelen. |
Opmerkingen:
|
Literatuur:
Relevante websites:
Minder relevante websites: |
Achtergrondinformatie: |
|
Arduino
Arduino is een open source computer platform (printplaat, computer) bedoeld voor iedereen die geïnteresseerd is in het maken en ontwerpen van objecten die kunnen reageren op hun omgeving, door het aansluiten van allerlei sensoren en actuatoren op de Arduino. Via de sensoren kan digitale en analoge inputsignalen genereren die door de Arduino verwerkt worden en dan weer een actie kunnen initiëren door het afgeven van digitale en analoge outputsignalen. Input kan bijvoorbeeld worden gegenereerd door schakelaars, lichtsensoren, bewegingsmeters, afstandsmeters, temperatuursensoren, of op basis van commando's afkomstig van internet, een radiomodule of een ander apparaat met een seriële interface. Outputsignalen kunnen bijvoorbeeld motoren, lampjes, pompjes en beeldschermen aansturen, maar ook input genereren voor een andere Arduino module. Op de Arduino kan men zogenaamde
"shields" zetten door dezen op de input-/outputpinnen van de
Arduino te plaatsen. Deze shields kunnen bv extra functie
toevoegen of verschillende sensoren en modules in één
printplaat combineren. Het meest bekende shield is het
ProtoShield dat dienst doet als breadboard, om op te
experimenteren. |
|
Toevoegen Library aan Arduino | |
|
|
|
|
|
|
Python code (indentation is verloren gegaan) | |
# Project: read data and display
it from Arduino equipped with a DHT11 sensor # Note: ensure that only Pyserial is installed. If serial is installed also, uninstall it import serial import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator, FormatStrFormatter import time import keyboard from datetime import datetime import csv import statistics def main(): # ----------------------SET UP COMMUNICATION WITH ARDUINO--------------------- # Replace 'COMX' with the apropriate COM port name on your system arduino = serial.Serial('COM5', 9600) # Confirm which port is used print("Serial Port: " + arduino.name) # ask for measurement interval interval = input("Time between measurements in s (mininimum is 2)? ") print("Program reads and displays data every "+ interval + " s") # print("Press q to stop the program") print("Use CTRL-C or press q to stop the program"'\n') # Read data from the serial port arduino.close() arduino.open() # ----------------------------------- SET UP DATA STORAGE -------------------------- # create lists for data temperature_list= [] humidity_list=[] time_list=[] # create a csv file for storage of the collected data # get current date and time current_datetime = datetime.now().strftime("%Y%m%d_%H%M") print("Current date & time : ", current_datetime) # convert datetime obj to string str_current_datetime = str(current_datetime).lstrip() date = str_current_datetime[0:8] # create a file object along with extension file_name = str_current_datetime + ".csv" file = open(file_name, 'w', newline='') data_file = csv.DictWriter(file, fieldnames=["date", "time", "temperature", "humidity"]) data_file.writerow({"date": "Date", "time": "Time", "temperature": "Temperature (°C)", "humidity": "Humidity (%)"}) # ---------------------------- SET UP REAL TIME DATA PLOTTING WINDOW ------------------- plt.style.use('ggplot') fig_w, (ax1,ax2) = plt.subplots(nrows=2, ncols=1, sharex=True) i=0 # ------------------------------ READ AND STORE DATA --------------------------- # ---------------------------- WITHIN AN INFINITE LOOP ------------------------- # ----------------------- INCORPORATES ACTIONS TO STOP THE LOOP ----------------- try: while True: data = arduino.readline() # data as such is unreadable, needs to be decoded and assigned data2 = data.decode() items = data2.split() temperature = round(float(items[0]),1) humidity = round(float(items[1]),1) # add the time of measurement now = datetime.now() current_time = now.strftime("%H:%M:%S") # print data in terminal print ("Date: ", date, "Time: ", current_time, " Temperature: " + str(temperature) + " oC ", "Humidity: " + str(humidity) + " %") # store the data in the lists time_list.append(current_time) temperature_list.append(temperature) humidity_list.append(humidity) # store the data in the file data_file.writerow({"date": date, "time": current_time, "temperature": temperature, "humidity": humidity}) # Plot in a time window real time data ax1.plot(time_list, temperature_list, color='r') ax2.plot(time_list, humidity_list, color='b') fig_w.canvas.draw() ax1.set_title('Plotting sensor data in real time') # plt.ylabel('Temperature (°C)') ax2.set_xlabel('Time (hh:mm:ss)') ax1.set_ylabel('Temperature (°C)') ax2.set_ylabel('Humidity (%)') ax2.tick_params(axis='x', labelrotation=90) ax1.set_xlim(left=max(0,i-18), right=i+1) ax2.set_xlim(left=max(0,i-18), right=i+1) plt.tight_layout() fig_w.show() plt.pause(0.001) # not sure why we need this to make the window active i+=1 # Sleep for the specified seconds time.sleep(int(interval)) # press q to stop the program if keyboard.is_pressed("q"): print('Program stopped by pressing q(uit)'+ '\n') Plot_all_data(time_list, temperature_list, humidity_list) Evaluate_data(time_list, temperature_list, humidity_list, interval, current_datetime) file.close() break except KeyboardInterrupt: # use CTRL-C to stop the program print ('Program stopped by CTRL-C' + '\n') Plot_all_data(time_list, temperature_list, humidity_list) Evaluate_data(time_list, temperature_list, humidity_list, interval, current_datetime) file.close() # ------------- FUNCTION FOR PLOTTING ALL DATA COLLECTED ---------------------- def Plot_all_data(time_list, temperature_list, humidity_list): # data to be plotted x_values = time_list y_values = temperature_list y2_values = humidity_list # dimensions and markup of plot) fig, ax1 = plt.subplots(figsize=(8, 8)) ax2 = ax1.twinx() # ensures both y-axes are aligned ax1.set_title('Plotting collected Sensor Data', weight='bold', fontsize=20) ax1.set_xlabel('Time (HH:MM:SS)',weight='bold', fontsize=15) ax1.tick_params(axis='x', labelrotation=90) ax1.yaxis.label.set_color('red') ax2.yaxis.label.set_color('blue') ax1.set_ylabel('Temperature (°C)', weight='bold', fontsize=15) ax2.set_ylabel('Humidity (%)', weight='bold', fontsize=15) # set a grid pattern applicable to both axes ax1.set_ylim([0, 50]) ax2.set_ylim([0, 100]) ax1.grid(which = 'major', color = 'green', linestyle = '--', linewidth = 0.5) ax2.grid(which = 'major', color = 'green', linestyle = '--', linewidth = 0.5) plt.grid(True) # plot the plot, autoscale the x-axis and show it ax1.xaxis.set_major_locator(MultipleLocator(20)) ax1.plot(x_values, y_values, 'ro-') ax2.plot(x_values, y2_values, 'b^-') plt.tight_layout() plt.show() # ------- FUNCTION FOR CALCULATING SOME DATA CHARACTERISTICS ------------------ def Evaluate_data(time_list, temperature_list, humidity_list, interval, current_datetime): # Calculate some statistical data, display it and store it in a text file # Create a text file and write the data to the text file as well as the console # create a file object along with extension O_file_name = current_datetime + ".txt" O_file = open(O_file_name, 'w') O_file.write('Analysis of data collected\n') print('Analysis of data collected') # calculate basic statistical data Mean_T = ('Mean Temperature (°C): '+ str(round(statistics.mean(temperature_list),2))) O_file.write(str(Mean_T) + '\n') print(Mean_T) Sd_T = ('Standard deviation Temperature (°C): '+ str(round(statistics.stdev(temperature_list),2))) O_file.write(str(Sd_T) + '\n') print(Sd_T) Mean_H = ('Mean Humidity (%): ' + str(round(statistics.mean(humidity_list),2))) O_file.write(str(Mean_H) + '\n') print(Mean_H) Sd_H = ('Standard deviation Humidity (%): ' + str(round(statistics.stdev(humidity_list),2))) O_file.write(str(Sd_H) + '\n') print(Sd_H) Elem_List = len(time_list) Data_Points = str('A total of ' + str(Elem_List) + ' data points were collected with a ' + str(interval) + ' s interval') O_file.write(Data_Points + '\n') print(Data_Points) #close the file O_file.close() if __name__ == "__main__": main() |