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.

Tuesday, 27 January 2015

Getting started with Sniff and Propeller

Parallax are an odd company. Their products have many parallels with Arduino: They make and sell micro controllers targeted at education, with an emphasis on open source. However they've been doing it since the '90s (Arduino didn't start until 2005), and not only do they release complete systems, but they design and sell their own CPU's!

However if you're the UK/Europe you might not have come across them. That's probably because they're based in America, and as a small company their sales team don't have the resources to target overseas markets. They also have a policy of manufacturing in the USA where possible - which is very commendable if you're an American buying from an American company, but for the rest of us means that they're expensive imports.

Parallax's main CPU: the Propeller, has some impressive specs compared to other embedded controllers. It has EIGHT cores (which they call COGS), they're 32bit, and run at decent 80MHz. Each is supposed to deliver around 20Mips, so that gives us a potential 160Mips to play with. There are 32IO pins.

That sounds pretty amazing. Less impressive is the memory. Each COG has 2K of working RAM, and there's a central 32K of RAM. There's also 32K of ROM, but that's largely dedicated to code used by SPIN - Parallax's custom programming language, so we don't get much from it. 32K of core RAM doesn't sound too bad (The Uno has 2K), but the Propeller doesn't have built in eeprom like the AVR so boot code in the ROM loads your code from an external i2c eprom into the RAM to be able to run it. 32K of RAM has to hold both your code and data. To make it even worse the 32bit processor means code size is around 4 times as big as the AVR, so memory is very tight.

I've been tempted by the Propeller for a while and finally found an ebay seller who would ship me a quickstart board from America for about £20 including p&p.

It's about the size of an Arduino Uno, and again there are many similarities. It powers/programs over USB, and has the GPIO pins exposed on a header. One of the nice things here however is that the outputs are numbered 0-31, and appear in consecutive order on the header. No complex pin/port mappings to remember (I'm looking at you Raspberry PI!). Another nice touch is that there are 8 LEDS, with buffered drivers to you can go crazy flashing lights, but still use the same pins as inputs if you need to. The board runs at 3.3v, but each of the pins can source/sink a healthy 40mA (same as AVR - far more than most other CPUs), so you shouldn't have to worry too much about blowing it up.

There are no "special" pins on the Propeller. Whereas the AVR has UART's, I2C, PWM, and SPI hardware, the Propeller doesn't. One of the reasons for having those 8 cores is that you can simply code up those features and run them on a core, so you can have 8 UART's or 8 i2c busses if you want to. However there are some pins used by the boot loader: 30/31 are the serial connection, while 28/29 are i2c. In addition several of parallax's boards place an SDCard reader on pins 22-25, so it makes sense to use these for SPI where practical.

So onward to using Sniff on the board! Sniff compiles to C, and then uses the native C compiler to target specific platforms, so you'll need to install the Parallax "SimpleIDE" first. You should then be able to compile and run Sniff programs by simply typing "prop-sniff myprog.sniff". This puts the program into the eeprom, and starts it running.

One of the first things you'll probably find is that you run out of memory! You can improve things a bit by compressing the code, at the cost of a little performance: "prop-sniff cmm myprog.sniff". This uses the "compact memory model" as opposed to the "large memory model". You could also try the extended memory model, but to do that you'll need to refer to the parallax gcc documentation on configuring your board. Part of the problem is that the Propeller has no floating point hardware, so need to include maths libraries to do floating point - which Sniff depends on (its not efficient, but its easier to understand!). Simply using Sin() in increased the code size by 12K, so be careful, and check the code size. Hopefully this will improve with future versions of Propeller GCC.

Propeller-Sniff supports i2c, spi ( MosiPin=24; MisoPin=22;SckPin=23; SS for SDCARD=25) and gpio so most of the embedded examples should work. You can use PWM on any pins, but its currently limited to two channels. Serial works as expected, but is at 115200 baud.

Currently Sniff only uses a single cog to actually run your program (using 2 others for support functions), but in future release we should be able to make better use of more of the cores. Sniff is a parallel lanuage, so it will be really exciting to try and map it to a parallel chip.

Finally its really easy to build your own Propeller board! All you need is a Propeller (which comes in a 40pin DIL package!), a 5MHz Crystal , an i2c eeprom, and a few decoupling caps. You can program and power it using a 3.3 USB/ttl serial adapter: connect the DTR line to reset to synchronise when programming.

