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.

Saturday, 30 April 2016

Driving Motors (from Microbit)

One thing I've always thought was pretty dumb was all the Raspberry Pi crowd building robot buggies using the Raspberry Pi - not because its a good thing to do, but because they think a Pi is the answer to everything! The Pi is a terrible boar to base a buggy around. It's expensive (comparatively), difficult to power, unreliable, and its actually just not very good at the task (lack of HW PWM, and timing reliability). The microbit however is ideal.

Kitronik sell a buggy kit for a £25 (plus £5 postage), but you can get the same motor, wheels, and a much nicer chasis for about about £7 on eBay. To make the cheap one work all you need is a motor driver board. They also sell one of those for £11.50 (its included in the buggy kit). It's a nice looking board. but you can get exactly the same functionality using a generic board which costs £1.50. The only catch is you will need a breakout board so you can hook stuff up to the microbit, (kitronik £4.50), but you'll need one of those anyway for other projects. It's also going to get a bit messy, so the Kitronik motor board is probably a good choice if you want an all in one solution, but if you've already got some motors, and a breakout then the £1.50 eBay motor driver is a great addition to your parts box.


This is the sort of board you want (eBay: Arduino motor driver). They can look a bit intimidating to hook up as theres lots of wires but they're pretty obvious.

Starting at the end, the screw terminals on the left and right are where the motors go. Just connect the two wires from the motor into a terminal pair and tighten them up. Don't worry about connecting them the right way - get it wrong and your motor runs backwards. You can either fix this in software, or just switch the wires around (in workshops the first thing I get kids to do once they've hooked up a motor is check its direction, and reverse wires if  necessary so everyone's idea of forwards is the same!).

The terminal block with three wires is marked (from left to right) 12v, Gnd, 5V. Don't worry that we won't be operating at these voltages... 12v is a maximum(ish). If you're using the "yellow" motors, then they can run up to about 6v, so connect a power source/batteries of 5-6v between the left input, and to the Ground pin. The left pin provides power to the motors, but it also provides a lower voltage supply to the rest of the electronics on the board - that's what the 5V is for. If you're using a microbit DO NOT CONNECT ANYTHING ELSE TO 5V!

That's the heavyweight side hooked up - now to look at the controller side:


There are four pins on the board labeled in1-in4. (There are also a couple of pins labeled en-A and en-B butthey should have jumpers on them, and we can ignore them) - these need to be connected to four output pins on the Microbit. If you just want to control one motor you could connect them with croc-clips to D0 and D1, but i'm using the MB^5 (MicroBit Breakout Board Breakout Board) I build in the last post. It exposes pins 13-16 as a row of headers which is perfect for this. I just connected them straight across. You could connect them straight to a regular microbit breakout board - you'll just spend more time counting/checking pins. You'll also note there's also a ground connection from the boards GND pin to the 0V pin on the Microbit. DO NOT ATTEMPT TO CONNECT POWER BETWEEN THE BOARDS... you'll destroy your Microbit.

With that in place we're read to do some software:

make m1fw digital output D13
make m1bw digital output D14

when start
.forever
..set m1fw to yes
..set m1bw to no
..wait 1 secs
..set m1fw to no
..set m1bw to yes
..wait 1 secs

Here I've set up a single motor. Microbit pins 13/14 are connected to in1,in2 of the motor board, which control out1/out2 which are connected to what we'll call motor 1.

Driving a motor using two pins can be a bit confusing, but a little creative variable naming goes a long way. I've called the two output m1fw and m1bw: motor 1 forwards and backwards. So to go forwards, set m1fw to yes, and m1bw to no. To go backwards m1fw is no, and m1bw is yes. To stop you set them both to no (or set them  both to yes if you want, but no make more sense).

We could do the same for motor 2, but we can be a bit more clever.

make m2fw analog output D15
make m2bw analog output D16
make speed number
when start
.forever
..set speed to sin of (timer*100)
..if speed>0
...set m2bw to 0
...set m2fw to speed
..if speed<0
...set m2fw to 0
...set m2bw to -speed
..wait 0.1 secs

