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, 5 June 2014

Back To The Screen (Part 2: Graphics!)

A few weeks ago I did a blog post on connecting text based displays to Sniff hardware, and said I'd get back with another post on displaying graphics. While the Arduino isn't exactly a graphics monster, its actually pretty easy to hook a display and start drawing images.

Probably the cheapest way to get started is with a Nokia 5110 LCD display (shown on the left). These cost only a couple of pounds. These were used in old mobile phones, and now they're getting pulled out of broken phones, mounted on simple PCBs and sold cheap on ebay! The only downside to this is that quality is a bit hit and miss. Also if you're planning on connecting one to an Uno make sure that you get a version that's been set up to work on 5V.

For Arduino, Sniff uses the following pins:

DC    5
DIN  4
CLK  3

You also need to connect the CE (Chip Enable) pin to Gnd. (If you need to use this, then you'll know what to do with it!).

make nokia device
make displayX number
make displayY number
make displayColor number

To add the display to your code, we make a device, and create the variables required. We can then 

when start
.set displayColor to 000
.tell nokia to "clear"
.set displayColor to 777
.set message to "Once upon a time there were 3 bears..."
.set displayX to 1
.set displayY to 0
.tell nokia to "show"

This just displays a text message. It's a little more fidley than on a pure text display, as we need to first clear the screen, and say where on the screen we want to place it by setting displayX, and displayY (0,0 is bottom left).

We cal so need to specify the colour to use.  This is a black and white screen. 0 is "off" and anything else is "on", but more generally we use a three digit number, there each digit is between 0 and 7. The first digit is red, the second green and the third blue. This is a little clunky, but it's one of the simplest ways to do it. As note the spelling of displayColor - get used to american spellings. It's not pretty but pretty much all code uses that spelling, and when writing code its important to be consistent.

To draw some lines we use "move" and "draw":
.set theta to 0
.repeat 72
..set displayX to 50
..set displayY to 20
..tell nokia to "move"
..set displayX to 50+30 * cos of theta
..set displayY to 20+30 * sin of theta
..tell nokia to "draw"
..change theta by 5
.wait 1 secs

This draws a circle of radiating lines.

..tell nokia to "setPixel"

does exactly what you'd expect.

Once final command that's not immediately obvious is "hfill":
.set displayY to 10
.set displayX to 10
.tell nokia to "move"
.set displayX to 120
.tell nokia to "hfill"

This draws horizontal lines. The code to draw arbitrary lines is quite complex, while drawing horizontal lines is much faster. That means (for example) if you want to draw a filled in rectangle you can hfill the rows much more quickly than if you tried to draw them.

An alternative display with similar performance and price are the 128x64 OLED displays which are available from various sources (on the right of the top image). These come in i2c and SPI varieties, but we need the i2c version. The great thing about that is that it only uses a couple of pins. However avoid the "Crius" versions of these screens - they have a couple of faults which make them unusable without mod'ing the hardware.

While still black and white, and limited resolution, these are brilliantly sharp. The only real downside is that they're small - less than 1" on the diagonal. That's ideal if you want to make some kind of wearable device like a watch, but even compared to the Nokia 5110 screen they're small.

To make them work just plug them into i2c (check the voltage for which version you have), and use the same code as above - just replace nokia with oled. This works for all of the graphics screens - just use the appropriate name.

Next up we have the tft shield, that's currently available from dozens of sellers on ebay. It's identifying features are some icons drawn on the bezel of the screen (home, book, email, camera, video?). Technically the important thing is that these are using the spfd5408 chip. Build quality on these is a little flakey - again it looks like they were made for something else, so these are surplus stock that's being pushed out the back door, but image quality is amazing for the price: 16 bit colour for less than £5.

They're a little slow, but they're plenty fast enough for displaying information - just too slow for games or animation. 

The biggest disadvantages of these is that  they use every pin on the board except A5 (and the code only runs on an Uno). However that means we can plug in a sensor of some kind, and plot results - I used this on the Coffee, and Heartbeat experiments.

All of the screens so far have the advantage of being cheap. At the other end of the scale there's basic support for Gameduino 2. This is a great looking screen, that's absolutely huge by comparison to the others. However it costs around £60. For that price you not only get a nice screen, but some horsepower to drive it. There's a GPU chip built in that makes most operations pretty much instant compared to the other screens. Unfortunately to make use of this performance, requires that the screen is redrawn in full each time, so typically you would use the standard Sniff drawing commands to draw, then call "swap" to push that drawing to the screen. You then need to redraw everything again for the next frame. This support is still a work in progress...

The final way to display some graphics is to use a TV screen! It's pretty obvious that this would work on a Pi - use the device called "framebuffer" and it will draw on your video screen, but it turns out the Arduino can generate a TV signal too!

Make up a phono cable as shown in the picture (hint - you can use two 1K resistors in parallel to make a 470, so you can make the thing with 3x1K's. I've got loads of 1K's so I use this trick a lot!).
On an Uno, connect Sync to pin9, and video to pin 7, and you're good to go! Just use the avrVideo device and start drawing. Resolution is quite limited, as there's not enough memory to store more detail. It also works on a Mega2560, but here you need to connect Sync to pin 11 and Video to Pin 29. This gives a slightly higher res display.
So there you go - 5 ways to do graphics on an Arduino (or Pi) in Sniff.

No comments:

Post a Comment