Bonus update: David Whale (@whaleygeek) just pointed me in the direction of Spinvent - purveyors of all things Propeller in the UK and Europe! Check them out! Their "demo board" looks pretty good value!

Monday, 26 January 2015

Release 14: The Parallax Propeller

It's time for another release of Sniff!

The headline feature this release is that we can now compile for the Parallax Propeller chip. This is a pretty cool CPU designed with education and hackers in mind. It's main feature is that it has 8 cores!!! So far Sniff can only use a few of those, but in the future we hope to make more use of them. Also pretty neat is that its available in a standard old-school 40pin package, so you can build your own machine on breadboard (details later). Parallax are based in the USA, and as a small company haven't really broken into the European market (as far as I can tell), and the boards aren't that common in the UK, so if you're using one we'd love to hear from you.

To use propeller with Sniff, install the Parallax SimpleIDE first, then just use prop-sniff.

The other big feature is that windowing now works natively on OS X, which most signifigantly means that the sniffpad side (Which is written in Sniff) works on OS X too.

For those of you working at the lower hardware levels, we've introduced a new timer: Timers are difficult! On Arduino there are two methods of getting the current time: micros() and millis(). The problem is that millis() fails after about an hour, while micros() can run for weeks, but is less accurate. For data logging you want millis(), while for low level hardware you want micros(). We've tried it both ways, but there's always been gotcha's. Now we have "timer", and "fast timer". They both return the time in seconds, but fast timer is more accurate, while timer works for longer time periods.

There are also a bunch of other improvements and fixes. Let us know how you get on, either on the forum, or by emailing us.

Release 14 for Linux/Mac
Release 14 for Windows

Monday, 5 January 2015

Turtles Part 3: L-systems

Last post we showed how you could produce some pretty neat patterns by taking simple rules, and replacing parts of that rule with something only a little more complex. Repeat that four or five times and you've got a really complex shape. This idea of rule re-writing to create complex self-similar shapes (Fractals), was developed by Astrid Lyndenmayer, so we call them L-Systems. However Lyndenmayer wasn't a mathematician or a programmer - he was a biologist!

L-Systems were developed to describe plants! Lyndenmayer realised that the branch of say a fern, basically is a small copy of the whole fern, so if he could find a way to describe that, he could use it to classify and record how plants grow.

This is a page form Lyndenmayers book "The Algorithmic Beauty of Plants" which you can download as a pdf (legitimately!). The only difference between these shapes and the ones we did last time is that these ones branch. This is pretty important if you're trying to make a tree!

The basic concept of branching in L-Systems, is that when you find a "[" in the rule that means the start of a branch. We're going to go off and draw the branch, then come back to continue drawing the rest of the L-system afterwards. That means we need to remember where we need to come back too...

To do that we make a list of numbers called "stack".

make stack list of number

..if command = "["
...add displayX to stack
...add displayY to stack
...add direction to stack

When we encounter the "[" command during drawing we record the turtle's (remember them - feels like we've forgotten all about turtles it was so long ago!) position and orientation, so we can put it back where it was later.

..if command = "]"
...set lastStack to length of stack
...set displayX to item lastStack-2 of stack
...set displayY to item lastStack-1 of stack
...set direction to item lastStack of stack
...delete lastStack of stack
...delete lastStack-1 of stack
...delete lastStack-2 of stack
...tell display to "move"

When we find a "]" command we know we've finished drawing the branch, so we get the values we recorded back from the stack, and continue on. (this code is slightly more complex than it should be, but there's a bug in Sniff, which means the simpler code doesn't work - its fixed for the next release, so once that's out I'll update this, or maybe forget).

  • Axiom: F
  • Angle: 45
  • F=>F[+F]F
This is one of the simplest branching systems. We can think of each "F" as a segment of the plants stem. At each iteration, each stem segment doubles in length, and grows a branch half way along.

While that doesn't sound like much, the next time around each of those branches grows a new branch, and we quickly get something interesting. (If you don't get the whole thing drawn correctly remember to increase string length in $SNIFFDIR/lib/sniffDefs.h - these rules get very long)

