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, 28 January 2016

Wedo Speed Trap

We've got a couple of live events coming up in the next few months, and at one of them we plan to talk about how the Picoboard, Wedo and Flotilla can be used to do "real" science experiments rather than just fun e-toys. While there's nothing wrong with fun gadgets and demo's to attract attention at some point we need to harness that interest and show that programming can solve "real" problems. (I need a way of advancing my presentation slides and all I've got is this size of pizza and a $50 interface box designed for this exact situation is neither real nor a problem). It doesn't really matter what that problem is, but there needs to be some element of writing code to do something that's extrinsically relevant (and better in some way than alternative approaches - pizza has many great features, but some kind of ir or bt remote is a way better and cheaper method of controlling slides).

This led to revisiting a few of our old experiments, and prepping to fit as many cool demo's into 30minutes as possible. On of the things we wanted to demo was the hot wheels speed trap, but based using the pico board or the wedo. Both proved pretty easy to do, but we found that the pico board doesn't deal well with updating more than about 100 times per second. It gets swamped somehow, and just gives up. This is fine for measuring longer time intervals, and we set up a tube, with a light sensor at the top and bottom to measure how long a beanbag took to fall the length of the tube. However for measuring the small intervals required of the speed trap it was too slow.

The wedo on the other hand proved to be very reliable, and worthy of a mention here.

We simply placed two motion sensors at opposite ends of a board, and measured that the distance between them. Just by being Lego we git instant "extra" value (I hesitate to say free value, as its stupid expensive), it makes a big difference just being able to stuck together some kind of structure, even as simple as this, just to hold things in place.

Then just wait for the first to detect something, then wait for the second and measure the time between them (15 studs 0.8mm per stud=12cm)



make wedo device
make wedoConnector number
make wedoValue number

make startTime number
make recordedTime number
make recordedSpeed number
make sensorDistance number 0.12

make message string 

when start
.forever
..say ""
..set wedoConnector to 1
..tell wedo to "readDistance"
..repeat until wedoValue < 0.06
...tell wedo to "readDistance"
..
..set startTime to timer
..say "go"
..
..set wedoConnector to 2
..tell wedo to "readDistance"
..repeat until wedoValue < 0.06
...tell wedo to "readDistance"
..
..set recordedTime to timer - startTime
..set recordedSpeed to sensorDistance/recordedTime
..
..set message to "time      :"
..set message to join message [ recordedTime ]
..say message
..
..set message to "speed     :"
..set message to join message [ recordedSpeed ]
..say message

The "readDistance" command sets wedoValue to an estimate of the distance in metres, so we check to see if its less tham 6cm. Then we switch to the second sensor and check that. Once we have the time, we divide that into the distance (14 studs x 0.8mm/stud) to get the speed.

If we drop a beanbag from a know height, and measure how fast its going when it passes the beam we can use the equation:

Vf^2=Vi^2+2ad

As we're dropping it, its initial velocity is 0, so we can simplify and rewrite as:

a=(Vf^2)/2d

So we can calculate gravity (again!) - it came out at about 9m/s/s this time, which is pretty close.

Best of all the sensor proved to be very robust. We've used light dependant resistors to do this sort of things before, and there's always a bit of tweaking involved to get the lighting, and threshold values just right. Because the lego sensors are self illuminating and (semi) calibrated, they work without requiring much adjustment in a wide range of conditions. The lego sensors detect things in front of them rather than shadowing them, which is much easier to work with. They're also easy to mount, so you could use them for all sorts of things where you need to measure speed.

Tuesday, 26 January 2016

Sniff 64 Handheld Game Console

A few months ago we posted about writing a Flappy Bird  running on an Arduino, and displaying on a max7219 8x8 led matrix. We thought it as so much fun that we followed up and wrote Space Invaders, Lunar Lander, Breakout, Snake and Defender. Code for all of these is in the current Sniff release examples.

We liked it so much we decided that we needed to build some kind of handheld game console to run these that we could use as the basis of workshops. We wanted kids to be able to come in, and build their own then write a game to run on it.

What followed was a few months of intense design work. What's left is something that (as J Ive would say) looks effortless... its a very basic "obvious" design, but every aspect was deliberated over.  Here are just some of the design issues we grappled with:

The Controller

An Arduino Uno was used for the original tests, but for a while we intended to swap it out for a Nano. These are functionally identical, but smaller. We also found a screw terminal board for the Nano which in theory would make it simple to attach components semi-permanently to the board. However when we actually tried to assemble a system based on the Nano, we found the screw terminals incredibly fiddly to work with, and something we wouldn't inflict on kids! (We do use screw terminals to connect motors in our robot workshops, but they're a bit larger). With that tested and rejected we went back to the Uno!

The Screen

