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, 12 May 2016

Skylanders Vs Infinity on the Microbit

It's just been announced that Disney Infinity is dead. This isn't so much of a surprise - V1 showed some promise, but V2 didn't include any Disney characters, alienating the market they'd grown with V1 (I would have bought it if the selection of Marval characters included Jessica Jones, just to unlock the empty whiskey bottle in the toy box), while lacking depth to appeal to older players.

Skylanders has also jumped the shark... I quite liked Swap Force, but Super Chargers was just dull - probably because as a parent my role was to hold the second controller and press fire, while offspring got to do all the driving. 

So the only think left to do with all those figures - let them battle it out one last time with your Microbit! Both Skylanders and Disney Infinity use "RFID" tags inside the figures, so that the base station can identify them. It's the same technology that's used for contactless credit cards.


To teach your Microbit to read RFID tags you need a "Mifare RC522", sometimes called MF522. These cost about £2.50 on eBay, and you can use them to read all sorts of cards. You can even buy "blank" cards, which you can store data on. Inifiity/Skylanders use this feature to record the progress on the figure rather than in the game, but they have a security code so you can't easily write to them yourself. All we're going to do is read the ID of the card.

Hook up is really easy: If you've checked out our other microbit posts you'll have used SPI. Just connect the power, and the 4 SPI wires from the MF522 to equivalent ones on your microbit, and you're good to go. There may also be a "reset" pin but just ignore that.

make spi device
make cardReader rfid device D16
make cardData string
make cardAddr number

make message string
make scrollDone boolean

First thing to do is make an SPI device and then an rfid device. I used D16 for "CS/SS" though you could use something else if you wanted to. I'm going to display the data on the screen using a script called scroll, so I also set up some variables for that.

when start
.set message to "ready"
.broadcast scroll and wait
.
.forever
..repeat until not cardData = ""
...tell cardReader to "get card"
..set message to cardData
..
..if message="12,5c,20,10"
...set message to "Bash"
..if message="88,4,7e,eb"
...set message to "Elsa"
..
..say message
..broadcast scroll
..tell cardReader to "release card"
..wait until scrollDone

To use the "scroll" script we set the message and run the script. We kick of by saying "ready". Now we're going going to tell the reader to "get card", which tells it to start talking to a card. If it finds one it puts its card ID into cardData, so when we find one we can set that as the message.

The card ID will look like four hexadecimal numbers. I check them against the figures I already know about, and if they match, I replace the ID with the characters name. I picked Elsa and Legendary Bash to use (remember these are the numbers for my figures - yours will be different). You can add as many as you like. If you have a lot you could write some code to check them against a list rather than testing teach one. You could even add an SD card, and have a file of known figures.

Once I know the character I "say" it to the computer, and run "scroll". We don't "and wait" this time as we need to tell the card reader that we're now done with this card, and it should disconnect. Then we wait until the scrolling is complete.

The code to display/scroll text is something we've also seen before:

make display microbitDisplay device
make displayX number
make displayY number
make displayColor number
make displayFlush boolean

when start
.forever
..tell display to "tick"

make offset number
when scroll
.set scrollDone to no
.set displayColor to 0
.tell display to "clear"
.set displayX to 1
.set displayY to 1
.set offset to 8
.repeat until displayX<0
..set displayColor to 0
..tell display to "clear"
..set displayColor to 777
..set displayX to offset
..tell display to "show"
..change offset by -1
..wait 0.08 secs
.set scrollDone to yes

The only new thing I've added is that it sets scrollDone to no at the beginning and scrollDone to yes when its finished. This allows the main script to wait until the full text is displayed before going again.

And that's it - really easy. You could use figures to control anything you can connect to your microbit. Use them to unlock doors, control lights, make your buggy move. You could write your own "credit card" system and pretend to shop! When you've done that have a look at examples/Embedded/rfid which includes reading and writing data to programmable cards. 

Wednesday, 11 May 2016

Microbit Thermometers - is it hot in here?

If you go through the posts here, you'll find that a bit part of what we think is important is taking computing and linking it to the rest of the curriculum. We did a presentation at a recent event called "Banana Physics", which shows how you can use devices you probably already have like the Lego Wedo, and Scratch Picoboard to do real science (We'll also be showing this as a poster at Scratch@MIT2016). Measuring and recording real data and combining that with maths and physics to actually learn real things about the world - stuff you might have learned in KS4 or A Level physics in a chalk and talk class you can easily turn into practical sessions which put computing to work for real applications. By making it practical much younger kids can apply results from much more advanced theoretical classes.

