2: Writing to a CSV file (DHT22 data)
- Page ID
- 434772
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)In this activity you will read temperature and humidity data from a DHT22 sensor and post them to a csv file along with the time of the reading. If you are not familiar with the DHT22 you will need to check the following two links, where we go over how it works, and how to set it up to collect data.
- DHT22: Temperature and Humidity Sensor - description on how DHT22 works
- DHT22: Streaming Temperature and Humidity Data - Instructions on how to set up the DHT 22 sensor
Checking DHT22 Setup
Run the following code in Thonny
#!/usr/bin/python3 #Import the modules import time import board import adafruit_dht #Declare the sensor and the GPIO pin it is connected to dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False) while True: try: # Print the values to the serial port tempC = dhtDevice.temperature humidity = dhtDevice.humidity print(f"Temp: {tempC} C Humidity: {humidity}% ") time.sleep(10.0) #pause for 10 seconds except RuntimeError: pass
or alternatively, type the following code into the command line (you will need to use the path to the file on your computer, and be sure the program is executable and has a shebang that identifies the interpreter
/home/pi/Programs//DHT22/DHT22_1.py
What this code is doing is printing the temperature and time every 2 seconds
Now that we know the sensor is reading data correctly we need to put the data into a file so that it can be used.
Writing to CSV File
CSV (comma separated variable) are one of the most common types of data files, and are the kinds of files Excel and Google Docs work with. These are not files that are read by python in the sense that they are a data type that python works with. But you can generate these (write) with the python inFile.write command, and in a latter exercise we will see how to read a CSV file by converting its content into a datatype that Python can work with, like a list.
Before running the following code save it in your folder for this exercise and then look at the contents of that folder (you can do this with the "ls" command, or using the desktop file manager). Then run this program and look again at the content of the folder. You should see a new file appear called "DHTtemperatures.csv". Right click on this and choose "text editor" (note, if you installed LibreOffice and click on the file it will open in LibreCalc, which is an open source program like Excel.
import datetime from time import sleep import board import adafruit_dht def getValues(): dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False) for i in range(0,5): try: humidity = dhtDevice.humidity temperature = dhtDevice.temperature except RuntimeError as error: print(error.args[0]) sleep(2.0) continue except Exception as error: dhtDevice.exit() raise error if humidity is not None and temperature is not None: return (humidity, temperature) inFile= open("DHTtemperatures.csv","w") inFile.write("time,humidity,temperature\n") for x in range(0,10): humidity,temperature = getValues() now = datetime.datetime.now().strftime("%H:%M:%S") inFile.write('%s,%s,%s\n' %(now,humidity,temperature)) sleep(2) #note the DHT22 does not read faster than this print(x) inFile.close()
Questions
What is the role of the for loop in the function getValues()?
- Answer
-
This is assigning humidity and temperature values to the variables humidity and temperature. If the value returned is not valid it retries 5 times. This is important in working with sensor readings as you need checks to be sure the data you are transferring is real data.
What does the following line of code do?
inFile=open(DHTtemperatures.csv","w") do? If the file already exists, what happens to the data?
- Answer
-
This creates the file DHTtemperatures.csv and clears out all data if there was data in the file.
What does the following line of code do?
inFile.write("time,humidity,temperature\n")
- Answer
-
It inserts into the CSV file the headings of time, humidity and temperature. The \n generates a new line.
Where in the code are the variables assigned values, what is the variable for time and why is its assignment executed after the variables humidity and temperature are assigned values?
- Answer
-
They are assigned in the for loop. The variables humidity and temperature are assigned values by calling the function getValues(). The variable for time is now and it is called after the function getValues() has returned a value. If you look at the function getValues() you see a loop with up to 5 iterations, depending on if a valid value is returned. So the time delay could be 0,2,4,6,8 seconds. By getting the time after the value is returned we are certain the time is correct, and so our plot will be correct, although the data values may not be evenly spaced. If 5 bad values are returned you have a serious problem and may need to check your wiring,
Change the range of the loop from 10 to 5 iterations and run the code. Before looking at the file, how many values to you expect to be generated?
- Answer
-
You will see 5 data values plus the title. You are writing a new file ('w'), not overwriting the original data
Change the "w" of the infile= open( ) statement to an "a" and change the 5 in the range of the loop back to 10. Run the code. What happens, how many lines of data do you see, and what does "a" stand for?
- Answer
-
"a" stands for append, and you are now adding data to the file, and will have 15 rows of data. Note, since you ran the program twice you generated the title twice.
temporary stuff
Spod1Backup = open("openspod1backup.csv","a") #Spod1Backup.write("\n") Spod1Backup.write(str(values)[1:-1]) Spod1Backup.write("\n") Spod1Backup.close()