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, 15 March 2016

Banana Physics

Yesterday I presented a talk at ICT Conference for Schools, in Southampton. We're (hopefully) going to be presenting something similar in Boston this summer. I thought it would be good to just summarise it here, and post the code examples I showed.

Banana Physics starts with the Banana Piano - the classic Makey Makey project... or should I say the ONLY Makey Makey project. Despite their claim its an "invention kit" which can "make anything", their idea of "anything" is rather limited to being a keyboard made out of fruit! More or less any fruit you'd like!

In addition to being limited, we don't actually learn anything from the piano project. It's fun (for a few minutes), but what are we trying to teach? That Banana's are fun? The best thing we might learn is that Banana's conduct electricity... 

Except they basically don't. To understand we need to investigate RESISTANCE. If we use a pico board, instead or a makey makey we can actually do science!


This is the circuit that the pico board (and pretty much everything else) uses to attach your banana to the computer. R1=10K, and the banana replaces R2. With a bit of good old school Ohm's law, we can write an equation to calculate R. It turns out the Banana's have a resistance of around 40K-50K ohms. Not good conductors at all.

The next step is to drop a thermistor in place of R2. With a bit more complex maths, we can turn that resistance into a pretty accurate temperature (or up to 4 different temperatures on the different channels). It's pretty easy to log that data over time. On the one hand Picoboards aren't cheap (about £30 in the UK), that's really nothing compared what you'd pay for a 4 channel data logger, or even a good multimeter.

We then switch out the thermistor for a light dependant resistor. We could track light levels, but we can also use it to detect an object moving in front of the sensor. We set up two about 70cm apart, and time a beanbag to fall from the top one to the bottom one. Applying kinetic equations we know starting speed (0m/s), distance (0.7m), and we measure time. Which allows us to calculate acceleration - gravity.

Alternatively we can use the Lego Wedo... Two distance sensors make a great speed trap, so we can measure the speed of an object. If we drop the beanbag 70cm, and measure its final speed, kinetic equations will give us gravity again. In the talk I just did a very casual demo, and dropped it from a very rough distance, and it came up with a value of 8.5m/s/s. Pretty good.

The final demo was using the wedo tilt to measure the period of a pendulum. Again putting together  a bit of maths/physics, and coding I got a value of 10.5 this time. Again, this is pretty good for a guy standing in a room with a laptop and a few bits of Lego.

Here's the code I used for the demos. Check out the "Science" tag on my blog posts, to get more detail on these projects (perhaps built with different hardware), and ideas for other code based science.

The point of the talk was (in addition to promoting Sniff!), to show how using coding and making you can make high school science really fun. If coding is writing, then the whole point of learning to code is to unlock new ways of expressing and exploring. If coding just lives in the ICT class then its a total waste of time. If it lets you explore and understand the universe better, then that's pretty amazing.


Tuesday, 8 March 2016

Lego Dacta Control Lab B

So far I'm very skeptical about the Wedo 2.0. It's yet another lego electrical plug standard that's incompatible with both the existing Wedo/PF range or the EV3. That means not only do we have to buy new motors and sensors but we have only two sensors and one motor (where as Wedo 1 can use st least use several motor types, the servo, and lights). The argument that the new plug will by more versatile and flexible is exactly the argument that was used when the Wedo/PF plug replaced the older Lego 9V system, but in practise there were less components produced for PF than for the 9V system.

In fact looking back at the Lego 9V/RCX system, it seems the most complete, and well thought out of the many the different (incompatible) Lego electrical systems. While it is a bit limited, and in theory the more modern systems should have a technical advantage the older and simpler system has one fantastic thing in its favour: compatibility. 

While currently lego uses one plug for its technics range (Power Functions) another for Wedo 2.0, and a third for EV3, the older system used the same plug for all its products, so technics users could add an RCX controller. Even when NXT (and subsequently EV3) was introduced an adapter cable allowed 9v/RCX sensors to be used. Even today the Power Functions extension cable allows 9V motors to be used (and PF motors to work with 9V controllers).
The old 9V plugs were also simple: a positive and negative terminal which could either provide power, or be connected to a resistive sensor. With a bit of cleverness, they could be persuaded to do both at the same time, so powered sensors were possible. Putting the same system in the hands of the public, and educators led to an explosion of creativity (that neither the Wedo or the Microbit are able to enjoy!).

