Saturday, March 22, 2008

Building a temperature probe for the OLPC XO-1 laptop

I bought an OLPC XO-1 laptop through the G1G1 program and was intrigued to discover the Measure activity.

The measure activity uses the internal audio system to measure a value input on the microphone socket. With nothing connected this application reads the value of the internal microphone and displays a waveform. You can have fun just by whistling, speaking or singing with Measure running.

But since you can measure a voltage input into the microphone socket, it's possible to build sensors and connect them to th OLPC XO-1. On the Measure web site they mention building a simple temperature sensor using an LM35 temperature sensor that looks like this:

The LM35 can measure a temperature between 0 and 155 Celsius just by hooking it up to a 5v supply. It outputs 10mv per degree so a temperature of 20 Celsius corresponds to 0.200v.

Since the OLPC XO-1 has a USB port it's possible to get 5v from the laptop by hacking a USB connector, and connect 5v to the LM35 and then take the signal coming from the LM35 (the middle pin) and connect it to the microphone socket.

I did this by building two parts: a generic adapter which gives me 5v and a signal line out of a standard stereo 3.5mm jack:

The stereo jack is wired up so that the tip is +5v, the base is Gnd and the middle is the signal going to the microphone socket. The USB plug has only two wires connected (for +5v and Gnd), and the jack going to the microphone socket (which is mono) has the connected to the middle of the stereo jack, and the base is Gnd. All the grounds are joined together.

When plugged into the OLPC XO-1 it creates a generic connector for any other projects I might work on:

For the temperature sensor I simply connected the LM35 to a stereo socket with the correct connections to match up with the stereo jack plug. Then I created a probe with an old plastic pen and some waterproofing compound (so that I can do things like shove the probe in a cup of coffee without wetting the contacts on the LM35). Here it is:

Connect the two together and run the standard Measure activity and you can start to look at the output of the sensor and hence the temperature.

But there's a problem. The microphone input can only handle voltages in the range 0.3v to 1.9v (and my measurements of my OLPC XO-1 show this range to actually be 0.4v to 1.9v). So that means as is the probe can be used to measure temperatures in the range 40 Celsius to 155 Celsius. That low end is a bit high for the sorts of experimentation you can do at home (e.g. measure the temperature in the fridge, or a glass of cold water, or even the temperature inside your mouth).

So we need to scale the voltages coming from the sensor to fit better into the range that's readable by the laptop. The standard way to do that is with an operational amplifier which is used to add two voltages together: the voltage coming from the sensor and a reference voltage. Doing this will move the voltage up.

For that I used the LM1458 which in a single 8 pin package contains a pair of operational amplifiers.

Here's the circuit diagram:

The circuit has three parts: a voltage divider, a summing amplifier and an inverting amplifier.

Voltage divider: the reference voltage is created by taking the 5v available from the USB port and passing it through resistors R8 and R9. The voltage at the middle point of these two resistors is determined by the standard formula for a voltage divider of 5v * R9/(R8 + R9) = 5v * 1 / ( 10 + 1 ) = 0.45v. In my actual circuit with 1% tolerance resistors the measured voltage was 0.41v.

Summing amplifier: the middle portion of the circuit takes the two inputs and adds them together (and because of the nature of the circuit inverts the summed value). So its output going into R7 is -ve the sum of the reference voltage and the sensor voltage.

Inverting amplifier: the final part just inverts the voltage so that the output is +ve and in the range that the OLPC XO-1 can read.

One complexity is that this circuit requires +9v, Gnd and -9v to operate. I obtain that with a pair of 9v batteries linked together giving Gnd where the two are connected. Here's the final circuit with appropriate connectors to hook up to my existing probe and laptop adapter:



And here's what it looks like when it's all hooked together:

Now, this wouldn't be any fun without a bit of software and since the Measure activity can only display the voltage being presented (which is now a mixture of the sensor voltage and the reference voltage) what's needed as a new activity.

I found the developer documentation to be very hard to follow and I ended up hacking the existing Measure activity and renaming it Temperature.

The critical code is in the file drawWaveform.py where it reads self.avg (the value coming from the microphone input via the ADC) and scale it for display. I measured voltages coming from my probe for a couple of known temperatures and worked out a scale factor (The +32768 is because the self.avg ranges from -32768 to 32767):

layout.set_text("Temperature: %.1f C" % (0.00221833*(self.avg+32768)) )

Here's a screenshot of Temperature running on the laptop and measuring the ambient temperature in my office:

You can download my Temperature activity using the browser on your OLPC XO-1 to install it.