If you remember when we flashed an LED we used an analog output to flash the LED very fast, and it looked like it was dimming. We can use the same trick to control the speed of our motor. Pins 15/16 are driving in3/4 on the board. I've created a variable called "speed", which I set to something between -1 and +1, which are going to represent full reverse and full forwards. I use a Sin wave just to create something interesting.

If speed is positive we want to go forwards, so set m2bw to 0, and m2fw to how fast we want to go forwards. If we're going backwards, then M2fw is 0, and m2bw to -speed (because speed is negative, so -speed is how fast we go backwards).

The "turning on and off fast" can break if we try and change the speed to often, so we add a 0.1 second delay in there just to keep things running smoothly. If I was using this in a bigger program I might write an update motor script to handle all of this and make everything a bit cleaner:


make speed number
when updateMotor
.if speed>0
..set m2bw to 0
..set m2fw to speed
.if speed<0
..set m2fw to 0
..set m2bw to -speed

when start
.forever
..set speed to sin of (timer*100)
..broadcast updateMotor
...wait 0.1 secs

If you like you can even write it as:

make m2fw analog output D15
make m2bw analog output D16
make speed number
when start
.forever
..if speed>0
...set m2bw to 0
...set m2fw to speed
..if speed<0
...set m2fw to 0
...set m2bw to -speed
..wait 0.1 secs

when start
.forever
..set speed to sin of (timer*100)


While this isn't the most efficient system it is the most "scratch-like". We've got one script updating the motor speed every 1/10th of a second, so the "main" program at the bottom can just do its thing, and set the speed it would like the motor to be running at, without worrying about how that happens.

Hopefully as the microbit ecosystem matures we'll see a whole range of cheap boards but there's a whole load out of bits on ebay already that are easy to hook up once you've got some kind of breakout.

Friday, 29 April 2016

The Microbit Breakout Board Breakout Board

The core strength of the microbit is that it has a bunch of stuff built into it. You can connect external stuff up to it, but realistically beyond the odd LED its not much fun. The edge connector is really cool looking, but its a pain to actually work with. So start by enjoying what it can do first. Realistically if you're going to start hooking up significant amounts of external hardware, then consider moving to  an Arduino, or perhaps the Nucleo N411RE. Sniff will run identically on these platforms.

In the future I can imagine a rich ecosystem of equipment that you can just plug a microbit into. You can code on your own board, and then just plug it into something that has sensors and actuators on it for a specific task. That would be pretty fun, though I'm not sure its particuarlty practical.

However right now the small UK hardware manufacturers who are likely to produce such equipment can't get their hands on a microbit to work with, and with the future of the micro:bit undisclosed they can't really make plans for future products.

The one company with access to the board in advance of the release (or even following the release!) are Kitronik. They've essentially produced two key products which operate with the microbit: a motor driver board, and a breakout board. They bundle these in various forms (buggy: motor driver+chasis, "inventor kit": breakout + breadboard). The motor board is a great idea, though a bit expensive at £11.50 - an Arduino equivalent would be about £1.50.

However the "Essential" which I expect they'll sell thousands of is the breakout board. Right now if you want to connect something to your microbit, then this is the only way to do it. I suspect over the next few weeks we'll figure out where to get hold of the parts to make these ourselves, but right now the only way to tap onto the edge connector reliably is to order one of these. These sound great value, but the headline price doesn't really last long: £2.50 sounds great, but then you decide not to solder it yourself, then add vat, then add postage and your £2.50 costs you £9.50! But they're the only game in town!

