Arduino Humidity Sensor Raspberry Pi Server - dtredger/RaspberryPI GitHub Wiki

Over the last few weeks, I’ve developed a hunch that my apartment is really dry. Since I grew up in a mild climate a few blocks from the ocean, low humidity isn’t something I’ve ever thought about.

I had this Arduino sitting around, unused, and I decided this could be a good use for it. (I finally put my raspberry Pi to use, as a web server: see the site it hosts).

This is the easiest-possible thing I think you could do with it, besides the LED-blinking tests, which is probably good.

The sole component, besides the Arduino board, a breadboard, and three short wires, is a DHT22 Temperature and Humidity sensor, which is around $10.

There are two elements to this project (in somewhat-variable order):

  • Build the circuit
  • Upload the correct software onto the Arduino board

Building the circuit is simple, but unless you know what each pin on the little sensor you bought already does (how?), requires documentation. There’s a record of this exact project on fritzing.org That can show you how the circuit should look. I omitted the second wire to ground, since that site says it isn’t necessary.

The second element is the software. The sketch that needs to be uploaded is also linked to from the Fritzing.org site (under downloads on the sidebar), as AM2302_3.ino.

If you verify that in the Arduino program, it will probably give you an error, since that sketch relies on a library you must download. That part is non-obvious, I think.

You can download the DHT library from Adafruit on github. This should be placed in the libraries directory of your Arduino directory. For certainty, my directories in OS X appear as follows:

/Documents/Arduino
	/dht11
		dht11.ino
	/libraries
		/DHT
			DHT.cpp
			DHT.h

Now you should be able to verify and upload your sketch to the Arduino without issue. Once done, click the serial monitor button in the top-right of your Arduino program. If the circuit is assembled correctly, you should start to see humidity and temperature start to print out, like:

Humidity: 19.60 %	Temperature: 21.70 C
Humidity: 19.60 %	Temperature: 21.70 C

Do more with the Output

As it turns out, the Arduino program’s Serial Monitor isn’t magic, and you can access the same kind of thing from the command-line. You do this by opening a screen to the specific serial console.

If you notice in the bottom right of the Arduino program, it shows you what port the Arduino is connected to (for example, Arduino Uno on /dev/tty.usbmodem1421). Use the screen command to connect to this, and have the output print there instead (it appears to interrupt the Arduino from printing the output).

screen /dev/tty.usbmodem1421

Run that, and You’ll see the output start to print. What’s interesting to me, since I know nothing about serial connections, is I guess things just come in as a continuous stream, rather than as discrete objects. Just before I ran that command, my Arduino monitor was printing:

Humidity: 19.50 %	Temperature: 22.10 C
Humidity: 19.50 %	Temperature: 22.10 C
Hu

The screen I opened begins:

midity: 19.60 % 	Temperature: 22.10 C
Humidity: 19.60 %       Temperature: 22.10 C
Humidity: 19.60 %   

Seems likely to me that those are the same line, interrupted right in the middle! I also imagine that a serial connection has much less error-checking, so every so often you’ll see a line print out that’s a bit screwy: a few missing letters, say. (In fact, I think I’m seeing the missing letters show up in the Arduino console!)

Screen has its own crazy syntax, and it’s easy to get stuck in it if you don’t know how to escape:

control-a-:quit

control-a tells screen you’d like to enter a command after pressing control-a, it seems you do have access to some commands (like +flow, whatever that is). To exit, though, you must include the semicolon in the command you want to type.

While I don’t know how useful it is for our purposes, a great strength of the screen command is that you can “detach” the screen, allowing you to start a process, and then have it run without your terminal window point at it.

ctrl-a
d

That’s how a screen is detached while you’re in a screen to see the screens that are running (i.e. that you’ve detached, run screen -ls. If there’s just one detached screen, you can run screen -r to reattach to it; if there is more than one, use the number the -ls command returns, for example screen -r 17089


Capture the Output for Something (Python, say)

We’ve seen that reading data from the serial port that the Arduino is sending things to isn’t magic, and the Arduino program, as well as the command line, can both do it. How about a program? YUP.

I’m using python, because it seems appropriate, and I’d like to connect this to Raspberry PI in some way, and it’s got Python pre-installed.

There’s a library called pySerial that can make interacting with a serial port super easy. If you have pip, it’s as easy as pip install pyserial. I’m sure you can do this without the library, but it’s like an 140k download. The Arduino site explains how to do everything. Essentially you need a four-line program to print to the screen, just as with the console.


Connecting the Arduino to the Raspberry PI is easy, in terms of hardware:

  1. Plug in the USB cable
  2. DONE. Once the Arduino has the AM2302_3.ino sketch on board, it will start executing that program the moment it has power. Whether it’s connected to a computer or not, it’s trying to send the temp & humidity data.

The confusing part of connecting the Arduino to the Pi is finding out where the data is ending up. Just like on the Mac, the Arduino is connected to a serial port. However, I didn’t find which one as easy in this instance. To list out which tty “virtual consoles” are in use, there is a record in /proc/tty/drivers. Simply run the cat command to print them.

cat /proc/tty/drivers

The output of that will likely be:

user@raspberrypi:/sys/class/tty# cat /proc/tty/drivers
/dev/tty             /dev/tty        5       0 system:/dev/tty
/dev/console         /dev/console    5       1 system:console
/dev/ptmx            /dev/ptmx       5       2 system
/dev/vc/0            /dev/vc/0       4       0 system:vtmaster
acm                  /dev/ttyACM   166 0-31 serial
ttyprintk            /dev/ttyprintk   5       3 console
pty_slave            /dev/pts      136 0-1048575 pty:slave
pty_master           /dev/ptm      128 0-1048575 pty:master
unknown              /dev/tty        4 1-63 console
ttyAMA               /dev/ttyAMA   204 64-77 serial

I honestly didn’t know which one of these could be the Raspberry Pi, but I made a lucky guess. It seemed likely that the one we wanted would say serial, rather than console or system. Another way you could do it is to check the message buffer of the kernel with the dmesg -T command. (The -T flag isn’t necessary, it simply outputs the time an event happened as a date, rather than the number of seconds since the OS started.) Essentially, dmesg prints info on when the OS has set up devices (either on boot, or when they’re plugged in). (Incidentally, this helped me find where the external HD I connected was living!) Based on all this, I my first guess was ttyACM. To examine what was coming in from that “device”, whatever it was, I navigated to /dev/ttyACM0, and displayed its contents to the screen with:

cat /dev/ttyACM0

The output?

Humidity: 24.10 %	Temperature: 19.80 C

HURRAH!