One of the things we learned from writing games on the red matrix was that 8x8 pixels was actually a really great size to code games on. The Arduino can handle it easily and you don't need to worry about performance. There's also something really pure about these games - there's no artwork or other asset creation. They're 100% game mechanic. However we did find that it was sometimes hard to know what each pixel was supposed to be - one red dot looked a lot like every other!

That could be solved by adding colour support, and we recently posted out findings from testing every 8x8 matrix we could get our hands on. Our favourite was the bi-colour red/green display using the tm1640 driver. These are a bit hard to find, but they give just enough colour at a price and size that we liked. The next step up would be a neoPixel solution, which was just a fraction above our budget. The cost needs to be sufficiently low that every student gets to take one home, without costing us a fortune.

Controls

The original design had several different control configurations. We quickly got a design with a thumbstick and a button, but when we started refining it into something we could make, we couldn't find a nice button that didn't cost more than the thumbstick, and the thumbstick includes a button. We then briefly considered the idea of two joysticks - one basically replacing the button. This would have been fun,  even allowing for two plays games, but it proved impossible to lay out the components in a way that would be a comfortable size and shape to hold. In any case it was just too complicated, so we simplified and just went with a single thumbstick and its built in button.

One slight niggle is that the switch in the thumbstick connects the output to 0v when the button is pressed, otherwise its open circuit. Negative logic is needlessly confusing for kids (the pin turns OFF when its pressed!), but the alternative of wiring the power to it in reverse (which would work!) is also pretty nasty. We also needed to add a pull-up resistor - its easier to solder an extra resistor to the board so that it just works, rather than to explain pullups in a workshop context.

Sound

We used a buzzer so that you can just set it to "on" to get a sound. As an alternative you could use a speaker, so that you need to send a square wave to it, but we just need a few beeps. Just having the thing beep when something happens makes a big difference to the feeling of playing a game, and while we could do more, as with the controls we were happy to go with something simpler.

Power

In the initial design we were going to use AA batteries - Probably 3 of them connected directly to the Arduino's power bus. However then we'd need to worry about getting the right polarity, having some kind of power switch, and it was difficult to find a layout for the case which would hold batteries. We also considered using a USB power pack - the sort that are meant for recharging your phone when it goes flat, and you're away from home. These work great and are very cheap, so we will probably bring some along to the workshop, but in the interested of simplicity we decided to stop short of building a power supply into the design. We can power via the USB port - not exactly portable, but you can always use an external USB battery.

Physical Assembly

A big part of this project is that we wanted something that was relatively solid and robust, while still being "made". We spent hours trying to work out how to juggle all the parts into something that would feel right, and many of the decisions made for the components were influenced by whether we could put them together and lay them out nicely (and cost effectively).

The easiest way to construct a custom case was from two layers of 3mm acrylic - a base to hold everything and a top layer to protect it (we did consider some designs with three layers but again it added to complexity). The base could be coloured, but top clear so that the screen could be underneath it. We included mounting holes for that Arduino, as it has a well defined spec, but the rest of the components are attached with double sided foam tape. This is easily strong enough to hold everything in place and avoids the problem that the screen lacks any mounting holes, and each batch of joysticks we buy has the holes in different places!


The final piece of the puzzle was making it as easy as possible to wire all of this up in a way that would be easy to do in a workshop, but still relatively robust. The Uno isn't really designed for this as is has female headers. Male header pins, and female jumper cables are much stronger than female headers, and male jumpers.

The screen requires 0v, 5v, plus two data pins, and comes with female jumper cables. Our first trick is to attach these to the Arduinos ICSP pins!

The cluster of six pins at the end of the Uno (that you probably never use) can be used to program the board, but they're actually just pins D11, D12, and D13 broken out. We chose to use pins 11 and 12 to attach the screen so that we could connect them here rather than in the usual female headers.

The added bonus is that not only are they stronger, and use the supplied cable, but they're lower than the regular headers, so this makes the whole device thinner. This is important if we mount the joystick on the base plate and poke it through a hole in the top plate.

Unfortunatly the Uno doesn't have any other male headers so we need to get really creative... We took a sheet of strip board 9 strips wide, and soldered two sets of 4 straight pins and two sets of 4 angled pins on to it. 



The straight pins will fit perfectly into the analog and misc/power headers, with the angle pins pointing inwards and down so they take up no extra space. Then we can easily attach female jumper cables to them, making a simple, secure and low profile connection.

The joystick connects to A0,A1,A2 0v and 5v, leaving a spare 0v and A3 to connect the speaker to! The joystick can use a regular strip of female jumper cables so the only soldering we have to do is to make up the angle connector, and solder some headers onto the speaker. This is a big deal when you have to make up a batch of components before a workshop!

