Arduino and Twisted
The datalogger progresses - now with carefully-soldered SC600 sensor online:
Still need to add the 47uF cap and 100k RC filter, though, so the humidity data is crap.
I cleaned up the code a bit. The Arduino now simply sends raw ADC counts, and lets the other side do the linearization and conversion. Much more sensible. To make it easy, I have the Arduino send
ADC ADC\n
In other words, value space value newline, which is the easiest possible thing to parse on the other end. Code is now simply:
void setup() {
// initialize the serial communication:
Serial.begin(9600);
}
void loop() {
Serial.print(analogRead(0));
Serial.print(" ");
Serial.print(analogRead(1));
Serial.println();
}
Using the magnificent Twisted framework, this is a ’LineReceiver’ protocol on top of a serial port, so the code to read it is quite compact. I won’t paste it here, as its 85 lines with all the comments, command line parsing, error handling and such, but here are the key bits:
class Echo(LineReceiver):
def processData(self, data):
"""Convert raw ADC counts into SI units as per datasheets"""
if len(data) != 2:
return
tempCts = int(data[0])
rhCts = int(data[1])
rhVolts = rhCts * 0.0048828125
# 10mV/degree, 1024 count/5V
temp = tempCts * 0.48828125
# TODO need to rewrite this to include thermal compensation as per SC600 datasheet!
humidity = (rhVolts * 45.25) - 42.76
logging.info('Temp: %f C Relative humidity: %f %%' % (temp, humidity))
def lineReceived(self, line):
try:
data = line.split()
logging.debug(data)
self.processData(data)
except ValueError:
logging.error('Unable to parse data %s' % line)
return
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, \
format='%(asctime)s %(levelname)s [%(funcName)s] %(message)s')
o = THOptions()
try:
o.parseOptions()
except usage.UsageError, errortext:
logging.error('%s %s' % (sys.argv[0], errortext))
logging.info('Try %s --help for usage details' % sys.argv[0])
raise SystemExit, 1
if o.opts['baudrate']:
baudrate = int(o.opts['baudrate'])
port = o.opts['port']
logging.debug('About to open port %s' % port)
s = SerialPort(Echo(), port, reactor, baudrate=baudrate)
reactor.run()
Gotta love Python! (And Arduino.) Next up is trying to get the data into Cacti or RRDtool…
Update 6/17: Adding a web interface took just a few more lines of code:
class indexPage(resource.Resource):
isLeaf = True
def render_GET(self, request):
ccStr = 'Temp:%f Humidity:%f\n' % (lastTemp, lastRH)
return ccStr
root = indexPage()
site = server.Site(root)
reactor.listenTCP(2000, site)
Now trying to get Cacti to parse the data it returns.
Comments