So what do you get for your £9.50? Its a simple board with an edge connector to plug the Microbit into and 2 lines of 20 pins. The 20pins carry the signals from pin0-16 plus 1x3v power and 2x0v ground pins. If you check the microbit docs you'll see that it actually has pads numbered up to 22, but 17,18 are 3V, and 21,22 are 0V. That leaves 19, 20 which are the i2c pins. If you've done this sort of stuff before (or you followed our Microbit tutorial) then you'll know that this is used internally to communicate with the Accelerometer and Magnetometer. Presumably to stop people messing with these 19 and 20 are connected to a couple of extra pads which aren't part of the main connector and don't have any pins soldered to them. If you want to add i2c you'll need to solder the pins in yourself.

So far we have a board that's (baring the i2c) totally functional, but hooking stuff to it is a total pain. It's a breakout in the strictest sense that all the pins are now accessible slightly more easily than they were before. However its not a lot of fun to use. While the pins are numbered, there's no indication of what functions they actually perform, so you'll constantly be referring back to the docs to see which pins are used by the display, or which support analog inputs...

What we really need is a project board - a breakout for the breakout (Microbit Breakout Breakout or MBB), that turns the strictly functional kitronik boarding something that we'd actually like to use, perhaps sacrificing some of that functionality for practical usability...

The first issue was how to attach stuff to the breakout board - my first thought was somehow to make the MBB plug into the Kitronik breakout and sit on top of it, perhaps using something like this:
However there were a couple of problems: it would leave everything at a funny angle, and I din't have one so it would take a few days to order one! Then came the breakthrough moment: I realised we needed a 40pin ribbon cable...  which it turns out is exactly what old IDE hard drives use! I had 3 in a box under my desk that were never going to be used for hard drives, and they fit perfectly.
With that sorted, we can connect a ribbon cable from the Kitronik breakout to the MBB Board (or MBBB). Now we're "in" we can layout at the MBB anyway we like.

The breakout I use most often (all the time!) is the Arduino Sensor shield V4. It's really easy to plug things into because each signal pin is part of a group of three, with gnd and power. Simple devices like servo's, LEDs, potentiometers, thermistors, speakers, DHT11's etc can be wired so they use this three pin header and just plug in.

However there's no point in breaking out ALL of the Microbits pins. We just don't need that many (or if we do then the Microbit is probably the wrong tool), and it would be confusing if we did. Also many of the pins are also used to control the screen, so it makes sense to stay away from them if we don't have to. I'm sure some project will use all of those pins for something, but at that point you probably need a custom board anyway, so that's not the problem we're trying to solve here. Instead I started be breaking out pins D0, D1 and D2 - the big ones!

The other thing I like on the Arduino Sensor shield is that it breaks out i2c on a four pin connector (0v, 5v, data, clock) and its really easy to plug stuff into it. Unfortunatly i2c isn't going to work here as its not carried on the 40pin header of the Kitronik board. If we were going direct the Microbit I'd include two sets of the i2c headers. However we do have SPI. SPI is a bit like i2c, but works in a slightly different way (think firewire Vs USB - different but doing the same job). I'll cover using it in the next post, but its broken out on the Microbit as pins 13,14,15. However while these are the main 3 SPI pins, we actually need a fourth pin to act as "CS". Pin 16 is free and almost certainly has been left free for that purpose, so we use 6 pins 13-16+power and earth. If you're not using SPI, then this gives four pins you can plug stuff into, so they'd be good for a stepper motor controller.

Finally, one of the things I missed when testing the Microbit was what is technically know as ein "BLINKENLICHTEN". The display is great but actually requires quite a lot of code to get working. Sometimes you just need to flash an LED to tell the world that you're OK. According to the spec's Pin 8 is the final, completly unused pin (12 may or may not be "reserved" depending on the docs you have), so lets throw an LED on there.

And thus the design was finished. From there it was straightforwards to wire it all up, and here it is! My soldering skills are awful, so I won't show you the reverse of the board - its not pretty. I also still need to make some labels, though that's a lot less of an issue now there are less available pins.



It took me an hour or so to wire this up, but I'm pretty confident that it will save me a lot more time than that over the next few weeks.  Initial tests worked great. I was able to quickly and easily plug loads of different things in, with far more confidence than using the regular breakout. If you're looking to use the microbit to teach electronics, then this exactly what you need. If someone out there has PCB facilities, they could lay it out in minutes and it would cost next to nothing to make on a small commercial scale.