If we look at the first example on the page above, we can see it uses a similar structure. Each stem segment becomes a segement, a branch to the left, a segment, a branch to the right, and a final segment:
  • Axiom: F
  • Angle: 25.7
  • F=>F[+F]F[-F]F
While this might seem simple we get a pretty convincing plant from it:

These kinds or rules add branches to every stem segment, and are good for some kinds of plants, but other plants are more structured, and only branch at the ends of branchs (while older branches become longer). We can represent those just as easily by marking the active "nodes" with an X. If we look at example E.

  • Axiom: X
  • Angle: 25.7
  • F=>FF
  • X=>F[+X][-X]FX
Each "bud" marked with an X turns into a stem segment with a bud to its left, and right, followed by more stem with a single bud at the end.

While the results are a bit geometric - it doesn't help that its symetrical, its a pretty good fern. It doesn't take a lot to make something more organic like example F:

One of the great things about L-Systems is that more or less whatever you put in, you get something that looks like some kind of plant - just make up a rule and see what you get. Slightly harder is to write an L-system to look like a specific plant (start by considering is it stem branching, or bud branching).

While we've implemented the basics of L-systems, there are lots of extensions you can include, for example changing the branching angle with each generation, or adding commands to control the colour.

If you get really serious about L-systems you could make something that looks like this:

Kevin Mack won the 1999 Visual Effects Oscar by using L-systems to make this tree for the film "What Dreams May Come". In fact L-Systems are a really big deal in computer graphics, where they're used to make trees and plants for all sorts of animated and special effects movies.

That's pretty cool for a turtle!

You can download Source Code for this and the previous turtle posts here.

Sunday, 4 January 2015

More Turtles (and Fractals) Part 2

In the last post we set up a basic turtle system in Sniff and used it to draw some simple shapes. Now that its working lets draw some more complex things...

But before we do, lets consider first setting up a way of describing a shape, by making a rule for the turtle to follow. To keep things simple we can use a string of characters, at for now we'll just have three letters: "F" meaning move forwards and draw, "+" meaning turn left, and "-" meaning turn right. We could then set a distance and and angle to turn each time, and then tell the turtle to draw the shape.

Building that on top of what we did last time is pretty easy:

make rule string
make command string
make index number
make angleDelta number
when drawRule
.set index to 1
.repeat length of rule
..set command to letter index of rule
..change index by 1
..if command="F"
...set penDown to yes
...broadcast move and wait
..if command ="+"
...change direction by angleDelta
..if command ="-"

...change direction by -angleDelta

We have  a string called "rule" and we go through it one letter at a time, extracting that letter (command), then checking if its any of our drawing commands, and behaving appropriately. If we set angleDelta to 60, then we can draw a triangle with the code:

.set angleDelta to 60
.set rule to "F++F++F++"
.broadcast drawRule and wait

But now we've got this rule described by the "rule", what if we wrote some code to change that rule.
What if we went through and replaced each edge ("F") with the shape on the right? To do that we just need to change the string so that "F" becomes "F+F--F+". (To make sure we keep things the same size we also divide distance by three.)

make newRule string
when substitute
.set newRule to ""
. set index to 1
.repeat length of rule
..set command to letter index of rule
..change index by 1
..if command ="F"
...set newRule to join newRule "F-F++F-F"
...set newRule to join newRule command
.set rule to newRule

Much like the drawing code, we go through the string a letter at a time, and check it its "F", in which case we add the new fancy edge to the newRule, otherwise we just add the original letter. If we do this once, then we get a star, as each side of the triangle gets a little triangle added on. By why stop there - lets do the same to the new shape:

.repeat 4
..set displayColor to 000
..tell display to "clear"
..set distance to distance /3
..broadcast substitute and wait
..set displayColor to 777
..broadcast drawRule and wait
..wait 1 secs

In fact we can keep going forever (actually until we run out of memory!) replacing each new edge with a smaller edge with a triangle. What we end up with is an example of a Fractal, known as a Koch Snowflake. It has all sorts of neat properties. For example they tesselate(ish), and there are strange behaviours in term of its perimeter (which keeps getting bigger), and its area (which tends to a limit). 

We can do lots of fun things with this kind of rule rewriting. All we need to do is specify an initial rule (called an Axiom - meaning something we assume before we start), and a set of substitutions.

