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.

Friday, 11 September 2015

Weighing Things

We like measuring things here at Sniff Labs, so we're always looking out for cheap and fun sensors we can hook up to an Arduino. In Release 21 we've added support for weighing things using a load cell.
These can cost anything from a couple of pounds to hundreds of pounds depending on what you want to measure, but I bought a cheap one that can weigh up to 5Kg for about £3. They work on by attaching strain gauges to a metal bar. When weight is applied the bar deforms (slightly!) and the strain gauges reflect this. To turn this into something we can measure, the changing resistances of the strain gauge are arranged in a wheatstone bridge.

If all the resistances are equal the potential difference between D and B will be 0. Depending on your gauge several (or all) of the resistances can change, but basically the bigger the weight on the cell, then the bigger voltage between B and D.

Hopefully you're ahead of me, that we can measure a voltage using an Analog to Digital Converter (ADC). The Arduino has one of those built in, but there's a catch. The voltage we want to measure is very small and we need to measure it very accurately. The Arduino's analog inputs are the right general idea but we need something a bit more powerful...

And that would be the hx711. These cost about £2, and perform the same task as the Analog inputs, but much more accurately. In fact they're specifically designed for connecting to load cells, and have differential inputs, so they can measure the difference in voltage between the two points directly.

Wiring up the load cell can be a bit intimidating, as it (typically) just has four, unlabeled wires coming out of it. To make matters worse, the colours aren't totally standard, but most seem to be:
  • Red -> E+ (+ve power)
  • Black -> E- (-ve power)
  • Green -> A+ (+ve input)
  • White -> A- (-ve input)

If you get them wrong it probably won't do anything bad. In fact I got the green and white reversed when I made mine, and the only thing that happens is that it reads a negative voltage, rather than positive when a load is applied (which is perfectly fine, as it gets fixed when we do the calibration step).

The hx711 has two further inputs B+ and B- which allow you to connect a second load cell, but the Sniff device doesn't currently support that (if you need it, then drop me an email, and I'll look into it).

To connect the x711 to an Arduino we need two data pins: Data and Clock. Which ever pin you choose for Data, clock should be the next one, so I've used 8 for data, which puts clock on 9:

make loadCell hx711 device D8 #Data on D8, Clock on D9
make hxRawValue number

when start
.tell loadCell to "read"
.say join "Raw:" [ hxRawValue ]

All we need to do is tell the cell to "read", and we get back a value from the sensor.

However before we can do anything with that we need to calibrate the cell. There are two parts to this, and the first is done automatically. If you've used kitchen scales then you know that you can put the empty bowl on the scales and reset them to zero, so that the weight of the bowl is ignored in future measurements. We do the same thing, so when you run the program make sure there's nothing on the load cell that shouldn't be. The code will measures the weight of anything thats on the cell when its reset, and subtracts that from future measurements, so you don't need to worry about it.

Now that we've got our "zero" we now need to set our units:

.say "Apply the Calibration Weight now"
.ask "How heavy is the test load?" and wait
.tell loadCell to "read"
.set scaleFactor to value of answer/hxRawValue

We need to apply something of known weight to the cell. It doesn't matter exactly what it is, but it should be a sensible weight for the load cell you're using. We then get the raw value from the sensor and that gives us a scale factor.

..tell loadCell to "read"
..say join "Raw:" [ hxRawValue ]
..say join "Weight:"  [hxRawValue*scaleFactor]
..say ""
..wait 1 secs

From then on we can just read the raw value and multiply by the scale value to get the weight. 

You only really have to do this calibration step once - you can just print it out, and then use that number in future code. Once calibrated you don't really need the computer anymore, so it would be easy to replace the onscreen output with an LCD display. However each load cell (or at least each type of cell) needs to be calibrated at least once.

In primary school children learn about measuring by starting with alternative units - how many hand spans is the desk? How many strides is the playground? While kids this age aren't going to be coding this example themselves, you could have some fun by making a set of scales that weigh in alternative units. The calibration stage doesn't care what you put on the scale - the obvious thing is a 1Kg weight and tell it that it weighs 1 unit, but get creative: The hamster is a perfectly good unit of weight! 

At the calibration stage just put 1 hamster on the scale, and tell the program that it weight 1 unit. From then on your scale weighs in hamsters!

No comments:

Post a Comment