However while the 9v system is well remembered, one of its greatest creations is all but forgotten:

 Dacta 9751 Control Lab B



Look at that thing and ask yourself what more you could ask for from a system. 8 inputs, 8 outputs, connected via a serial port (so no drivers needed). Compatable with a wide range of cheap sensors. You'd need 8 wedo to do the same job! It was released in 1995, and its bigger and better than anything available now.

As for what you could attach, there were a choice of motors in various sizes, various types of lights, two different sirens, a light sensor, a rotation sensor, a button, and temperature sensor. The light sensor is actually very similar to the Wedo distance sensor (though not quite as robust), but the rotation sensor leaves the Wedo Tilt in the dust - It can measure angles of rotation in 22.5 degree steps, which compared to the Tilt's forward/backwards just shows how much we've dumbed down!


We were able to pick up one of these, and a whole load of sensors for less than half the price of a Wedo set. We also got some PF extension cables so we can use our existing PF motors (or hack them up to make new sensors!).

Cables:

If you have the original cables and PSU then great, but if they've gone missing, the PSU is 10V AC, 7VA. Note that this is an AC-AC transformer, so most PSU's won't work.

The second thing you need is a serial cable. Again most probably won't work! For you youngsters too you wet behind the ears to remember serial cables, gather round and I'll tell you about the olden days...

You see serial cables were designed to connect computers to modems. Modems would talk over a phone line to the another Modem, which would then have another serial cable to a computer. The Modems just passed the message along, so were called Data Communications Equipment (DCE), while computers were at the ends of the signal path, so were called Data Terminal Equipment (DTE).

Now if you've ever encountered a pin on a circuit board marked "TX" you'll know the dilemma - is this the pin that the board is transmitting on (so you connect it to your RX) or is it the pin that you should use to transmit, so connect it to your TX. Well with DTE and DCE its really easy: DTE is "in charge", so TX on DTE is an output, and TX on DCE is an input.

On a 9pin conector, pin 2 is RX and pin 3 is TX. Thats the same for DTE (male plug) and DCE (female socket) so you just connect all the pins straight across and you're good to go...

But what if I'm not talking to a modem? I'm talking to an I/O board here... They should both be DTE? Well the "correct" thing to do is to use "null-modem". In theory thats a small box that has a DCE socket on each side. You connect each piece of DTE equipment to the Null Modem and the null modem crosses over the RX and TX wires.

But that's a lot of hassle - two cables and a box when we could just make our I/O board look like a modem. Put a female socket on, wire it like a modem, and use a regular cable. Or we could just get one cable and put a twist in it, so we'd have a female-female null modem cable. Or we could do something totally crazy...

which is exactly what Lego have done... They've put a female (DCE) connector on the box, so you need a male-female cable, but they've wired it as DTE. That means you need a M-F DB9 null modem cable!!! They do exist and you can get them cheaply on eBay, but they're not the sort of cable you're likely to have in your bits box.

Between the odd PSU and odd serial cable I hate to think how many of these gems have been thrown away as "not working", when they just need hooked up properly.

With that in place, you'll probably need a USB-Serial converter - any with a DB9 connector on will do. While using old school serial might seem tedious compared to USB, the benefit is that we're now good to go - no drivers, or difficult code to write. Just send some text and it works.

Lets Go:

Even when you get everything hooked up, you still need the right software to get the thing to jump into life. I spend some time wondering if mine was broken, before getting it working reliably.