With everything mounted and connected we just have to attach the top sheet of acrylic using spacers and we're good to go!  We used 25mm spacers for the prototype, but that leaves plenty of space, and we're using 22mm for the next batch (20mm would probably be OK too!).

And here it is...

After an innuendo packed brainstorming session we completed the project by picking a name for our creation. We've named it the Sniff 64, or S64 for short. After all it does have 64 pixels.

Code to run on it is included in the examples/Embedded/maxGamer folder in the current release. The code should be set up for the "official" hardware, but if you want to run it on a different screen you should just have to change the first few lines of code.

We put Snake on it and left it "lying around" near some kids, and it proved very popular.

If you'd like to build on then the details here should make it pretty easy to put one together yourself.  The only "tricky" part is getting the acrylic cut - if you've got access to a laser cutter, then its pretty easy (I'll post the DXF here once its final-final, or get in touch). Otherwise you can just mount it to any single sheet, and forgo the top layer, or get creative see what you can come up with.

Friday, 22 January 2016

Fake "PSP" Gameboy Advance Emulator

One of the goals of porting Sniff to Gameboy Advance was to get games running on something that felt like real game hardware. But what should you do with your GBA files once you're done?

Well the best thing is to get yourself a real gameboy advance, and a "Flash Cart". These are special GBA cartridges with and SD card slot, so you can simply put your game onto them. Then you can play them pretty much as if they were a real game. That's pretty neat. Unfortunately Flash Carts have become harder to find as the GBA becomes increasingly obsolete.

However in our regular trawls of the internets flea markets we came across an interesting device that looks like a PSP. However instead of playing Sony games they run a Gameboy Advance emulator! While that's not as cool as running on the original hardware, they are "real" handheld game consoles that look the part, and include both built in storage (so you can download games over USB) and a microSD card slot, so you can put games on that.

Best of all they cost under £20, so we ordered one to find out what they were like!

Within a couple of weeks one arrived direct from China. It came in a fun box, and included a set of headphones and  a USB cable but no charger, so we plugged it into a computer to charge. While it was charging we checked it over - I saw a review complaining it felt cheap and plastic... newsflash: it IS cheap and plastic. Anyone who is surprised by that I don't know what they were expecting, but with any realistic level of expectations its a pretty solid for the price. The screen and feel isn't as nice as more expensive consoles, but its decent enough. Mine appears to have a stuck pixel, but then again one time I had a stuck pixel on a new MacBook Pro (I wasn't happy when I was told it was "within tolerance", and shouted until I got a replacement) - in this case I'll live with it.


Within a few minutes it was charged enough to power up and gave me the option to operate in disc mode, charge or charge and play - so of course we chose charge and play.

The thing comes loaded with dozens of commercial games... Mostly GBA, but some other consoles are supported too. A lot of them seem to be odd street fighter/mortal combat clones in a variety of languages (including Japanese, Chinese, and French!). Firing them up and they mostly play pretty well. While most of them are pretty lame, there are couple of prime western titles mixed in there. One strange feature is that even though both the GBA and this device have shoulder buttons, the GBA shoulder buttons are mapped to triangle and square. Select on the device exits the game, and the right shoulder button acts as GBA select. It's all a bit odd. There seems to be some suggestion that the keys can be remapped, but I couldn't figure out how.

It's really hard to take pics go the screen!

Outside of games circle seems to be the "Activate" button, Cross is back, and square is change - this is odd, but works OK  once you're used to it.

However we're not here for the pirated games! Really... we're not! In fact I could see them being a serious distraction if we try and use these for workshops. Some of the "built in" games are actually on the internal storage, and can be copied to a computer, then deleted to free up space, but a good chunk of them are part of the firmware, and can't easily be removed.

At this point we found we couldn't turn the thing off while plugged into a power source... very odd. Also to turn it ON when not connected you need to turn on the power switch, and press and hold start! Well now you know!

Anyway we put the thing in USB storage mode, and it appears as mass storage. There's a folder called games, so we made folder called Sniff inside that, and dropped in Bounce Out, Asteroids and Catch the Flowers (we'll talk about porting them to GBA in a future post).

Ejecting the disk, the thing powered into its normal mode, and we were off! Selecting Games showed the Sniff folder and we selected each game... They all ran perfectly!!! In fact  they felt smoother than when we ran then on openEMU on my Mac. This might have been helped by the smaller screen, and the feel of a real game console, but they worked great.


One gotcha is the screen resolution... It's higher than a GBA. More problematically its not an exact multiple. There are therefore two ways to run a game - either with a large black border, or "full screen". Unfortunately in full screen mode some GBA rows and columns get doubled up, while others don't. This looked pretty bad for Bounce Out, as the ball wobbled in size as it moved, and the right hand blue line almost disappeared. However for most games full screen looked pretty good.



Overall this seems to be an awesome toy. I could see us buying a set of them to use with kids in more advanced workshops in the future. Proof reading through this I note I've used the word "odd" quite a few times, and this is certainly a device that has its quirks, but the "in-house test team" who did the artwork and sound for Catch the Flowers were pretty blown away to see their own game on real hardware. For less than £20, that's got to be worth it!

Thursday, 21 January 2016

Bitmaps and Sounds on the Gameboy Advance

In the last post we covered basic drawing on the Gameboy Advance screen using Sniff. That works fine, but at some point you'll probably want to make some "real" artwork, as a bitmap, and draw it on the screen. You might also want to add sound. Both of these are pretty easy if you're familiar with Sniff on a PC, as there are GBA equivalents of the Sound and Bitmap devices.

We've covered these previously, but they're pretty easy to use. To draw a bitmap on the screen:


make display gbaScreen device 4
make displayX number
make displayY number

make img bitmap device
make fileData string

when start
.tell display to "clear"
.
.set fileData to "Castle.bmp"
.tell img to "load"
.set displayX to 100
.set displayY to 80
.tell img to "draw"


First we need too set up the graphics screen, so that we have somewhere to draw. Then create a bitmap device. Set the image name, and tell the bitmap to load it, and then we can draw it at specific coordinates on the screen.

There are a couple of differences between the Bitmap device on a computer and on the gameboy, but these probably shouldn't affect your games. Firstly the bitmap is "read only". For example in SniffPaint we actually create the contents of a bitmap device inside the program before saving it out. On GBA that's not possible due to the way data is stored. The other thing you can't do is rotate bitmaps. On a PC you can tell the bitmap to rotate, and draw it at a jaunty angle... On the GBA this was just too slow, and it was slowing down all of the drawing code, so we removed it. However in the next post we'll talk about sprites, which can do this super quick and easily!

Sounds work just the same way: 

make player sound device
make fileData string

when start
.set fileData to "WinSound.raw"
.tell player to "load sound"
.forever
..tell player to "play"
..wait 10 secs

They play 8 bit signed raw audio data at 16KHz Mono, but otherwise they behave just like on other platforms.

However there's one thing we've glossed over (and the reason I'm writing about both of these together)... On a PC the bitmap and the audio data get loaded from files, but the GBA is a games console - it doesn't have files, so where does the data come from?

It needs to be made into an "asset bundle" which gets added to your program. Fortunately we've got a bunch of scripts which make it really easy. In the folder your working in, create a folder called "Images" and put bmp files in there. Similarly create a "Sounds" folder and add ".raw" files containing the audio. Then in the main folder type "gbaBundleAssets". If all goes well this will create a file called "ASSETSBUNDLE", which will automatically be included in your game.

If you get an error about commands not being found then go to the folder examples/GBA/tools and run installIDE to compile and install the bitmap conversion tools, which are written in Sniff. These pre-process the images into the format needed for inclusion.

And that's all there is to drawing bitmaps and playing sounds on a Gameboy Advance.


Tuesday, 19 January 2016

Gameboy Advance Graphic modes in Sniff

A week or so ago we posted on how you could now make Sniff programs to run on the Gameboy Advance.While the hardware is a little old now, its a real console and running stuff on it is way more exciting than just drawing on a regular screen. So far we've just focused on getting stuff going, so today I'm going to start with some drawing code.

To draw on the GBA screen you need to use the gbaScreen device:

make display gbaScreen device 4
make displayX number
make displayY number
make displayColor number
make displayFlush boolean
make message string



Then you can use standard Sniff drawing operations to tell the screen what to do:

when start
.set displayColor to 777
.set displayX to 0
.set displayY to 0
.tell display to "move"
.set displayX to 100
.set displayY to 100
.tell display to "draw"

If you've not used these before, then you probably want to practice drawing on a PC screen first, before going to Gameboy. If you have used them, then they're exactly the same.

The new thing you do need to know about is that the the GBA has six different screen modes. Modes 0-2 are "tiled" modes, and while these are actually used for most real GBA games, they're a bit more tricky to understand, so we'll leave them for now. For regular drawing you need to use modes 3,4 or 5. Each has its own tradeoffs...

Mode 3 is 240x160 pixels with full colour. Unfortunately this uses up all of the GBA's graphics memory, which means it can't do double buffering or page flipping. In mode 3 the Sniff displayFlush has no effect, and all drawing goes directly to the screen, which means it can be very flickery unless you're careful.

To avoid flickering we need two screens worth of memory, and then we display one, while drawing to the other. Then we flip them over and all of our drawing appears instantly, without any flickering! Great, but we don't have enough memory for a full screen of full colour - something has to give:

Mode 4 is full resolution (240x160) but uses 8bits per pixel instead of 16. This isn't too bad, as Sniff generally uses a 9bit colour model(000-777). Unfortunatly this mode can also be a little slower due to the way the hardware handles memory.

Mode 5 keeps full colour but uses a lower resolution of only 160x128. Again we get the benefit of being able to keep two screens in memory, so we avoid flicker, but the low resolution looks a bit odd on screen.

Generally we like mode 4 the best, but you can run your code easily in any mode just by setting the parameter when you create the display device.

And that's all you need to know. You'll find examples of this kind of drawing in examples/GBA/window.sniff and there's GBA port of bounce out in examples/GBA/bounce.sniff

Sprites, Bitmaps, and Sound we'll save for another time.

Friday, 15 January 2016

LED Matrix Madness

I did a post a the end of last year on writing Flappy Bird in Sniff, to run an Arduino with an 8x8 led matrix screen. Following on from that I got very excited about the potential for running more complex games on such a simple screen. Having only 64 pixels to work with really focuses the gameplay and makes you think about every pixel. I started thinking of the possibility of designing a workshop session around these sort of games, and have a pretty near finalised design for a handheld "games console" that's easy to put together and is great fun to code for. However before I got to that stage I investigated lots of hardware options for what to use for the screen.

I started with a fairly common board with an 8x8 matrix of red leds driven by a max7912 chip. We already supported them in Sniff. Clk and Din connect to the SPI pins on an Arduino (or other controller), while you can connect CS to any control pin. Using SPI means it really only uses one pin (as the others can be shared), and its super fast, though as its only pushing out 8 bytes of data that's not really an issue (not worrying about drawing performance is a big win, as Arduino's struggle to push data out to bigger screens). What's especially nice is that you can daisy chain the boards, connecting the output from one to the input of the next to make a bigger display. Sniff is set up to handle up to four of these boards side by side - the shape of the board prevents them being stacked vertically.

To code for them just make a display device, and do some drawing:

make display maxMatrix device D10
make displayX number
make displayY number
make displayColor number

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

The pixels are numbered 1-8, rather than 0-7 as its really critical that you make every pixel count. Normally it doesn't matter than screens start at 0, but in this case numbering from 1 is more "Sniff like".

We were able to get recognisable versions of breakout, space invaders, snake, flappy bird, and most impressively defender running on this. It's a great board, and easy to find for under £2.


Working with these boards revealed that 8x8 was plenty of resolution to get some interesting game play, but trying to display multiple things on screen made them indistinct. It wasn't that we needed more pixels but that we couldn't distinguish what different pixels were supposed to be. For that reason we started looking into coloured displays.

 


The Colorduino is an all in one system, specifically designed to drive full colour an 8x8 rgb matrix with 8bit per channel colour depth (rather than just being on or off). The board is an arduino compatible, with headers laid out so that an rgb matrix drops straight on top of it. Shopping around I was able to get the board and a matrix for under £10, which is pretty reasonable (though i regularly encountered prices FAR higher that that). Not only is the display full colour , its huge - twice the height and width of the regular Max matrix.


To use it, just change the first line of the above code to:

make display colorduino device

and you're good to go. Compile and download using uno-sniff and it should just work like a normal Uno.

There's lots to like, but there are a couple of downsides. Most significantly is the limited I/O pins left available after the RGB matrix has been plugged in. On the side of the board are D0,D1,A4 and A5 (aka tx/rx and i2c data/clock). While this is a good selection it can be limiting. There's also no USB support on the board, so you need a USB/serial adapter to program it. These are only a couple of pounds and I keep a few around "for emergencies", so this should be no obstacle if you're using one for your own projects, I decided it was a bit fiddly for a workshop, as I didn't fancy getting a room full of kids to wire up serial pins compared to the simplicity of plugging in a USB cable. The extra cost also pushed it to the edge of what the budget for our workshops would allow.

Everyone loves neoPixels, and the only thing better than neoPixels is MORE netPixels arranged in an 8x8 grid. While these are expensive from mainstream suppliers, again we managed to find them for under £10. You'll need to add an Arduino to that, but they look amazing. Unfortunatly ours have got lost in the post, so we haven't been able to play with them yet. As soon as they arrive we'll have a device driver for them which lets you use them with the standard drawing commands, but for now you'll need to drive them using the standard ws2812 code.

As they're neoPixels these have the advantage of only using 2 pins on our controller, and are full colour. They're even BIGGER than the colorduino, which on the one hand is great, but they're perhaps getting a little too large (and expensive) for what we had in mind.


The final board gets back to the simplicity if the original Max single colour boards, but just steps it up a little. The tm1640 matrix is hard to find, but is available for about £4, and rather than being full colour, each of the pixels is a bi-colour LED - red and green. Each of the channels is a single bit, so they can be on or off, giving only four options: black, red, green and orange/yellow. However on my board the orange is a bit of a disappointment, being hard to distinguish from red. Despite that just having red and green opens up the options considerably, and everything looks really great. 

The other limitations on this board are that it has no mounting holes and the chip is on the bottom, making it hard to attach to stuff, and there's no through pins like the max, so you can't easily connect several of them to make a larger display.


The pins on the board are unlabelled, and it took us a while to confirm the pinout, but once we had that is an easy hookup - just power, data and clock. The board is smaller than the colorduino, but larger than the Max, making it a great size. Coding works exactly the same - just use:

make display tm1640Matrix device

All things considered this was our favourite board - just enough of a step up from the original red max matrix to be exciting, without being too big or expensive.

So here it is in operation in our Arduino powered handheld game console!


We went though a lot of iterations to the design before we end up with this which looks great, is fun to use and is cheap and simple enough that we can use them in our workshops. There's still a few small changes to make before its finalised, but we'll tell you more about it in another post.

Wednesday, 13 January 2016

Sniff on the Gameboy Advance

One of the things that we hear talking to teachers and kids is that they want to make "real" programs/games that run on actual game consoles and devices. While the GameBoy Advance is a little old now, but it fits the bill as a real commercial gaming device. As its a little older, it has the advantages of being cheap, well documented and its relatively easy to get code onto it, so now you can actually make your own game in Sniff, and download it into a cartridge, and the plug it into a GBA and have your own game running on a real device.



Assuming that you're already running Sniff, the next thing you'll need to do is install devkitARM. The instructions for this are a bit hit and miss, and are are directed more towards the Nintendo DS, but you just need to install the main devkitARM package and the libgba package and you're ready to go. Don't forget to set up the environment variables, as instructed on the dkARM install page.

With that done, go to the Sniff/examples/GBA folder, and we're ready to make a program.

make AButton digital input 0
make BButton digital input 1
make selectButton digital input 2
make startButton digital input 3
make rightButton digital input 4
make leftButton digital input 5
make upButton digital input 6
make downButton digital input 7
make leftShoulderButton digital input 9
make rightShoulderButton digital input 8

when start
.forever
..if AButton
...say "A"
..if BButton
...say "B"
..if startButton
...say "start"
..if selectButton
...say "select"
..wait 0.1 secs

All of the GBA buttons appear as digital inputs, so can read them easily. By default the GBA screen is set up in a simple text mode, so you can print things to it using "say". This isn't something you're going to use very much, but putting together the buttons, and "say" allows us to check that everything is working correctly.

You can compile this using the command "gba-sniff buttons.sniff" and you should get a file called buttons.gba which is an actual GBA rom image. The easiest  way to play it is to use an emulator - I used openEmu. That allows you to just fire up your ROM on you computer, and you can play it straight away.


However if you want the "real" experience you'll need a "flash cart". A few years ago everyone had one of these, and they were easy to get hold of, but they're a bit more obscure now. If you shop around you can get one, and then just copy your ROM onto an SD card, plug it into your GBA (or an original DS, which can play GBA carts), and you're instantly transported back to 2002.

There is third way which we're currently investigating... Floating around eBay and Aliexpress are handheld consoles that include a GBA emulator. These cost less that £20 and you can download your game straight into one of those via USB, and get a real handheld console experience. We've got one on order, and we'll report back when it arrives.

There's a lot more we need to say about using GBA graphics, sprites and sound - all of which are fully supported in Sniff. There's example code for using them all in the examples/GBA folder, and they work pretty much the same as they do on other Sniff devices, but I'll write more about them in a future blog post.

Tuesday, 12 January 2016

Measuring Cheese with the Esplora

One of the new features of Release 24 is support for the Arduino Esplora. This is essentially an Arduino Leonardo (so compile programs using leo-sniff), with a whole bunch of sensors, buttons, a joystick and a slider built onto the board, so you can start programming without having to hook up extra hardware. As such you could always compile programs to run on it using leo-sniff, but now we've added got hold of one we've added support for all of the sensors.



The foam is acting as a diffuser for the very bright RGB Led

make usb device
make usbConsole device

The main difference between the Esplora and the more common Uno is that they handle their usb communication to your computer completely differently. One the Uno there's a dedicated chip which does nothing but handle the USB, but on the Leonardo and Esplora this is all done in software. This is more flexible, but less reliable. If you have problems programming the board, then pressing the reset button just before you download the program will usually solve the problem.

We need to include the usb device to handle the core of the USB protocol, and then the usbConsole device so that "say" and "ask" get directed over the software USB implementation. These have been stable for some time, but we've recently seen some problems with OSX Mavericks. "ask" in particular seems to have become unreliable. Helpfully we'll get this resolved in the future.

Now for the interesting bits:

#Some of the HW is just atattched to pins:
make redLed analog output D5
make blueLed analog output D9
make greenLed analog output D10
make led digital output D13

when start
.forever
..set redLed to 0.5*((sin of (timer*100))+1)
..set greenLed to 0.5*((sin of (timer*110))+1)
..set blueLed to 0.5*((sin of (timer*120))+1)

The Esplora has a regular LED attached to D13 like most Arduino's but it also has an RGB led attached to pins 5,9 and 10. These support analog output so we have easily mix colours together.

make buzzer digital output D6


The buzzer is attached to pin D6. In fact the "buzzer" is simply a piezo speaker, and to play a sound we need to "push" the speaker in and out at specific speeds:

when start
.forever
...set buzzer to on
...wait 1000 microsecs
...set buzzer to off
...wait 1000 microsecs

There's an accelerometer attached to analog inputs (yes A11 is a real thing - not a typo), and a couple of spare pins D3, and D11 which are brought out on two "tinker kit" headers.

make accX analog input A5
make accY analog input A11
make accZ analog input A6

make tkOutA digital output D3
make tkOutB digital output D11

Though tkOutA and B are labelled as outputs they are direct pin connections and can be used as both inputs or outputs.

You can access all of the above using regular Sniff Arduino code, but the other hardware on the board is a bit more tricky, so we've bundled it up in the "esplora" device:

make esplora device
make temperature number
make joyX number
make joyY number
make joyButton boolean
make esploraSlider number
make esploraLight number
make esploraSound number
make switch1 boolean
make switch2 boolean
make switch3 boolean
make switch4 boolean
make tkInA number
make tkInB number

We've got access to the temperature (though in a previous post I expressed serious doubts about its accuracy) joystick, slider, light and sound levels, four switches and two generic tinker kit inputs (not that these ARE input only).

when start
.forever
..tell esplora to "read"
..say join [switch1] join ":" join [switch2] join ":" join [switch3] join ":" [s
witch4]
..say join "Temp:" [temperature]
..if joyButton
...say "Joy Pressed"
..say join "Joy:" join [joyX] join "," [joyY]
..say join "Slider:" [esploraSlider]
..say join "Light:" [esploraLight]
..say join "Sound:" [esploraSound]
..wait 1 secs


If you have the Esplora TFT screen you can also draw stuff on it, using the standard Sniff drawing methods, having first declared a display:

make spi device
make display esploraTFT device

With the basic stuff out of the way, lets actually do something useful with this...

 it's CHEESE TIME.

In addition to an Arduino Esplora, one of the residents of Snff Manor got a cheese making kit for Xmas. As I'm sure you all know, cheese needs to be matured in a cool place between 10 and 14 degrees. The cellars seemed ideal but some kind of monitoring system was clearly in order.



when start
.set maxTemp to -100
.set minTemp to 100
.
.set displayColor to 0000
.tell display to "clear"
.broadcast updateGraph and wait
.
.forever
..set slowAverage to 0
..repeat slowSampleTime
...set fastAverage to 0
...repeat 10
....tell explora to "read"
....change fastAverage by temperature
....wait 0.1 secs
...set temperature to fastAverage/10
...change slowAverage by temperature
...
...if temperature > maxTemp
....set maxTemp to temperature
...if temperature < minTemp
....set minTemp to temperature
...
...broadcast updateLed and wait
...broadcast updateText and wait
..
..set temperature to slowAverage/slowSampleTime
..add temperature to history
..repeat until not length of history>historyLength
...delete item 1 of history
...
..broadcast updateGraph and wait


There's a lot going on here, but if we start from the middle, you'll see that we repeat 10 times, measuring the temperature and averaging it over 1 second. This makes the built in sensor much more consistent (if not more accurate). Then we compare the measured temperature to the max and minimum, and fire off a couple of scripts to update the RGB led and some text on the display.

We do this 900 times, which is 15 minutes, and calculate an average over this longer period, which we add to a list called "history". This records the last 12 hours of data, and we call a script to plot it on the screen.

make lowestThresholdTemp number 6
make lowThresholdTemp number 10
make highThresholdTemp number 14
make highestThresholdTemp number 20

when updateLed
.if temperature <lowestThresholdTemp
..set blueLed to 1
..set greenLed to 0
..set redLed to 0
..stop script
.
.if temperature <lowThresholdTemp
..set blueLed to ((lowThresholdTemp-temperature)/(lowThresholdTemp-lowestThresholdTemp))
..set greenLed to 1-((lowThresholdTemp-temperature)/(lowThresholdTemp-lowestThresholdTemp))
..set redLed to 0
..stop script
.
.if temperature <highThresholdTemp
..set blueLed to 0
..set greenLed to 1
..set redLed to 0
..stop script
.
.if temperature <highestThresholdTemp
..set blueLed to 0
..set greenLed to ((highestThresholdTemp-temperature)/(highestThresholdTemp-highThresholdTemp))
..set redLed to 1-((highestThresholdTemp-temperature)/(highestThresholdTemp-highThresholdTemp))
..stop script
.
.set blueLed to 0
.set greenLed to 0
.set redLed to 1

I've set up four constants using the new Sniff R24 syntax. lowestThresholdTemp is 6, and using the word is exactly the same as using the number. This means we can push these definitions outside the code itself so if we need to change them, then we can see exactly where they need to be tweaked. In this first run, I've decided that the cheese should ideally be kept between 10 and 14, with a less ideal window of between 6 and 20.

When updateLED runs, it sets the RGB LED to blue if the cheese cave (thats what they call it!) is too cold, it then blends from blue to green as it warms up. When it reaches 10degrees it turns green. From 14 upwards it then starts turning red.


The TFT display on the Esplora is a really nice display. Unfortunately in some respects its too nice. Usually we use something like a Nokia5110 screen which is low resolution and each pixel is either on or off. Here we've got much higher resolution and full colour, which creates a real problem for us. With the smaller screens we can prepare the screen image in memory then push it out in a single blast, which minimises flicker. Here the screen is way to large to fit in the Arduino's minimal RAM, so we have to draw directly to the screen. Not only is this slower, but it means when we clear the screen to draw on it, the screen actually goes blank. Large amounts of flicker are unavoidable. To minimise it as best we can we're not going to clear the whole screen at once but rather clear off bits of it before redrawing:

make counter number
make minY number
make maxY number
when partialClear
.set displayColor to 000
.repeat (maxY-minY) using counter
..set displayY to minY-1+counter
..set displayX to 0
..tell display to "move"
..set displayX to 160
..tell display to "hfill"

when updateText
.set minY to 110
.set maxY to 118
.broadcast partialClear and wait
.set displayColor to 777
.set displayX to 0
.set displayY to minY
.set message to join "Temperature:" [temperature]
.tell display to "show"
.
.set minY to 100
.set maxY to 108
.broadcast partialClear and wait
.set displayColor to 777
.set displayX to 0
.set displayY to minY
.set message to join "Low:" [minTemp]
.tell display to "show"
.
.set minY to 90
.set maxY to 98
.broadcast partialClear and wait
.set displayColor to 777
.set displayX to 0
.set displayY to minY
.set message to join "High:" [maxTemp]
.tell display to "show"

The text is 8 characters high, so we use PartialClear to clear only the rows we're about to print on. Then we tell the screen to show the latest statistics.



when updateGraph
.set minY to (minTemp-graphOffset)*graphYscale-1
.set maxY to (maxTemp-graphOffset)*graphYscale+1
.broadcast partialClear and wait
.set displayColor to 007
.set displayY to (lowestThresholdTemp-graphOffset)*graphYscale
.set displayX to 0
.tell display to "move"
.set displayX to historyLength*graphXscale
.tell display to "hfill"
.
.set displayColor to 070
.set displayY to (lowThresholdTemp-graphOffset)*graphYscale
.set displayX to 0
.tell display to "move"
.set displayX to historyLength*graphXscale
.tell display to "hfill"
.
.set displayColor to 070
.set displayY to (highThresholdTemp-graphOffset)*graphYscale
.set displayX to 0
.tell display to "move"
.set displayX to historyLength*graphXscale
.tell display to "hfill"
.
.set displayColor to 700
.set displayY to (highestThresholdTemp-graphOffset)*graphYscale
.set displayX to 0
.tell display to "move"
.set displayX to historyLength*graphXscale
.tell display to "hfill"
.
.set displayColor to 777
.set displayX to 0
.set displayY to ((item 1 of history)-graphOffset)*graphYscale
.tell display to "move"
.repeat length of history using counter
..set displayX to counter*graphXscale
..set displayY to ((item counter of history)-graphOffset)*graphYscale
..tell display to "draw"

Finally we draw the graph, again using PartialClear to get rid of only the bit we need to. There are 4 horizontal lines on the graph, representing the 4 threshold temperatures, then we simply loop over "history" drawing the graph.

We placed this down in the cellars and were able to monitor temperature, and see how it varied. The graph was particularly handy, as it was able to reveal some large changes of temperature that happened when we weren't actually there.

As we had reservations about the accuracy of the Esplora's temperature sensor, we also attached a dht11 to on of the tinker kit outputs. Things still to do include logging data to the SD card, and sounding an alarm if the temperature gets to high - "quickly! To the Cheese Cave!!!!!"