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.

Tuesday, 15 July 2014

Tom's Giant Thermometer

Another quick bit of fun:

One of the guys who helps out on Sniff is Tom Stacy (@Code_ED on twitter). One of his other projects is an environment sensor using the Arduino Yun. One day he turned up with a fun idea to display temperature by making a giant thermometer out of neopixels! It's pretty easy, as we just need to read the temperature (using a dht or ds18), and then light up the right number of pixels with an appropriate colour.

If you're demoing an experiment to a class you could set one of these up on the wall, and everyone would be able to see the temperature readings your getting.

Lets start by making the devices:
make dht device A1
make temperature number
make humidity number

make neoPixel device A4
make neoShade list of number
make neoColor list of number

We'll also need some info on how we want this configured:
make ledCount number
make minTemp number
make maxTemp number
make ledIndex number

when start
.set ledCount to 10
.set minTemp to 20
.set maxTemp to 30

Now we just need to loop forever, reading the temperature and lighting up the neoPixels:
..delete all of neoShade
..delete all of neoColor
..tell dht to "readDHT11"
..set ledIndex to ledCount*(temperature-minTemp)/(maxTemp-minTemp)
..repeat ledIndex
...add 0 to neoColor
...add 50 to neoShade
..repeat ledCount-ledIndex
...add 180 to neoColor
...add 100 to neoShade
..tell neoPixel to "show"
..wait 1 secs

NeoPixels are driven by filling in the two lists with the shade, and colour. Colours go from 0-360, where 0 is red, and shades go from 0 (black) though 50 (saturated colour) to 100(white). We start by emptying the lists, and reading the temperature.

Then the clever line... we calculate how many led's to light by calculating the fraction of them to light, and multiplying by the number of LED's.

Then we just fill up the lists with ledIndex of them being red, and the next 1-LED of them being white, then output them to the strip. There's actually a subtle bug here, as ledIndex isn't likely to be an exact integer, so depending on its value we might end up using an extra LED - its a rounding error combined with an off-by-one bug (its also one of the reasons why most programming languages have an int and a float type). However in this case all that happens is an extra LED gets lit, so I'd rather not complicate the code with it (a bit of rounding should solve it).

As set up the code is written for Arduino, and uses 10 neoPixels attached to A4, and a DHT11 attached to A1. It should work fine on a Pi, and you could substitute a ds18 for the dht11 (or 22) as these come in steel cases which let you measure the temperature of liquids and other things you might be interested in.

There is one gotcha though... 10 isn't exactly "giant". I had hoped to use a full strip of NeoPixels. I've run those from the Arduino power pins more or less without problems, but it is on the limit of what is "OK". When I connected the dht11 and the neoPixels I found that the noise introduced into the system by the neoPixels caused erratic readings from the DHT11. I was able to get 10 working reliably. With better smoothing you can probably get a few more, but for best results (and a giant!) thermometer then you'll need to hook up a proper PSU for the neoPixels - this is good practise anyway...

No comments:

Post a Comment