Plug it all together and fire up Sniff, release 25 or later. It should find the serial port (it'll call it an Arduino, but it calls everything an Arduino!). If you're on Windows you'll need to set ARDUINODEV to be the com port you're using. The example files are in examples/Hosted/dacta/test.


make lego dacta device
make legoValue number
make motor dactaMotor device 1

when start
.forever
..set legoValue to cos of (timer * 60 )
..tell motor to "update"
..wait 0.1 secs


To control a motor, the first thing we need is a dacta device. the variable legoValue is used to communicate with modules. We then create a motor device on port 1. To set its speed, just set legoValue and tell the motor to update. If your familiar with the old Wedo Sniff API then you can also communicate with a specific port by using the legoConnector variable, but the new style API is nicer. The Wedo also can use this new Object based style (check the examples).

To read from a device like a button:

make lego dacta device
make legoValue number
make button dactaTouch device 1

when start
.forever
..tell button to "update"
..say [legoValue]
..wait 0.2 secs

Interestingly the lego "Touch" sensors are actually analog, and can report the strength of the push rather than just being on or off.

The dactaLight, dactaTemperature and dactaRotation devices work in exactly the same way, returning a value whenever you call "update".

 One minor thing to watch is that the Control Lab has a fail safe - it if doesn't receive a message within 2 seconds it shuts everything down. Normally this isn't a problem as you're probably reading sensors more often than that, but if it is just add

when start
.forever
..tell lego to "update"
..wait 1 secs

somewhere in your program, and it will just keep the board alive.

The Wedo 1 is a great device, the Wedo 2 maybe in the future, but the Control Lab B is really the Mother of all Wedo! It's an amazing device, and its a shame that we can't have something quite as cool available today.

Monday, 7 March 2016

Release 25: Soul-Silver release!

Release 25 if Sniff is now with us, and brings the usuall cornucopia of goodies.

Features:

  • SniffPad improvements
  • Flotilla Support Improvements
  • Lego Control Lab B support
  • Improved Wedo Support
  • Embedded GPS support


A big call out, and thanks to Robin Newman for his help it getting the Flotilla support close to complete. The new release is more stable, and supports the changes made to the Flotilla in in its "shipshape" update/pre-release - make sure your FW is updated to this. We've were unable to test the full Flotilla system "in-house" as we only had access to a small number of the modules. Robin's done a great job testing the code (often long before we got close to making it work),  bug fixing, and demoing the system. The Motion module is the one outstanding thing to build and we'll have that going in the next few weeks.

We also 'discovered' the Lego/Dacta 9751 Control Lab B... and just had to get hold of one, and add Sniff support. These are about 20 years old and are one of the first Lego/Computer systems. Look at what they had available then, and what they have now, someone is clearly going in the wrong direction - 8 inputs & 8 outputs, easily controlled from a computer without any complex drivers or installs needed - that's like 8 Wedos in one box! There are more (and better) sensors available than the Wedo, and you can pick them up super cheap second hand. I hate to think how many of these have been thrown away when someone couldn't get the SW to work, or because they're just "old". Grab em while you can!

As we were building the SW for the Control Lab, we looked at what we'd learnt developing for Flotilla, and built a more "object oriented" interface to it, than we had for the Wedo. So then we went back and re-worked the Wedo to support the new way of talking to this hardware. You can code for Control Lab or Wedo using either the old Connector based numbering system or using the new method.

We've updated SniffPad so that it now does basic keyword highlighting, and formats text a little nicer, so you can see what's going on in your code so much better. 

On other minor thing you might need to know... To make the Pi versions easier to work with we've moved the GPIO support from the "sniff" command. Compiling on Pi with the command "sniff" just generates a regular executable. This means you don't need to run it as root. To access the gpio you can compile with the pi-sniff command. 

Saturday, 6 February 2016

Lego Wedo Semaphore

After building the Semaphore robot, I was clearing up the Wedo Speed trap stuff, and wondered if we could make a semaphore robot from Lego?

The easiest way to do it would be using EV3 motors. We can run Sniff on the EV3, and the Mindstorm, and in fact EV3 motors are perfect for this task. We weren't able to use regular motors for the Arduino version, as normal motors just turn, and you can't figure out where they are (so we used stepper motors). EV3 Motors have an extra sensor built into them so you can position them exactly. That means they can easily turn the required angle, and move to specific positions. However setting up the EV3 is quite a bit of hassle.

That's one of the reasons I like the wedo so much. It's just quick, plug and play fun, without the "bigness" of EV3.


The Wedo supports motors by default, but it can also use Power Functions components like lights. One of the coolest Power Functions components is the Servo, which can move to a precise (ish) position over 180 degrees. It's not supported by the Official Wedo software but we can operate it from Sniff.


Check back with the previous post on semaphore for the bulk of the code and background on handling semaphore. We'll concentrate on the Wedo bit. Most of that is taken care of by a script called "update":


when update
.forever
..set wedoConnector to 1
..set wedoValue to -2*((target1+1)-3)/6
..tell wedo to "setMotorSpeed"
..set wedoConnector to 2
..set wedoValue to -2*((target2-3)-3)/6
..tell wedo to "setMotorSpeed"


This maps semaphore positions in the "target" variables to value between -1 and +1. However we need to be a bit careful. The Lego Servo is an odd machine, which only handles a fixed set of positions. It can move to centre (0) and 6 positions each side (even though the Lego website says 7!). A value to 1 means 90 degrees, and we can move in 15 degree increments. If you try and set a value between those increments strange things happen - sometimes the servo skips, or doesn't move, and sometimes it makes whining noises. For best operation we need to move the servo value in 1/6ths
 
For the left motor we have to support semaphore values between -1 and 5 so lets add 1 to it, so now its between 0 and 6. Now subtract 3 so its centred around 0 (ish), then divide by 6 so we get  nice reliable steps.

But each step is only 15 degrees. We want each step to be 45 degrees. We also need a travel of 270 degrees, which the Servo can't do... That's why we used a stepper last time. But now we're using Lego, we can easily build a gearing system. A Lego small cog has 8 teeth, and a large one has 24, so if we use the servo to drive a large cog, it will turn a small cog 45 degrees, and we will have a potential travel of 540 degree!

That sort of works, but neither the servo or the gearing is that precise - there's a lot of play in both, which means that it isn't accurate enough to clearly signal. Instead we multiply by 2, so each semaphore position is two steps separate (30 degrees). Now we need a gearing ration of 1.5, which turns out to be quite hard to make. However if you have Extra large cogs they have 40 teeth, so if we drive a large cog from an extra large cog we get a ration of about 1.6 which is close enough.

The minus sign just flips the direction, as the gearing reverses the direction of rotation and we need to compensate. We have a similar mapping for the right hand servo which is on Wedo connector 2.

The rest of the changes from last time are just about tweaking the code to work right with the specifics of the build, and evolution of the code. Left and right ware swapped just because of the way I connected it, and target is now specified in semaphore positions rather than stepper positions. The timings change a bit just because of the speed of the motors and we have no way of knowing when they arrive in position (thought the lego servo is much faster than the steppers).


make theLetter string
make theLeftPos number
make theRightPos number
when getPositionsForLetter
.make counter number
.repeat length of key using counter
..if letter counter of key=theLetter
...set theLeftPos to item counter of leftFlag
...set theRightPos to item counter of rightFlag
...stop script
.set theLeftPos to 0
.set theRightPos to 8


when attention
.repeat 3
..set target1 to 1
..set target2 to 7
..wait 1 secs
..set target1 to 3
..set target2 to 5
..wait 1 secs
.set target1 to 0
.set target2 to 8
.wait 2 secs

when start
.make counter number
.
.set target1 to 0
.set target2 to 8
.
.broadcast update
.broadcast load and wait
.forever
..ask "What's the message?" and wait
..broadcast attention and wait
..
..repeat length of answer using counter
...set theLetter to letter counter of answer
...broadcast getPositionsForLetter and wait
...say join [theLeftPos] join ":" [theRightPos]
...set target1 to theLeftPos
...set target2 to theRightPos
...wait 2 secs
..
..set target1 to 0
..set target2 to 8

And here's the "finished" version:


Unfortunatly now I have to admit, I couldn't finish the project - I've only got 1 PF Servo... They cost £20.99 + postage and my lego budget has to cover a lot of other things! Even worse on Ebay there are buy it nows from £28 to £60!!!!! (EV3 medium motors are £19.99 on lego.co.uk but £34.99 on eBay!) I've noticed this before - ebay is some kind of crazy place to buy Lego. Sometimes you get bargains, but on newer stuff you can pay more than buying direct.

Rant Warning - you can skip the next few paragraphs...

To make things worse, Lego just obsoleted Power Functions. PF isn't officially dead (yet), but the new Wedo 2.0 uses a completly different connector. According to Lego PR, the Bluetooth connection between the computer and 2.0 hub means they "needed" to change the cable between the hub and motors... and the tilt sensor now has a "shake" mode... so they needed to change the cable! This is obviously untrue. Previously Wedo used standard PF components, but now the Wedo 2.0 has it's own connector and won't plug into anything else (whereas the old version plugged together like... you know... Lego?). The explanation is that PF is about to be replaced by PF 2.0 (there's a reference here: https://education.lego.com/en-gb/lesi/elementary/wedo-2/faqs) . There's no backward compatibility so throw out all your old sensors and motors!!

It's really about time Lego got its act together on this... three generations of Mindstorms used different cabling (with some backward compatibility at least), Power Functions was introduced to replace the old 9V technics motor system (and versions before that!), with the claim it allowed for future expansion - which only materialised as Wedo. Technics never got any sensor features, and Wedo was kept secret from the public. Each generation of Lego engineers decides that the old plug system is too limiting. Wedo 2.0 delivers nothing in terms of new sensors (yet) and in fact we loose lights and servo's, but they're asking me to throw out about £500 of my own motors sensors and hubs, just to avoid the cable to the computer.

Going Bluetooth has benefits (and disadvantages if you have a lot of them in the same room and group 1's computer pairs to group 2's build - accidentally or deliberately!),  and if I could buy a Bluetooth hub to use with my current motors and sensors and ADD to my wedo system I'd be first in the queue, but starting over with a system that's less capable...

With that rant out of the way, now might not be a great time to invest in Power Functions components! At some point there's going to be some tough decisions whether to invest more in established (but obsolete) 1.0 tech or throw out a lot of expensive stuff, and  start over.

And we're back...


Anyway I was able to test and get both arms working - just not at the same time! It's less precise that the stepper version, and but it works really well. Cost wise its a bit crazy - the hub and two servos would cost about £80, whereas the Arduino version cost less than £10. On the other hand, the lego version demonstrated the power of Lego - I was able fabricate the supporting structure, including gearing way more easily -  building a gearbox for arduino and servo's isn't something I could do. That's where the Wedo really pays off - just being able to combine building and coding so easily...

Thursday, 4 February 2016

Stepper Motor Semaphore

For some reason I can't quite remember I stumbled across some web pages on semaphore, and thought wouldn't it be good to write some code to convert messages to semaphore. 




In Semaphore, each letter is represented by the position of two flags. There are 8 flag positions, numbered clockwise from 0 at the bottom, through 4 (straight up) to 7 bottom right. Of course we could just draw them on the screen but really we want to to actually wave some flags around. 

There are basically three options for physically moving stuff under computer control. For robots we just use DC motors, but all you can do is turn these on and off. Then they spin fast and you've no which orientation they're in. You can add a sensor to track the rotation, but that's hard work. The second option is Servos. These would be perfect - you send them a timing signal which represents a position, and they move to that position. However there's a gotcha - servos typically have a limited rotation of about 180 degrees. That would be Ok if each arm just had to move on its own side, but if you look at the chart, you'll see that sometimes both flags are on the same side - for example the left flag naturally moves from 0 (down) to 4 (up) on the left side (as we see it), but sometimes it needs to move to 5 or 7 - a total angle of 270 degrees. While there are servos that can do this (and we could add gearing to solve the problem) we need to consider a third option.

Stepper Motors have a magnet in the middle, and a set of coils (typically 4) around the outside. 
When we turn on one of the coils the motor turns to align the magnet with the field of the coil. If we turn on each coil in turn, then we can make the motor rotate. However its under our exact control - each time we turn on the next coil the motor turns by exactly one "step". Depending on how the motor is built, each step will be a known angle, so we can move the motor very precisely - with one proviso - we can move it precisely by any required angle, but we've no way of knowing where it is!


We bought two motors and controllers for under £5 on eBay. You can get them cheaper, but we wanted them now! Hook up is simple - two power pins, and 1 pin for each of the four coils. Now we can code this up:

make stepper number
make coilA digital output D4
make coilB digital output D5
make coilC digital output D6
make coilD digital output D7

when fullStep
.forever
..if stepper > 4
...change stepper by -4
..if stepper < 1
...change stepper by 4
..
..set coilA to (stepper=1)
..set coilB to (stepper=2)
..set coilC to (stepper=3)
..set coilD to (stepper=4)

when start
..broadcast fullStep
.
.set stepper to 1
.repeat 2048
..change stepper by 1
..wait 2000 microsecs
.repeat 2048
..change stepper by -1
..wait 2000 microsecs

The four coils are connected to digital outputs, and we run the "fullStep" script all the time in the background. The variable stepper represents which coil is currently turned on. In the main script we increment stepper 2048 times - as the motors I bought take 2048 steps to complete 1 revolution. We then then decrement it to rotate back. We have a pause of 2milliseconds between each step - these are physical things and take time to respond, so if you move them too fast they'll just sit there and jitter. This was as fast as the ones I bought could go.

when fullStep
.forever
..if stepper > 4
...change stepper by -4
..if stepper < 1
...change stepper by 4
..
..set coilA to (stepper=1 or stepper=2)
..set coilB to (stepper=2 or stepper=3)
..set coilC to (stepper=3 or stepper=4)
..set coilD to (stepper=4 or stepper=1)

The original version works fine, but we can get a little better performance out of it by turning on two coils at a time instead of one. When stepper is 2, both coils A and B are turned on, then when it changes to 3, A turns off and C turns on. The magnet now lines up half way between the two active coils.


when halfStep
.forever
..if phase > 8
...change phase by -8
..if phase < 1
...change phase by 8
..
..set coilA to phase = 8 or phase=1 or phase=2
..set coilB to phase = 2 or phase=3 or phase=4
..set coilC to phase = 4 or phase=5 or phase=6
..set coilD to phase = 6 or phase=7 or phase=8


If we combine these two ideas we can "half step" the motor - alternately lining it up with a single could and half way between coils. The sequence is on A, AB, B, BC, C, CD, D, DA... It's now taken 8 half steps to move the same distance as 4 full steps. Movement is a little smoother, and we have finer control over position.

Now its time to wrap all  that up in something we can use in our Semaphore code:

make position number
make target number
make stepsPerTurn number 2048

when halfStep
.make phase number
.
.forever
..if position<target
...change phase by 1
...change position by 0.5
..if position>target
...change phase by -1
...change position by -0.5
..
..if phase > 8
...change phase by -8
..if phase < 1
...change phase by 8
..
..set coilA to phase = 8 or phase=1 or phase=2
..set coilB to phase = 2 or phase=3 or phase=4
..set coilC to phase = 4 or phase=5 or phase=6
..set coilD to phase = 6 or phase=7 or phase=8
..
..wait 1000 microsecs



This improved halfStep script, uses three variables to keep track of the motor: position (where it currently is), target (where we'd like it to be), and phase (where it is in the step sequence). It then uses the half step sequence to move the motor towards the desired target. You'll note that now we're half stepping we can run twice as fast (delaying 1mS).


With that in place we can turn to the problem of semaphore. To do that we need to control 2 flags, and in a "real" programming language we'd do that with an array and a data structure containing the outputs and the positions. Unfortunatly Sniff can't do that - it is after all Scratch, and data structures are the main limitation of a language designed for at primary school children. Instead we need to duplicate the halfStep script and make it operate on a second set of coils.


make leftFlag list of numbers
make rightFlag list of numbers
make key string "abcdefghijklmnopqrstuvwxyz"
when load
.#A
.add 1 to leftFlag
.add 8 to rightFlag
.
.#B
.add 2 to leftFlag
.add 8 to rightFlag
.
.#C
.add 3 to leftFlag
.add 8 to rightFlag
.
.....
.
.#X
.add 5 to leftFlag
.add 7 to rightFlag
.
.#Y
.add 3 to leftFlag
.add 6 to rightFlag
.
.#Z
.add -1 to leftFlag
.add 6 to rightFlag

We add the flag positions to two lists - one for left and right (as we face them). However there's one trick to this - down is position 0, so when we move to position 4 from there we move clockwise, but for the right flag this would hit the left flag as it rotates. We want the right flag to move from the down position to its target position anticlockwise, so instead of recording it as 0 we record it as 8. Simarly when we want the left flag to move to the 7 position, we call it -1

Now we can write some code to look up letters in these lists:

make theLetter string
make theLeftPos number
make theRightPos number
when getPositionsForLetter
.make counter number
.repeat length of key using counter
..if letter counter of key=theLetter
...set theLeftPos to item counter of leftFlag
...set theRightPos to item counter of rightFlag
...stop script
.set theLeftPos to 0
.set theRightPos to 8

Finally we just need to initialise everything, get a message from the user, then step through the letters of the message broadcasting each in turn:

when start
.make counter number
.
.set position1 to stepsPerTurn
.set position2 to 0
.set target1 to position1
.set target2 to position2
.
.broadcast halfStep
.broadcast load and wait
.
.ask "What's the message?" and wait
.broadcast attention and wait
.
.repeat length of answer using counter
..set theLetter to letter counter of answer
..broadcast getPositionsForLetter and wait
..say join [theLeftPos] join ":" [theRightPos]
..set target1 to theRightPos*stepsPerTurn/8
..set target2 to theLeftPos*stepsPerTurn/8
..wait until position1 = target1 and position2 = target2
..wait 0.5 secs
.
.set target1 to stepsPerTurn
.set target2 to 0

And here's the robot actually running:

(idea for next project - use GSM shield to actually receive SMS messages and show them as semaphore!!!).

Download the source code.

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.