One of the things you should absolutely do with your microbit is measure and record temperatures. This is one of the cheapest, and simplest pieces of equipment you can attach to a Microbit, so (as many of you are probably new to this),  I thought I'd do a quick roundup of the options available to do that:

Built in Sensor

Wait a minute, doesn't the Microbit have a built in thermometer? Well yes, sort of... it actually has two - one built into the bluetooth chip, and another in the magnetometer. So what's wrong with these? Well they're designed to monitor the chip, not the outside world. If the chip is working too hard, smart software will give it a rest to cool down (your phone does this, so it gets slower when it gets how. Similarly for laptops - they also use this to control the fans). As a result they can misleading readings. They're also not really calibrated, so you may need to add/subtract an offset before they're even slightly meaningful. 

make thermometer microbitTemperature device
make temperature number

when start
.forever
..tell thermometer to "read"
..say [temperature]
..wait 1 secs


As of release 28 (not out yet, as I write this), you can use this device just by telling it to "read". It's probably good for saying "its hot in here" at appropriate moments, but after that you should think about something more accurate.

Thermistor

The classic way to measure temperature is with a Thermistor - their resistance changes with temperature. The most common type is a 10K NTC, so you can connect one from 0V to D0, and a 10K resistor from D0 to 3V. We can measure the voltage using an analog input and use that to calculate the resistance (using Ohms law!), and then apply another equation to convert resistance to temperature:

make v analog input D0
make r number
make t number

when start
.forever
..say join "Voltage:" [v]
..
..set r to v/((1-v)/10000)
..say join "Resistance:" [r]
..
..set t to (ln of (picoRa/10000))/3950
..change t by 1/(25+273)
..set t to 1/t
..change t by -273
..
..wait 1 secs

The 10000 is the nominal resistance of the device at 25C. 3950 is the B value for the thermistor, and we need to remember to switch between C and Kelvin at appropriate points.

This does work pretty well, and should be pretty accurate. It's super cheap (a thermometer costs pennies), and for not much more you can get on enclosed in a waterproof case so you can put it "in" things to measure their temperature.

DHT11, DHT22

While thermistors are great,and the programming is at a level that if you put the equations on a worksheet kids should be able to work through it, the coding just to measure temperature is a lot of work in itself. Sometimes we want to do the measuring and do something with the result. In which case the dht11 (blue) is a go-to component for anyone doing this kind of thing. They cost less than a pound and can be just connected directly to 0V, 3V and a data pin (one pin is unused).

make thermometer dht11 device D0
make temperature number
make humidity number

when start
.forever
..tell thermometer to "read"
..say [temperature]
..say [humidity]
..wait 1 secs

Not only do they measure temperature, they also measure humidity. However they're not that accurate. If the data you're collecting is important, then you'll need to spend £2 on a dht22 (white). This is an almost identical device, but has a much better spec, for both accuracy and range.

make thermometer dht22 device D0

Functionally they're identical so all you need to do is swap out the line which makes the dht11 to one that makes a dht22. You can buy a load of dht11's for everyone to play with, and just replace them with a dht22, when it comes to actually recording real data. In fact you'll see that all of the devices apart from the thermistor work very similarly. They can also all be wired up to a 3 pin connector (0v,3v, signal) like the one on the MB^5 we designed.

DS18B20

The final way to measure temperature is using a DS18B20. Again these cost about £1 for a waterproof version, and connect via three pins to the microbit (you need an additional 4k7 resistor between signal and 3v). We used two of these connected to an Arduino to compare the temperature of our pond to the air temperature - it was very exciting! You can connect multiple sensors, of the same or different types to different pins  and see how different things behave differently (block box/white box/shiny box?).

make thermometer ds18 device D0
make temperature number
make humidity number

when start
.forever
..tell thermometer to "start"
..wait 1 secs
..tell thermometer to "read"
..say [temperature]

One gotcha here is that the ds18 takes about 1 second to take a reading. We don't want to hang around for 1 second doing a reading, so we tell it to start, wait 1 second and then come back to collect the result. If this starts to make your code more complex that you'd like, remember you can always do this in a separate script, and then just use the measured temperature in a another script.

DS18's are a bit timing sensitive, and don't work reliably on Microbit in Release27. Release 28 fixes this.

i2c

There are couple of other devices you can use (like the bmp180) which include temperature, that can be connected via i2c. However even if you have the kitronik breakout, it puts the i2c pins on a separate connector, making external i2c devices a bit clunky to wire up. In any case these devices are generally designed to do something else (air pressure) and temperature is just an "extra", so if you just want temperature they're not the best choice.