There are few changes I'd make if this were a commercial product, but for now I'm really pleased with it.

Thursday, 28 April 2016

Release 27: Micro:bit!

Last week we took the unusual step of putting out Release 27pre, as we were keen to get Microbit support out as quickly as possible. We've now spend quite a bit of time with it, and have made a few minor fixes and changes. It's now pretty stable, and we've been able to test it with quite a bit of external hardware, including the Nokia 5110 screen, an SD Card reader, and a dht22.

Before you can use Sniff with Microbit you'll need to install Yotta from mbed.org. This is really easy on Mac and Windows. For Linux it may be more of an adventure! Let us know how you get on.

We've also produced a series of Tutorials for the Microbit, taking you from never used Sniff, through to using all the features of the Micro:bit.

We're really excited about the new platform, so have fun with it, and get in touch to let us know how you're getting on.

Release 27 is now now on the Downloads page.

ian@dctsystems.co.uk


Wednesday, 27 April 2016

Sniff From Scratch #6: Microbit Compass

In addition to the accelerometer the Microbit also includes a Magnetometer. It's two main uses are either to make a compass, or to detect the movement of metal objects around it. While in principle its pretty simple there are couple of gotchas:


make i2c device
make magnetometer mag3110 device
make xMagneticField number
make yMagneticField number
make zMagneticField number
make heading number