For example 
  • Axiom="FX"
  • X=>X+YF+
  • Y=>-FX-Y
produces a Dragon Curve.  You can just plug the Axiom and substituition rules into the Snowflake code and get a completely different shape. Set angleDelta to 90. You don't need to worry that we've got new letters in our rule - they work fine in the substitution phase and get ignored when drawing. Each time we substitute we get more detail added.

Another interesting shape is the Hilbert Curve:
  • Axiom="A"
  • A=>-BF+AFA+FB-
  • B=>+AF-BFB-FA+
  • angleDelta=90
Which produces something that looks like:

The cool thing about this one is that its "space filling". Given enough iterations it will completly fill up the square, even though its only a line. While that's a pretty cool just as a concept, its not just a neat mathematical trick: NASA have used this exact shape to design miniature radio antennae, as it clams a lot of wire into a small space!

One problem with building code like this is that the rules rapidly become very long. So long in fact that Sniff can throw away the last parts when the they get so long they won't fit in the allocated memory. If your Fractal stops drawing itself part way through, then edit the file $SNIFFDIR/lib/sniffDefs.h, and change the value for string length from 1024 to something bigger. On a PC there should be no problems setting this to 4096 or even bigger.

The idea if creating fancy patterns by rule rewriting was developed by a guy called Astrid Lindenmayer, so we call these kinds of rules Lindenmayer Systems, or L-Systems for short. The shapes we've drawn so far are among the most basic shapes that L-Systems can produce. However to see what L-Systems are really for you'll have to read the next blog post...

Saturday, 3 January 2015

Turtle Graphics (part 1)

One of the key differences when moving from Scratch to Sniff is that Sniff doesn't have any built in graphics, or sprites the way Scratch does.In fact Scratch is so centred around sprites that it becomes hard to consider writing code that doesn't move the cat around. By  not having sprites, its possible to think about all the other things you can do in Sniff!

However turtle graphics are a fun way of exploring geometry, and as Sniff has developed, its become sufficiently powerful that making your own turtle routines is pretty trivial. In fact all you need is:

make display window device
make displayX number
make displayY number
make displayColor number

make direction number
make distance number
make penDown boolean

when move
.change displayX by distance * cos of direction
.change displayY by distance * sin of direction
.if penDown
..tell display to "draw"
..tell display to "move"

We create a display device, which in this case is a window (which works on Linux (Pi) or Windows). If you want to try this on Arduino or even EV3, then switch the device for something else, and it should work more or less unchanged. We then set up the usual display parameters.

The important code lives in the "move" script. The movement is defined by a direction, a distance, and penDown. The code is pretty self evident if you're familiar with how sin and cos work. If you're working with younger kids then you can treat this as a black box, or even take the opportunity to introduce the concepts in a practical and useful way.

when start
.set displayX to displayX/2
.set displayY to displayY/2
.tell display to "move"
.set direction to 0
.set distance to 100
.set displayColor to 777
.set penDown to yes

When we start we set the turtles position to the centre of the screen, facing "east", with a step size of 100 pixels. We also tell it to draw in white.

After that we can draw whatever we like but lets start with a hexagon:

.repeat 6
..broadcast move and wait
..change direction by 60

Easy! Now lets make a Spiral:

.set distance to 1
..broadcast move and wait
..change direction by 9.5
..set distance to 1.01 * distance
..set penDown to not penDown

We set the initial distance to 1 so the spiral starts out small, and each time we turn by a fixed amount. We also increase the distance of the step a little each time. Finally just to make it more fun, we turn penDown on and off, so that only alternate steps are drawn. This gives us a dotted line. Experiment with the different values!

.set distance to 2
..broadcast move and wait
..change direction by pick random -40 to 40
..set penDown to not penDown

Here we choose a small distance again, and then at each step we turn randomly. The result is a "random walk". Random walks turn up everywhere, but one common example is Brownian motion.

They have lots of interesting mathematical properties. For example it doesn't really matter what values we pick for distance, and the angle we turn through - it just affects the scale, but the behaviour is the same (after a moderate number of steps the original direction is statistically irrelevant to the current direction). Also the average distance traveled is proportional to the square root of the number of steps.

There's still lots more to do with Turtles, but that's a good start for one post...