In summary, I'd go for a dht11 as my basic choice, dht22 if I need more accuracy, and ds18b20 if I need waterproof.

All of the simple devices can be easily attached to the Microbit just using croc clips if necessary, and if you have some kind of break-out then they can be wired to just plug straight in. Add an SD card and you've got a great data-logger. However you choose to measure temperature, its really easy and the potential to link coding, building and science is really great. What's the point in coding if you only ever code in computer class?

Monday, 9 May 2016

Microbit Sat-Nav

One of the features we added in a recent build of Sniff was support for a GPS module. These cost less than £10, and are really easy to hook up. However so far, I've only tested them at home. While that was initially exciting, it quickly became very boring, as I always got the same (pretty accurate and correct) reading for where my house is.

Note, this one has an integrated antenna on the board,
Many have an exteneral one which probably performs
better, but it going to be more fragile/tricky to hook up

Once I realised I could hook it up to a microbit, things got more interesting, as combined with the built in screen and compass we could build something that would be sufficiently portable to be viable. Unfortunatly when I hooked up the GPS to the microbit a few weeks ago it didn't work. The problem was that the Microbit is pretty slow, and couldn't keep up with the required maths and timing to process the data from the gps as fast as the gps was sending it. A helpful suggestion (and sympathic ear to my rambling DM's) from @whaleygeek sorted the bit timing, and once stuff started getting decoded I was able to optimise the handling of the data so the Microbit could keep up. The new GPS code will be in Release 28, or if you really can't wait, then drop me an email/DM (ian at dctsystems.co.uk, or @sniffCode on twitter). The code should also work on a Arduino with minor tweaks.

To hook up the GPS Module, connect 0v, and Vcc (it works find on 3v), and then connect "tx" to a data pin on the Microbit. There's also an rx pin which allows you to change settings on the GPS, but we shouldn't need to change anything, so we can ignore it.

make gps device D2
make longitude number
make latitude number

Here I tell Sniff there's gps plugged into D2. As we're only ever likely to have one gps device plugged in at the same time, I've not bothered to give it a name. You can miss out the names on devices and they just inherit the device name, so this is equivalent to :

make gps gps device D2

The gps is going to return out longitude and latitude in degrees. It can also give us the time/date, speed and heading, but we're not going to need any of those.

make deltaX number
make deltaY number
make distance number

when start
.set targetLat to 50.7429791
.set targetLong to -1.89716810
.
.forever
..tell gps to "update"
..set deltaX to targetLong-longitude
..set deltaY to targetLat-latitude
..
..set distance to sqrt of (deltaX*deltaX+deltaY*deltaY)
..if abs of distance < 0.001
...set deltaX to 0
...set deltaY to 0
..else
...set deltaX to deltaX/distance
...set deltaY to deltaY/distance
..wait 9.5 secs

This is the main script which updates the position every 9.5 seconds. I've pre-programmed in the location that I want to go to, and work out the direction I need to go in by subtracting my current position. This is incorrect. This would be right if the earth was flat, but long lat aren't cartesian coordinates, they're spherical polar. This will particularly break if you're traveling ling distances, or are traveling within the arctic circle. In either case I suggest you make more serious navigational plans! If you're in the UK and traveling normal distances then its close enough for a fun project... or you could look up the maths for doing this properly yourself - I just wanted to see if it would work at all!

We also approximate the distance, and divide the direction vectors by the distance so that they're normalised. We also check if the distance is very small, in which case we're there, and don't need to display anything.

Now lets make a compass and display:
make i2c device
make compass mag3110 device
make heading number

make display microbitDisplay device
make displayX number
make displayY number
make displayColor number

when start
.forever
..tell display to "tick"

All of this should be familiar - if not, check out our Microbit tutorials on using the compass and screen. We can now write another script that will run at the same time as the previous one, which do our drawing (this is a handy devision of tasks that is very "scratch-like").

make midX number 3
make midY number 3
make rX number
make rY number

when start
.forever
..tell compass to "read"
..change heading by -90
..set rX to (cos of heading)*deltaX-deltaY*(sin of heading)
..set rY to (sin of heading)*deltaX+deltaY*(cos of heading)
..
..set displayColor to 000
..tell display to "clear"
..
..set displayColor to 777
..set displayX to midX
..set displayY to midY
..tell display to "move"
..change displayX by midX*rX
..change displayY by midY*rY
..tell display to "draw"
..tell display to "flush"
..wait 0.1 secs

Now we tell the compass to read, and use the heading to rotate the deltaX/Y that we calculated in the previous script. We have to adjust heading by -90 so that North is at the top. This is just a quirk of the way the magnetometer is attached relative to the orientation of the screen. Then we just clear the screen and draw the rotated vector!


So how did it work out? Pretty well. The only issue is that reading from the GPS can take up to a second, as the simple device driver code just waits for the GPS to send it a message, which happens once per second. That's normally fine, but means the microbit display blinks off for half a second too. That's one of the reasons for only updating every 10 seconds.

I had a Sniff workshop (building robots) at the weekend and had someone in the car to check the microbit, so though I'd test it out on the way there (I did know where I was going, just in case). This is the first time I've used the microbit compass inside a metal box! Normally when you start using the compass you need to wave the microbit around, but that's a bad idea in a car, as you want it to learn the car's magnetic field as well as its own. That meant the car had to take few turns before the microbit settled down, but from then on it was pretty much spot on. We drove for about ten minutes, and by the end it was pretty solid. It even noticed when we drove past the destination to find parking, and started pointing backwards. It was really pretty good!

In the version I used I had another script which ran, checking the buttons so if you pressed one of them it would set the target location to be the current location - get me back to here, but you could pre-program several locations, and switch between them (great for geo-caching). When I googled for similar projects I found something called a "Jerusalem Compass", which is supposed to point to Jerusalem, but actually just points East - we've made a real one which can point wherever you want to!


Monday, 2 May 2016

A bigger screen for you Microbit (max7129)

While the Microbit's built in "screen" is great fun its a little limited... 5x5=25 pixels, which was great for our compass, and spirit level, and there's a fun snake game in the Sniff/examples/Microbit folder, its just a little bit frustrating. What if we could move up to something with a little more real estate:

The easiest way to do that would be an 8x8 led matrix. That may not sound like a lot more, but 8x8 is 64 pixels - more  than 2.5 times as many. Now in principle you could try and wire up one of these from scratch, but you need 16 pins to do it... instead get a board with a max7129 chip on it

These cost about £1.50 and are really easy to connect. They use 5 pins: GND, VCC (power - 5V or 3V is fine), Din, Clk and CS. Now if you read the previous post on using SPI some of those should sound familiar. However as this is an output device, there's no reason for it ever to talk back to the "master", so we don't need a MISO. As there's only one data pin now they've labeled it Din, rather than MOSI. So just connect up to the SPI pins CLK->13, Din->15. Remember you can use any pin you like for CS, but D16 is a good choice. Now to use it in Sniff just make a device:

make spi device
make display maxMatrix device D16
make displayX number
make displayY number

make displayColor number

When I've made the device I've specified the CS pin. If this looks little like what we had when we made the microbitDisplay device then it should. All the commands we used to draw on the 5x5 built in screen work exactly the same on the larger 8x8 display:

when start
.set displayColor to 000
.tell display to "clear"
.
.set displayColor to 000
.set displayX to 1
.set displayY to 1
.tell display to "move"
.set displayX to 8
.set displayY to 8
.tell display to "draw"

There's no need to call "tick" like we did on the microbitDisplay as the hardware handles that this time. Otherwise you just need to tweak your code to make use of the extra pixels.

You might notice that the maxMatrix board has pins on the top as well as the bottom... They're outputs, and if you connect them to another identical board they'll act as a single large display. In fact Sniff will let you connect up to four boards to make a screen which is 8 high and 32 wide (though you probably shouldn't try powering  that from the microbit). Now our original scrolling text is a giant message board!


Sunday, 1 May 2016

SPI Explained (connecting SD cards to the Microbit!)

Once you've got past the basics of flashing LED's and using the built in i2c devices on a microbit, the next thing you'll probably wonder what else you can connect to it...

Quite a lot of the cool things you might want to connect use "SPI", which is quite a lot like I2C, just different - in the same way that firewire, thunderbolt and USB are all different but do similar kinds of things. Like i2c it can be a bit scary to hook up at first, but its actually pretty easy. 

In addition to power (and earth) an SPI device will typically use 4 wires. Two of these are mysteriously labeled MISO and MOSI, but in fact they're really simple: 

MISO: Master In, Slave Out
MOSI: Master Out, Slave In

For our purposes the Master is the computer (Microbit) and the Slave is the thing we want to connect. MOSI sends data from the computer to the device, and MISO sends data from the device back to the Master. See... it really is easy.

The third wire is Clock, and that just makes sure that the two ends are properly synchronised. On the Microbit pin 13 is clock, 14 is MISO and 15 is MOSI. On Arduino they're on pins 11,12 and 13.


Remember how we said SPI is like USB... well just like USB you can connect lots of things to SPI at the same time. However the microbit needs to know which device its talking to. For that we need the final wire CS - Chip/Circuit Select. You can actually use any pin you like as chip select, but pin 16 is generally going to be the best choice on Microbit, as its sitting there right next to 13,14,15 not doing anything very much!

If you want to connect multiple SPI devices at the same time, then that's totally OK - just share the CLK, MOSI, MISO connections and give each their own CS connection.

So what can we connect? Well one of the most common SPI devices is an SD card reader. In fact there's actually no such thing as an SD card reader - its really not much more than a connector between the card and the computer. SD cards actually know how to talk SPI!

You can get on of these for about £1 on eBay, (search for "arduino sdcard reader"). SD cards operate at 3.3v and actually a lot of the ones sold for Arduino might damage the card when you run them at 5V, but the Microbit is 3.3v so we're good! (for Arduino get something like the Data logging shield or ethernet shield which has a card reader built in, along with the extra circuitry to access it safely, rather than one of these cheap stand alone boards).

There'll be 6 pins: 0v/Gnd, 3V/Vcc, MISO, MOSI, CS, and CLK. Just hook them up as described above and you're good to go!

If you've installed Sniff already, then you'll find the code to access the SD card in examples/Embedded. It's in the Embedded, rather than the Microbit folder because it runs essentially unchanged on Microbit, Arduino, Propeller or anything else you might want to try it on.

make spi device

make sdcard device  D16
make sdcardValid boolean
make fileSystem device
make fileData string
make fileOK boolean


The code begins with some definitions. We need an SPI device to create the SPI bus, then an SD card device. You probably need to change the pin number here to correspond to the Microbit.  On the Arduino SD cards generally use either D10 or D4 as their CS pin, but we want to use D16.

The example code starts with some diagnostics:

when start
.wait 1 secs
.say "starting"
.
.repeat until sdcardValid
..say "insert card!"
..wait 1 secs
..tell sdcard to "init"
.
.say "Card OK"
.
.if not fileOK
..tell fileSystem to "init"
.
.if not fileOK
..say "File System Failure"
.else
..say "ready"


This tests that the card reader is working, it has a card in, and that there's readable data on the card - you don't need to include any of this in your own code, but its good for testing. If this doesn't work then first check your wiring. If you're confident that its correct then you probably need to format your card. This is actually the hardest part! The Microbit is pretty limited in the complexity of code it can run, so it uses the FAT16 file system. This is OLD, so can only handle cards up to 2Gb. Your desktop machine will read FAT16 fine, but it might not be able to format FAT16. Or if it does format them, it can do a really bad job.  If you've got access to an Arduino, then use this sketch to reformat your cards, and theres a good chance that magically everything will start working.

Once you get past that hurdle, everything is nice and simple. The SDcard demo checks if the file "newFile.txt" exists:


when checkExists
.set fileData to "newFile.txt"
.tell fileSystem to "check file"
.if fileOK
..say "Found File"
..broadcast readTest
.else
..say "File Not There"
..broadcast writeTest

If it's there then it does a read test, and if its not it does a write test. 


when writeTest
.set fileData to "newFile.txt"
.tell fileSystem to "create file"
.tell fileSystem to "start write"
.set fileData to "Hellow World!"
.repeat 3
..tell fileSystem to "write string"
.tell fileSystem to "end write"
.say "End Write OK"

Writing data is really easy. We set fileData to be the filename we want, call "create file" to make it, then "start write" to prepare it for writing. The we loop three times writing "hello world" into the file, before telling it we're done.


when readTest
.set fileData to "newFile.txt"
.tell fileSystem to "start read"
.repeat until not fileOK
..tell fileSystem to "read string"
..if fileOK
...say fileData
..else
...say "EOF"
.tell fileSystem to "end read"
.say "End Read OK"
.set fileData to "newFile.txt"
.tell fileSystem to "delete file"


Reading it back is pretty similar, but this time we "start read". If its there and readable, then fileOK will be true, so we go around the loop, calling "read string". If that works then fileOK is true, and we print out what we got. Keep going until it fails, then "end read" to say you're done.

The read test also deletes the file when its done, so each time you reset the microbit it will alternate between doing a read test and a write test!

An SD card is a really cheap and easy way of adding permanent storage to your project, so you can make something that logs data overnight, or even for weeks. It's really easy to store data in a CSV file, and then just take the SD card to a computer and load it into a spreadsheet.