##################################### Snake Vivarium Control Computer Notes ##################################### I've got an old Raspberry Pi (version 1B) controlling my pet snake's vivarium. Specifically, it controls power to the lights and heaters and collects temperature data. It's nothing fancy, but this is my website, yeah? I'd like to think that this is largely an example of stitching together simple utilities to achieve complex tasks. The PID loops in Python are a little in violation of that idea, but nevertheless, the aspiration remains. Power Control Hardware ###################### Hard Power ========== The device used is a "Western Telematic Inc." "RPB+" (the plus sign is dramatically important; the "RPB" without plus is a *remarkably dumb* device). It speaks (an oddly-specific) RS232 out one side and has five standard 110V power ports on the other. Its manual is available at http://www.wti.com/guides/rpbp_b.pdf . To make Linux reliably use this device, it's necessary, apparently, to configure the serial port in a rather particular way :: stty -F /dev/ttyUSB0 0 || true stty -F /dev/ttyUSB0 sane -echo clocal crtscts hupcl -icanon icrnl inlcr 9600 The first line will hangup the port (lower DTR) and yet will report an error ("stty: /dev/ttyUSB0: unable to perform all requested operations") which *must be ignored*. I cannot fathom. In any case, the second line causes the kernel to... * bring the serial port into a sane state, but... * turn off character echoing (very important or we echo responses as commands) * wait for carrier * use RTS/CTS flow control * assert DTR when there's a connection open * turn off canonical mode (e.g. line buffering) * convert some line ending characters on the way in * set the baud to 9600 Phfew. At that point, we can speak to the device using the tools we might expect (e.g., ``socat STDIO /dev/ttyUSB0``). Every now and again the initial status report fails to make it all the way to the prompt. Press enter and "/S" again if you want it; it always seems to work the second time. Soft Power ========== Having hard relays driving the lights is fine, and it's fine for some of the heaters, too, but it's not so good for the under-tank heaters that are used to regulate hide temperature. Full power or full off just is too extreme, resulting in several degree overshoot in both directions that just seems stressful. So I got a DMX-controlled dimmer (a Chauvet DMX-35 4-channel dimmer pack) and a USB to DMX adapter (a DMXking ultraDMX Micro) so that these more demanding devices can be handled in a sane way. Additional Hardware ################### Camera ====== There is, additionally, a raspberry pi camera module, on a 5 meter ribbon cable, with a wide-angle lens mounted to the top of the tank. This lets me take pictures of Melman and eventually watch for motion and record segments. LCD === I have an I2C LCD connected and running `lcdproc `_. I had to build ``0.5.8-rc2`` from source because this backpack is wired differently than the old driver expects and the version with configurability is not in Debian. All told, the ``LCDd.conf`` stanza for this display looks like:: [hd44780] ConnectionType=i2c Device=/dev/i2c-1 Port=0x27 Backlight=yes Size=20x4 DelayBus=false DelayMult=1 Keypad=no Speed=0 i2c_line_RS=0x01 i2c_line_RW=0x02 i2c_line_EN=0x04 i2c_line_BL=0x08 i2c_line_D4=0x10 i2c_line_D5=0x20 i2c_line_D6=0x40 i2c_line_D7=0x80 BacklightInvert=yes Power Control Software ###################### Hard Power ========== A simple expect script suffices to drive the hardware. The lights are controlled by `remind `_, a remarkably flexible scheduling program. I have it running under ``runit`` automation (which, in turn, is running under ``systemd`` because I am on a Debian box) using a ``run`` file of:: #!/bin/sh exec chpst -u pi:pi:dialout remind -z /home/pi/.remind And the ``remind`` script itself, at ``/home/pi/.remind/sc.remind`` is:: SET $LongDeg 76 SET $LongMin 36 SET $LongSec 33 SET $LatDeg 39 SET $LatMin 17 SET $LatSec 33 REM * AT [sunrise()] RUN /home/pi/sc/rpb.expect 1 on >/dev/null REM * AT [sunset()] RUN /home/pi/sc/rpb.expect 1 off >/dev/null The expect script ``/home/pi/sc/rpb.expect`` is mercifully short:: #!/usr/bin/expect proc waitprompt {} { expect { "RPB+> " { } timeout { exit 1 } } } spawn /home/pi/sc/serial.wrap /dev/ttyUSB0 set timeout 70 send "\n" waitprompt if {$argc == 2} { set outlet [lindex $argv 0] set cmd [string toupper [lindex $argv 1]] send "/$outlet $cmd\n" set timeout 30 waitprompt } and the serial wrapper ``/home/pi/sc/serial.wrap`` too:: #!/bin/sh set -e -u stty -F $1 0 2>/dev/null || true stty -F $1 sane -echo clocal crtscts hupcl -icanon icrnl inlcr 9600 exec flock -e -w 60 /var/lock/LCK..`basename $1` socat $1 STDIO The use of a lockfile is necessary because Linux doesn't believe in exclusive access to serial devices. (Or, well, truthfully, it does, but there are enough caveats to "exclusive" that it isn't worth attempting to use robustly.) Soft Power ========== The DMX outputs are driven by PID loops that watch the temperature sensors. Eventually I will release the code repsitory, I just haven't done it yet, sorry. .. LCD Screen .. ========== .. .. Eventually I'll display temperature and PID data on the display