## Pages

Sniff is a "Scratch-like" programming language that's designed to help Scratchers move gently from Scratch to more conventional languages. They can start writing programs, without having to learn a new language because Sniff is based on Scratch. They learn a little more about variables, compiling, syntax errors (!), and they can have fun controlling real hardware while they're doing it.

## Thursday, 31 December 2015

### The Esplora temperature sensor...

We got an Arduino Esplora for Xmas!! or more strictly a knock off copy. Official Esplora boards are way too expensive,  but copies are starting to appear, and for about £20 you can get a board, with a TFT screen included. We wasted no time getting everything working with Sniff, and we'll post details in a future post (once we've released the drivers in the next code batch). However its basically an Arduino Leonardo (use leo-sniff) with a bunch of sensors built into the board.

While overall we're fairly positive about the board, when we started coding for the temperature sensor, we ran into some problems, which might be of interest to others using the board.

The first thing we found was that readings were inconsistent and jumped around. A little research showed that this is a fundamental design problem with the Esplora.

The board uses a tmp36 and we can learn all about those from those helpful people at Adafruit. The great thing about the tmp36 is that it outputs a voltage dependant on temperature of between 0.2 and 1.75V over a range of -25 to 125 degrees. We can easily convert a given voltage to temperature using:

T=(1000V-500)/10

In other words the tmp36 is a solid, well thought out/built device that is well suited for many applications. However its inclusion in the Arduino isn't well thought out or well suited.

The AVR has a 10bit ADC, so when we apply a voltage to an analog pin we get an integer value:

A=(Vin/Vcc)*1024

Or to put it another way, our estimate of Vin is:

Vin=(A/1024)*Vcc

Dropping that in to the first equation gives:

T=Vcc*100*(A/1024)-50

and as Vcc is 5V

T=500*(A/1024)-50

which is exactly the equation you'll find inside the Esplora library. But here's the first real problem... What happens if we change A by 1? T changes by 500/1024 or about half a degree. The absolute  best we could hope for is that the temperature is going to change in half degree steps.

Now that would be OK in many cases - accurate to the nearest 1/2 degree over a range of -25 to 125 degrees is pretty impressive. The ds18b20 is a similar, or worse spec, and its great - I regularly drop it in coffee, or buckets of ice to see what happens. But the ds18b20 comes in a waterproof case on the end of a wire. The sensor on the Esplora is soldered to the board underneath the TFT screen. It's only going to measure air temperature in nice people friendly environments. Drop it in boiling water and you've got a bigger problem than half degree errors. Most of its life is going to between 20 and 25 degrees. Getting it wrong by 0.5 degrees is quite a lot when you'r only expecting a swing of 5 degrees anyway. Had the designers being paying attention to that graph on the Adafruit page they'd have noticed its got three lines on it, and the other two which represent the tmp34 and tmp35 are much steeper. In other words they give a bigger voltage swing for a given temperature change.With the tmp36, even in extremely hot or cold rooms we're never going to see more than a 0.1V swing, which the AVR ADC just isn't sensitive enough to measure well. They picked the wrong component for the job.

But things get worse... That half degree accuracy is only good if was assume our device is operating perfectly. A 10bit ADC might give you 10 bits of accuracy, but it probably won't. That last bit or two is going to wander around as it picks up noise from the surrounding circuits, so the reading jumps up and down by half a degree, essentially at random. Fortunately we can fix this by averaging the results. I averaged 10 results taken over 1 second and was able to get something fairly stable, and if the noise is truly random it can actually make the results a bit more accurate...

So wrote a demo app, averaging the temperature, which was reading a consistent 23 degrees and displaying it on the screen. Then I moved it to run from a USB PSU, rather than from the computer and the temperature reading dropped 5.5 degrees. Moving it back to the computer and it was high again. Moving it from the USB hub to being directly plugged in dropped it 5 degrees.

Going back to a previous version of our equation:

T=Vcc*100*(A/1024)-50

We simplified this using Vcc=5, because USB runs at 5V... except it doesn't. USB specifies a voltage between 4.75 and 5.25. There's always a margin of error, and its considered OK to have a value +-5%. That corresponds to a 5% swing in T+50, or about +- 4 degrees at room temperature.

Using a USB Voltage/Current meter I was able to measure my power sources, and found that my USB hub is borderline out of spec, giving a low voltage, and hence high temperature. Both the Mac port, and the USB battery are pretty close to being right on spec, but even the difference of 0.04V was enough to give a small change (after averaging).
USB hub: 4.7v 23.9C
Mac: 4.99v 18.8C
Battery 5.03V 18.3C

Unless you trust your power supply totally the sensor is accurate to with 4 degrees. Again that would be fine if we were measuring a range of temperatures, but as we're limited to measuring air temperature 4 degrees either way of a 22 degree reading is not knowing if its 18 degrees (put a jumper on) or 26 degrees (open a window).

At one point I was plotting the temperature on the screen and got a regular up/down cycle. It turned out my USB volt meter was dropping the voltage by a few mV every time it switched from volts to amps reading... enough to give a systematic temperature variation.

For reference I hooked up a dht11, and a ds18b20 to the tinker kit ports of the Esplora, and set it to display all three recorded temperatures. The DHT11 and ds18b20 produced different readings but they were consistent when I changed the power source. The DHT11 is known for being inaccurate, but if it constantly reads high (as mine seems to) then you can calibrate around it.

Now you might argue that its just a fun/toy beginners board and that it was built to a budget, but that doesn't hold water. For a start the official boards sell in kits for £70. Also while its pretty easy for me as an experienced engineer to deal with these issues, someone less experienced would just be sat with a gadget that didn't work reliably.

Perhaps the worst thing though is that there are other solutions out there that would do the job better and more cheaply. A tmp36 costs about £1 on eBay (pennies in bulk), but a thermistor costs pennies on eBay (decimal points in bulk). They provide similar accuracy but because you thermistors as a potential divider Vin is proportional to Vcc, which means that in the equations Vcc just cancels out.

The real ironic moment is when you realise they picked a component: the tmp36 that has as a design feature that Vout is independent to Vcc. The tmp36 behaves the same even if the voltage changes... which in this case directly leads to us getting the wrong results. It's not the tmp36's fault... They just picked the wrong component!