start by making an i2c bus (you only need this once even if you're using the accelerometer and the magnetometer), and adding a mag3110 device. This is the proper name for the chip that the Microbit uses.

Now we can just tell it to "read" and we get our results back:

when start
.forever
..tell magnetometer to "read"
..say [ xMagneticField ]
..say [ yMagneticField ]
..say [ zMagneticField ]
..say join "Heading " [ heading ]
..say ""
..wait 1 secs


The x/y/z values are the measured strength of the magnetic field on each axis and the heading is just calculated from the x and y values. You could calculate it in Sniff but while the maths is easy, its actually surprisingly hard to code (try it and check it your results agree).

To turn that into a proper compass we just use the angle of heading to draw a needle:

make i2c device
make magnetometer 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"

when start
.forever
..tell magnetometer to "read"
..set heading to heading/45
..set heading to round heading
..set heading to heading*45
..
..set displayColor to 000
..tell display to "clear"
..
..set displayX to 3-2*cos of heading
..set displayY to 3-2*sin of heading
..tell display to "move"
..
..set displayColor to 111
..set displayX to 3
..set displayY to 3
..tell display to "draw"
..set displayColor to 777
..set displayX to 3+2*cos of heading
..set displayY to 3+2*sin of heading
..tell display to "draw"
..
..wait 0.1 secs

The only "clever" bit here is that to get nice straight line on the low res display, we round the angle to the nearest 45 degrees, but dividing by 45 (to see how many 45's we have), rounding to the nearest whole number then multiplying back again.


So far so good... however you might find that you get some strange results. The thing is that the magnetometer is sensitive to magnetic and electric fields, but then we've gone and put on a circuit board surrounded by metal and electricity! While this is definitely a problem, its not as bad as it sounds because those bits of metal don't move relative to the chip, so we can calibrate them out.

By default the compass is constantly calibrating, so if you just write your code, you might find that it doesn't work properly for a few seconds, until its taken a few readings and the calibration settles down. Turning the microbit around while this is happening will help a lot, and it will fairly quickly start producing good results.

Where this can backfire is if you place the microbit in a changing magnetic field. The calibration method assumes you're in a constant field and that changes are due to the chip rotating. If you want to measure changes accurately, then you need to calibrate before you start measuring. The variable compassCalibrate is normally just set to yes, but if we want more control then set it to yes, take some readings to calibrate the system, then turn off calibration, so that from then on the calibration if fixed. This will give you a more accurate/reliable measurement of changes in the field (which might otherwise be partially calibrated out).

make compassCalibrate boolean

when start
.set compassCalibrate to yes
.
.say "Calibrating"
.repeat 50
..tell magnetometer to "read"
..wait 0.1 secs
.
.set compassCalibrate to no
.
.forever
..tell magnetometer to "read"
..say [ xMagneticField ]
..say [ yMagneticField ]
..say [ zMagneticField ]
..say join "Heading " [ heading ]
..say ""
..wait 1 secs

With a bit of tweaking you can use this to detect metal objects moving near the microbit.


Electric motors also mess with the magnetic field, which can be both a win or a loss - you can detect when devices turn on and off just by putting the microbit close to them. However it also means that if you have a robot buggy and want to use the magnetometer to detect which way its pointing (very handy, as you can now make precise 90 degree turns!) make sure you place the microbit well away from the motors.

Tuesday, 26 April 2016

Do the Microbit shake!


In the recent tutorial series we used the accelerometer on the Microbit make a spirit level. By detecting which way is down we can use it as a sort of virtual joystick, to make up for there only being two buttons. If you've looked at some of the block languages running on Microbit you might have noticed that they also have a "shake" function, which allows a script to be triggered when the microbit is shaken vigorously from side to side.

That's pretty handy. Wouldn't it be nice to have some code run whenever you do a shake? Well yes it is handy but how does it actually work? Sniff doesn't have shake detection built in, but its really easy to add it. By doing it in Sniff we actually get to see how it works, rather than it being buried away in a C++ module. In general its better to do the work in Sniff than having a "magic feature" (much as Sniff can handle scrolling text in the language without requiring specific runtime support). While this might look a little complex, its actually far simpler than the way it has to be done in the Microbit runtime.

make i2c device
make sensor mma8652  device
make accX number
make accY number
make accZ number


make shakeStart number
make shakeCounter number
when start
.set shakeCounter to 0
.forever
..set shakeStart to timer
..repeat until accX > 0.5
...tell sensor to "read"
..repeat until accX< -0.5
...tell sensor to "read"
..if timer-shakeStart<0.5
...change shakeCounter by 1
...if shakeCounter>2
....broadcast shake
..else
...set shakeCounter to 0


Firstly we set up the accelerometer. We're going to need two extra variables - one to count the shakes, and another to time them. We initialise both (to zero and the current time respectively). Then we wait for the shakes to start. We read the sensor until the acceleration is greater than 0.5 then wait for it to be less than -0.5. This represents one cycle of a vigorous shake.

Then we use the timer to see how long that took. If it was less than 0.5 seconds then it was actually proper back and forth shake rather than just a couple of separate movements, so we count that as one step of a shake sequence. If we ever get more than two of these, each within 0.5 seconds of the previous ones then we actually have a real shake, so we broadcast shake, telling the rest of the code that something happened. If a single shake takes more than 0.5 seconds then the sequence is broken so we reset the count.


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


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

when shake
.set displayColor to 777
.tell display to "clear"
.wait 1 secs
.set displayColor to 000
.tell display to "clear"

Here we have some code that waits for the shake. When it gets it, it flashes the screen for one second.

By coding the shake in Sniff we gain lot of benefits - its now maintainable, and customisable by Sniff programers, so if for example you find the shake requires to vigorous a movement for your liking, you can reduce the acceleration threshold. If you'd prefer a vertical or an in/out shake then change the axis. If your getting false triggers you can increase the number of cycles required to count as a proper shake.

Best of all we can see exactly how it works. There's no hidden magic function that just makes it happen. After all isn't the point that we might actually learn something?

Monday, 25 April 2016

Sniff from Scratch #5: Microbit Spirit Level

Now that we've used devices to access the Microbit Display, the next step is to look at the other sensors in the Microbit, the simplest of which is the accelerometer. Using it in Sniff is really easy:

make i2c device
make sensor mma8652  device
make accX number
make accY number
make accZ number


The microbit talks to the internal sensors using i2c (pronounced eye-squared-see). While this can be a bit intimidating, its really just like USB - a way of connecting the computer bit with some kind of peripheral. The Accelerometer plugs into the i2c, just like a mouse plugs into USB, so the first thing we need is an i2c device, so we can talk to devices using it.

Then we make a sensor.  The Microbit accelerometer is a chip called an "mma8652". In theory that's what is written on the top of the chip, but its too small for me to read! There's nothing particularly special about this - its just the number of the part that they chose to use. There are other chips which do the same job, and in fact you could connect one to the microbit and have two different accelerometers. Similarly you could connect an mma8652 to an Arduino or other board. That's why Sniff calls it by its proper name, rather than just "accelerometer".

when start
.forever
..tell sensor to "read"
..say [accX]
..say [accY]
..say [accZ]
..say ""
..wait 1 secs

Having made we can now just tell it to read, and we get back the acceleration in x,y, and z!

You'll see that if you hold it still and flat, then the x and y values are small/almost zero, while the Z value is either 1 or -1. That's because of physics! The force of gravity results in an effect which is exactly the same as if you were accelerating upwards at 9.8m/s/s. Imaging being pushed back into your seat in a car (or better a plane!) as it accelerates. It feels exactly the same as if you were just lying down, and facing upwards!

That means that the most common use of an accelerometer isn't to measure acceleration, but to figure out which way is down.

If we take the x/y acceleration and just plot it we can tell if the microbit is flat:

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

make i2c device
make sensor mma8652  device
make accX number
make accY number
make accZ number

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

when start
.
.forever
..tell sensor to "read"
..set displayColor to 000
..tell display to "clear"
..set displayColor to 777
..set displayX to 3
..set displayY to 3
..tell display to "move"
..tell display to "set pixel"
..change displayX by -accX*5
..change displayY by accY*5
..tell display to "draw"
..wait 0.1 secs


Here's the whole code, which uses what we learn in the last session do to drawing, and combines it with what we've learnt about the accelerometer. The only gotcha is that accX is reversed - that's just down to the way that the accelerometer is placed on the board, relative to the screen.

This actually shows a really effective use for the accelerometer as a pseudo joystick.The microbit only has two buttons which isn't enough to control a game, but using the accelerometer you can control a character in a game by tilting the board around.

Sunday, 24 April 2016

Sniff from Scratch #4 : Drawing on the Screen

So far we've covered handling inputs and outputs on the Microbit. In doing this we've introduced a little bit of Sniff, but not by teaching the language - you already know that because you've used Scratch. Rather we've focused on hooking Sniff into meaningful things, like leds and switches which is far more fun! These simple inputs and outputs are easy to handle directly in Sniff, but sometimes you need to interact with more complex devices like the microbit display.

Complex hardware is handled by creating "Devices". These are a little like objects if you've used more advanced languages. If you're fresh from Scratch, then they're just a way of wrapping up a bunch of code someone else has written and letting you easily talk to a piece of hardware. The microbit display device handles drawing on the screen.

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


Here we've made a variable (of sorts) called display, which is actually a microbit display. We've also made some other variables which we're going to use to talk to the display. Now for some actual code:

when start
.set displayColor to 700
.tell display to "clear"

Colours in Sniff are (usually) represented by a 3 digit number. If you've written HTML you'll know it uses 6 digits. Sniff is just a slightly simplified version of that. The first digit is the amount of red, the second green and the third blue. Each digit is allowed to go from 0 to 7. But wait a minute - the Microbit display can only do red? That's true, but Sniff runs on lots of different hardware with different kinds of displays. Here we're specifying 700 which is full red, but 700 is full red on all displays. It means we can take this code and run it on different hardware later, with only minimal changes.

Having set a colour we tell the display to "clear". Tell is the only extra thing that's in Sniff that isn't in Scratch. In Scratch when you want to talk to something that's not part of the core system you use an extension, but that causes all sorts of problems, as you end up with dozens of extension, and hundreds of new blocks. In Sniff there's only one "extension" - tell. It lets us send a message to the display device asking it to do something. Different devices understand different messages, but devices which can act as displays have a fairly standard set of message.

Now there's one more think we need to add to get the  display to do something: The Microbit display is actually broken down into three parts. At any time only 1/3 of the display can be lit up. In other languages there's a lot of really fancy code built into the system that automatically lights up different parts of the screen really quick so you can't see it move but in Sniff, its much simpler - we light up different parts of the screen by calling "tick". That means we need an extra script to handle that:

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

You need to include something like this in every Sniff program that uses the microbit display. It might look a bit clunky when you start out, but its actually quite clever - Sniff is doing the work for us that would be much harder to do in another language. You can even add a delay into this loop, and you'll see the different parts of the display light up, so you can really understand how the display works. If your program isn't displaying, then check you've remembered to include this.


The next thing to do is try setting some individual pixels:

when start
.set displayColor to 000
.tell display to "clear"
.set displayColor to 777
.set displayX to 3
.set displayY to 3
.tell display to "set pixel"

This just sets the middle pixel to be fully on.

when start
.set displayX to 1
.repeat 5
..set displayY to 1
..repeat 5
...set displayColor to (displayX+displayY-2)*100
...tell display to "set pixel"
...change displayY by 1
..change displayX by 1

Here we set every pixel on the screen with a colour based on its position. This forms a gradient, with the bottom left pixel being off, and the top right being fill on.

You can draw lines with "move" and "draw":

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

Finally we can display text:

when start
.set displayColor to 000
.tell display to "clear"
.set displayX to 1
.set displayY to 1
.set displayColor to 777
.set message to "hello"
.tell display to "show"

This tries to write "hello" on the screen. Unfortunately the microbit screen is rather limited, and all you'll see is the "h" - the rest doesn't fit. To make it fit we'll need so scroll it around:

when start
.set message to "hello"
.set displayY to 1
.forever
..set displayX to 1
..set offset to 1
..repeat until displayX<1
...set displayColor to 000
...tell display to "clear"
...set displayColor to 777
...set displayX to offset
...tell display to "show"
...change offset by -1
...wait 0.1 secs


We start by drawing the text at 1,1 and then change the offset, so the next time around the loop its printed one pixel to the left. After you've drawn some text, displayX tells us where then end of the text is, so when displayX is less than 1 we know we've scrolled the whole message off the left hand side of the screen, and we start again.

You can easily add this script to any of your Sniff programs, so that a message constantly scrolls. In your main script you can measure something and then just assign the results to message, and it will scroll. If you like you could use a slightly different version that just displays the message once:

when showMessage
.set displayY to 1
.set displayX to 1
.set offset to 1
.repeat until displayX<1
..set displayColor to 000
..tell display to "clear"
..set displayColor to 777
..set displayX to offset
..tell display to "show"
..change offset by -1
..wait 0.1 secs

Then in your main script

when start
.set message to "scroll me"
.broadcast showMessage
.say "there's a message scrolling!"

We're starting the showMessage script by calling broadcast,  and just like in Scratch the showMessage script runs at the same time as the main script continues. If you want to wait for the message to complete scrolling just use broadcast showMessage and wait.

This might look like a lot of code just to display a piece of text, but look at what we're actually doing. All of the scrolling, and timing is handled in Sniff. Scrolling a message continuously on the screen while doing another calculation is very hard in most languages, but in Sniff its easy. Of course Python on the microbit has a "displayScrollingMesssage" function built in which does all of this for us, but that's because actually doing it in Python would be too hard. Doing it in Sniff means you can see how it works, and change it around. How about making the text bounce left to right, then right to left?

While we've been specifically talking about the Microbit display, you can use exactly the same code to draw on all sorts of different display hardware, from and LED matrix connected to an Arduino, and GameBoy advance screen, through to an on-screen window on a Mac, or PC. They all use the same commands, so porting the code is just matter of changing the type of device you create, and then maybe adding some scaling to take into account for the different resolution.