Simple environment monitoring with spare parts.

15 July 2020

It's going on summer in the Bay Area, which means that it's warming up a bit both outside and inside (because air conditioning is Not A Thing out here).  That, coupled with the not inconsiderable research infrastructure I have at home has left me wondering and worrying about just how hot my office gets during the day while I'm working.  Now, I could just put a simple little thermometer on my shelf (and I did) but my concerns are a bit bigger than that.  What happens if my office temperature reaches a critical point and servers start melting down on me?  I've dealt with heat damage in the past and don't particularly care to shell out a grand or so to replace parts that flatlined because I was away from the house and couldn't respond in time.  That, and the fact that I need to keep my mind busy while I'm stuck in quarantine if I'm going to be honest, are the reason why I built yet another weird-assed exocortex project: A relatively simple hardware monitor connected to a Raspberry Pi, and a bot that listens for commands and responds with what it can detect of the local temperature or humidity when I send it a message.

You're probably wondering why I used a RaspPi (a RaspberryPi Zero-W, to be precise) for this project when everybody and their backup would use a more common embedded microcontroller like the ESP8266.  I have three answers for this: The first is, I have a couple of RasPi Zeroes sitting around my workshop and wanted to put one of them to use in a fun weekend project.  The second is, I didn't have any microcontrollers sitting around.  The third reason is because I'm a shitty electrical engineer and I'm not afraid to admit it.  I wanted to prototype this sensor project on a platform I already know really well, find as many gotchas as I could, and then write a new implementation later (and, in point of fact, I ordered a couple of Adafruit Feather HUZZAHs built around the ESP8266 a day or two after I got the prototype stable).

The first thing I did was get my hands on some inexpensive temperature and humidity monitoring sensors.  After some research I bought a handful of AHT20s from Adafruit.  They're tiny, about the size of a US quarter, cost less than your average drink at Starbucks, and are really easy to wire up (just four pins, two of which are for power).  Even I can't mess that up (well, I could, but I didn't).  The aforementioned RasPi Zero-W came out of a small stash in one of my parts bins (at $5us each on special, they're hard not to snap up), as did a case for it and a microSD card.  I already had the patch lines from an earlier project sitting around and, even though they're designed for use with breadboards if you snip the connectors on the ends off they're perfect pre-sized wires for connecting stuff together.  Downloading the latest version of Raspbian (now RaspberryPi OS) took just a few seconds.

My plan was the prototype the sensor in such a way that porting it to an embedded microcontroller running Circuitpython would be very easy.  To that end I used a module called Blinka, which acts as a compatibility layer between my code and the underlying hardware (the RasPi).  When I started developing my bot on Windbringer I discovered that he doesn't have any of the RasPi-specific stuff so it didn't actually work.  I did most of the coding on the RasPi itself (hereafter refered to by its hostname Audra) so I could test and debug in realtime.

The first thing I had to do was figure out the pinouts: In other words, what solder pad meant what.  I did this by studying, making notes, and making sure that the information I found was consistent.  The sensor's pinout (as mentioned earlier) is really simple: Power in (3-5 VDC), ground, I2C Clock and I2C dataI2C, if you're not familiar with it (and I'm not, I need to sit down and learn about it) is a really simple serial protocol that embedded devices on the same circuit board use to communicate with each other.  If you've ever configured temperature and fan monitoring on a Linux box, you've configured I2C.  When I set up RaspberryPi OS (I guess I'd better get used to saying that because people can be really touchy about naming things) I made sure to enable I2C support so that the sensor would be available to the hardware.

Back to the pinouts.  The nice thing about the RasPi Zero W is that the pin headers where you're supposed to connect stuff are usually not present so if you wanted to solder wires directly to the PC board (and I did) you don't have to fight with it too much.  So, I ripped four patch lines off of the bundle I had in my drawer, snipped and tinned the ends, and soldered wires to pins 1 (3.3 volts DC), 3 (SDA), 5 (SCL), and 9 (ground) on the RasPi.  The other ends were soldered to the VIN (voltage in), SDA, SCL, and GND pins on the AHT20.  That's really all it took to get the right pulses of electricity going to the right places.  I did make a few mistakes when soldering, I hadn't gotten the conductive bits of the wires all the way through the holes in the circuit boards but that was easy to fix with a pair of hemostats and a little more soldering iron time.  Once everything was secure I powered Audra up and poked at the I2C bus with the i2c-tools package to make sure the new sensor was responding.

{19:45:52 @ Sat Jul 04}
[pi @ audra ~] () $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
{19:45:55 @ Sat Jul 04}
[pi @ audra ~] () $

The hard part done, I then sat down to actually write a bot that would interact with the sensor.  Surprisingly (or unsurprisingly, depending on how you look at it) practically all of the code is either boilerplate bot code (I have a template bot that I use to get a jump on writing new bots) or parsing commands.  The actual "read the temperature" and "read the humidity" functions would both fit onto an index card if they were hand-written.  This is what talking to the bot looks like.

I probably won't be able to fit an entire "XMPP bridge + bots" stack onto a microcontroller, and I probably won't be able to fit the logic for detecting spikes in temperature or humidity into a microcontroller either, due to the really constrained amount of memory I'll have to work with (about 160 kilobytes).  To be honest I haven't implemented that logic in Environment Sensor yet, but I already have code in Systembot that I can re-use.  But I'm rambling.  What I will probably do is set up a webhook in Huginn that the embedded sensor can push readings to, and do all of the spike detection with a small agent network.

One thing I noticed is that Audra consistently reports temperatures 6.2 degrees Fahrenheit higher than the standalone "control" thermometer I have on my workbench.  I suspect that is due to the fact that I attached the temperature sensor to the top of Audra's case, which is noticeably warmer than the surrounding environment.  To fix this, I snipped off the zipties and attached the sensor to an old SD card case mounted a couple of inches below the RasPi.  Once again, new zipties were used for attachment.  The effect was immediately noticeable - ambient temperature reported by Carlo is now three degrees lower and closer to the reference temperature in my workshop.

Of course, there is a gallery of pictures I took during the construction process.  I haven't taken any pictures of the new installation layout because I don't feel like editing the gallery again.

Later on, I'll post another build journal of the microcontroller version of this project.  Give it a few weeks, things are busy right now.