Arduino and Twisted

The datalogger progresses – now with carefully-soldered SC600 sensor online:
img_0191Still 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


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:

void loop() {
  Serial.print(" ");

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:

        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'Temp: %f C Relative humidity: %f %%' % (temp, humidity))

    def lineReceived(self, line):
            data = line.split()
        except ValueError:
            logging.error('Unable to parse data %s' % line)
if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO, \
                format='%(asctime)s %(levelname)s [%(funcName)s] %(message)s')

    o = THOptions()
    except usage.UsageError, errortext:
        logging.error('%s %s' % (sys.argv[0], errortext))'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)

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>