“Ultimate” Arduino Doorbell – part 2 (Software)

As mentioned in the previous post about my arduino doorbell I wanted to get the doorbell and my Chumby talking.

As the Chumby runs Linux, is on the network and is able to run a recent version of Python (2.6) it seemed like it would be pretty easy to get it to send Growl notifications to the local network.

This did indeed prove fairly easy and involved three main activities:

  • Listening to the serial port for the doorbell to ring
  • Using Bonjour (formally Rendezvous)/Zeroconf to find computers on the network
  • Sending network Growl notifications to those computers

Getting Python and PySerial running on the Chumby is pretty easy. The Chumby simply listens for the doorbell to send the string ‘DING DONG’ and can then react as needed.


def listen_on_serial_port(port, network):
    ser = serial.Serial(port, 9600, timeout=1)
    try:
        while True:
            line = ser.readline()
            if line is not None:
                line = line.strip()
            if line == 'DING DONG':
                network.send_notification()
    finally:
        if ser:
            ser.close()

port is the string representing the serial port (e.g. /dev/ttyUSB0). network is an object that handles the network notifications (see below).

The network object (an instance of Network) has two jobs. Firstly to find computers on the network (using PicoRendezvous – now called PicoBonjour) and secondly to send network growl notifications to those computers.

A background thread periodically calls Network.find, which uses multicast DNS (Bonjour/Zeroconf) to find the IP addresses of computers to notify:


class Network(object):
    title = 'Ding-Dong'
    description = 'Someone is at the door'
    password = None
    
    def __init__(self):
        self.growl_ips = []
        self.gntp_ips = []

    def _rendezvous(self, service):
        pr = PicoRendezvous()
        pr.replies = []
        return pr.query(service)
    
    def find(self):
        self.growl_ips = self._rendezvous('_growl._tcp.local.')
        self.gntp_ips  = self._rendezvous('_gntp._tcp.local.')
        def start(self):
        import threading
        t = threading.Thread(target=self._run)
        t.setDaemon(True)
        t.start()
    
    def _run(self):
        while True:
            self.find()
            time.sleep(30.0)

_growl._tcp.local. are computers that can handle Growl UDP packets and _gntp._tcp.local. those that can handle the newer GNTP protocol. Currently the former will be Mac OS X computers (running Growl) and the latter Windows computers (running Growl for Windows).

I had to tweak PicoRendezvous slightly to work round a bug on the Chumby version of Python, where socket.gethostname was returning the string '(None)', but otherwise this worked ok.

When the doorbell activates netgrowl is used to send Growl UDP packets to the IP addresses in growl_ips and the Python gntp library to notify those IP addresses in gntp_ips (but not those duplicated in growl_ips). For some reason my Macbook was appearing in both lists of IP addresses, so I made sure that the growl_ips took precedence.


    def send_growl_notification(self):
        growl_ips = self.growl_ips
        
        reg = GrowlRegistrationPacket(password=self.password)
        reg.addNotification()
    
        notify = GrowlNotificationPacket(title=self.title,
                    description=self.description,
                    sticky=True, password=self.password)
        for ip in growl_ips:
            addr = (ip, GROWL_UDP_PORT)
            s = socket(AF_INET, SOCK_DGRAM)
            s.sendto(reg.payload(), addr)
            s.sendto(notify.payload(), addr)

    def send_gntp_notification(self):
        growl_ips = self.growl_ips
        gntp_ips  = self.gntp_ips
        
        # don't send to gntp if we can use growl
        gntp_ips = [ip for ip in gntp_ips if (ip not in growl_ips)]
        
        for ip in gntp_ips:
            growl = GrowlNotifier(
                applicationName = 'Doorbell',
                notifications = ['doorbell'],
                defaultNotifications = ['doorbell'],
                hostname = ip,
                password = self.password,
            )
            result = growl.register()
            if not result:
                continue
            result = growl.notify(
                noteType = 'doorbell',
                title = self.title,
                description = self.description,
                sticky = True,
            )

    def send_notification(self):
        '''
        send notification over the network
        '''
        self.send_growl_notification()
        self.send_gntp_notification()

The code is pretty simple and will need some more tweaking. The notification has failed for some reason a couple of times, but does usually seem to work. I’ll need to start logging the doorbell activity to see what’s going on, but I suspect the Bonjour/Zeroconf is sometimes finding no computers. If so I’ll want to keep the previous found addresses hanging around for a little longer – just in case it’s a temporary glitch.

You can see the full code in my doorbell repository.

Programming a Picaxe 08m chip

After I got my Arduino I felt the urge to brush up on my general electronics knowledge. The last time I’d really played with any circuits was back in about 1994 when I was studying my Technology GCSE – which now is quite a long time ago. So I picked up a copy of Make: Electronics and started reading through it. Sadly I was a bit lazy and just read through the book, rather than actually building many of the circuits suggested. It did come in handy for tips on soldering and I do intend to go back and make some of the circuits – I just got a bit distracted by a new arrival. However the last chapter covered microcontrollers and in particular the Picaxe 08m chip. This really piqued my interest!

The Picaxe 08m is a PIC chip with a pre-installed boot-loader that allows programming the chip via a serial port. This is similar to the way that the Arduino has an AVR chip with a pre-installed boot-loader. There’s also some software for the Picaxe for handling the programming, a bit like the Arduino IDE.

The 08m is massively less powerful than an Arduino. It has 512 *bytes* of program storage and only 14 *bytes* of variable RAM. However it has 5 outputs/4 inputs and can run a single servo. In fact I could have used it for the logic part of my Arduino doorbell. It’s not quite as friendly to get started with as an Arduino though. You need to wire up a simple circuit before you can get going. In fact I actually had to solder together a prototyping board, as I didn’t have much luck trying to used a breadboard. The circuit needed isn’t that complex (assuming you use 3AA batteries for power). The cost of the 08m chip is less that £2. The proto-board is £2, so altogether you can have a simple usable microprocessor for less than £4. It’s also small and doesn’t use much power. So for projects where an Arduino is overkill it’s perfect.

Soldered picaxe 08m prototype board

To make testing out circuits easier I also added a female header to the board, so I could plug in breadboard jumper cables (in the same way as one does with an Arduino Duemilanove):

Picaxe 08m prototype board with header attached

To verify everything worked I wrote the “hello world” program of microcontroller world, a program that simply blinks an LED (by turning pin 1 on and off):

main:
	high 1
	pause 1000
	low 1
	pause 1000
	goto main

That’s Picaxe BASIC by the way. Maybe not as pretty as C, but for a processor with only 14 byte sized variables it’s more than enough.

Then I wired up an LED into the prototype board, along with a small current limiting resistor:

Picaxe 08m prototype board + header blinking LED

Using the Mac version of AXEPad and the Picaxe USB serial cable (which has a stereo socket at one end) I uploaded the program to the 08m chip and saw the LED blinking once every second. I’ve recorded a video of the programming, which should show how straightforward it is:

I’ve got a few projects in mind that are actually space/weight constrained and one in particular that might put the parts involved into extreme peril, so having the option of using a very small and cheap microcontroller is very appealing. I’ll reserve the Arduino now for projects that need it’s extra power and amazing flexibility.

“Ultimate” Arduino Doorbell – part 1 (Hardware)

After a first couple of small Arduino projects I felt the need to make something a bit more useful and permanent.

I had seen Roo Reynolds talking about hacking his doorbell to get it onto Twitter and as our doorbell is a bit rubbish I thought this seemed like a good project. His hack only updated Twitter, so there was no direct physical sign that the doorbell had been rung. Given that our current doorbell is pretty rubbish anyway (it should ring, but just makes a rattling sound), I decided to start off with the physical/audible side of things and then later move on to pushing notifications out to laptops on the local network or beyond…

I’ve been documenting my progress on Flickr now for a while.

Take apart wireless doorbell

Following Roo’s approach, I picked up a cheap wireless doorbell from Tesco for about £9 and took it apart:

I was able to verify that I could turn an LED on/off with the doorbell at this stage, so I knew I could use that as a signal in the Arduino. Using a multimeter also let me figure out some more details about the voltage and current used to power the speaker:

Testing wireless doorbell with multi-meter

This was about 3.1 V and 75mA output. That’s a few milliamps more than the Arduino can tolerate, so I knew I had to make sure I put a resistor (22KOhm) in between the doorbell and the Arduino. The doorbell would also need to draw power from the Arduino, but luckily the Arduino has a separate 3V output, so that wasn’t an issue.

Testing connecting Arduino to doorbell

From there I verified that when the doorbell was activated I could read a drop in voltage from the wire on the doorbell labelled “SPI”. At this point I had the input for my Arduino.

Servos and prototypes

The next step was to provide some sort of audible output. Originally I had thought about just adding a buzzer, but fancied something a bit more old-fashioned. I figured it’d be good fun if the nice 21st century tech of the Arduino used some rather more ancient technology to create sound – a bell.

Using a micro servo from Oomlout I created a couple of prototypes.

I made a pretty simple circuit to hook up the servo, doorbell and arduino:

The first prototype used some lego and a bell from a Christmas ornament:

This worked, but the servo was probably louder than the bell!

Next I got hold of a small brass bell from a music shop. Luckily the top unscrewed and would let me easily attached it to a piece of lego. So another prototype was created using the small brass bell:

Prototype doorbell with brass bell

This worked much better!

The bell is about 100g in weight, which isn’t massive, but when it’s flung around the lego prototype would tend to move too. Not so good when this will live on the kitchen window sill. So I’d need something sturdier for the finished version.

A little soldering

As well as trying out a better bell I also made the circuit for the bell and servo more permanent, by soldering everything up on a piece of stripboard. I also used a few headers, so most of the circuit would plug into the Arduino – like a rudimentary shield. The wire to the pin controlling the servo, was left to be plugged in separately. I hadn’t soldered anything since school, so I ended up swearing quite a bit trying to do this. For me it was probably the trickiest part of the whole exercise, but it did work in the end. Just glad I had a multi-meter with a continuity mode to find the short-circuits – a knife worked well to clear up some of those.

Stripboard soldering

Full soldered doorbell + arduino

Woodwork

I next turned to my (t)rusty woodwork skills to create a sturdier version. First off some pieces of wood to mount the Arduino, doorbell circuit and servo:

Arduino and doorbell mounted on wood block

Servo mounted in wooden block

Next came the base and first part of the bell moving arm:

Then I added the top piece of the arm as well as the picture wire to make the bell swing properly:

Closeup of bell innards

At this point everything worked as expected:

Tidying up

After the sawing and sanding was finished there was still some general tidying up to do.

Once I’d taped down the servo wire and antena wire with electrical tape I needed to deal with the movement of the whole piece when the arm swings out. First I got hold of some Sugru and made some small rubberised feet to prevent the bell sliding around:

Sugru rubber feet on bell

The next task was to add a counter weight so the bell wouldn’t tip over. For this I made two piles of fifteen pennies, which I wrapped in electrical tape and taped to the ledge on the reverse side from the Arduino:

Counter weights on back/front of doorbell

Eventually these will be covered up and will probably actually make up part of the internal structure of the outer decoration. This should also mean they’ll end up being attached better. For now though electrical tape has proved sufficient.

One final tweak involved inserting some small nylon washers either side of the arm:

Washer and tidier wire

This was done to help make the movement of the arm more consistent and slightly smoother. Previously I was finding that the arm would shift position slightly, which sometimes caused problems for the servo.

Deployment

With the hardware finished I then set about actually getting it all up and running as our real doorbell. So imagine my horror when upon placing the doorbell on our kitchen window sill and connecting the power everything went haywire and the arm just constantly moved! After some tweaking of the code and kitchen-side debugging I realised that I really should make use of the Arduino’s internal pullup resistors for the doorbell pin. Up until that point I had left it “floating”. When powered by the USB this rarely drifted to zero, so I thought it was working fine. However on mains power it regularly dropped quite low, making the Arduino think the button had been pressed, triggering the servo. Configured the pullup resistor and tweaking the activation threshold (as it was now higher than zero) sorted out this problem perfectly:

Conclusion

So we now have a slightly Heath Robinson doorbell. It works better that our old one. There’s also plenty of scope for making it do more too. In fact phase two will be mostly about connecting the doorbell to my Chumby to get it communicating with the local network.

Check out my doorbell git repository on github for the code, as well as a fritzing circuit file.

Kite Physics

I’ve finally managed to finish the Kite Physics Demo I started back in October:



Kite Physics Demo

It’s more of a plaything than anything else. It did give me a chance to try out writing some physics code again, something I don’t get much of a chance to do during web development. Though of course advances in Javascript speed and the Canvas tag may change that in the future.

Originally I made use of the keyboard to control the figure and the kite, but I switched to using the mouse as it makes interacting with the scene more pleasing. There’s a certain joy to being able to grab the kite to move it around or shift the wind direction by nudging a cloud.

It’s all written in Java, using maven to build and package. The code is available in my kite repo on guthub.

There’s about one third of a physics engine in the code. There’s no real collision detection for example. Most of the physics code is for handling constraints and basic forces. For the constraints I made use of the Gauss-Seidel technique, as outlined in Advanced Character Physics by Thomas Jakobsen. This was quite a revelation to me. Previously I’d experimented with rigid body dynamics (see my 2D racing game circa 2001), but the Gauss-Seidel method seemed much more intuitive. I found it much easier to think of bodies made up of points connected by lines. The “physics” naturally emerges from the way the bodies are then constructed.

The core physics code (in the com.psychicorigami.physics.* package) is fairly well structured. There a bit of compiler placation to (theoretically) allow for the same code to work for 2D and 3D physics. I’ve only actually implemented the 2D side of things, but have tried to use generics to make room for 3D too. When everything is points and lines, moving from 2D to 3D is not that tricky. Whereas for rigid body dynamics this can mean quite a big change in representation.

The code in the default package is used for the specifics of the demo itself, so is a bit messy really. Lots of tweaking and prodding was needed to get things how I wanted.

The physics for the kite and wind interaction were aided massively by this guide to forces on a kite. Particularly useful for understanding how to tweak the rigging, centre of gravity and centre of pressure of the kite to make it behave in a pleasing – if not entirely realistic – manner.

At some point I hope to revisit the physics code here. I’ve always had a wish to create something like Karl Sims “blocky creatures”, but lacked the specific technical knowledge. Know that I have a technique for simulating complex constraints in an intuitive manner maybe I’ll manage it yet.

watch-cp.py

During software development it’s key to minimize the time between editing code and seeing the results of a change. During web-development the constant tweaking of CSS/HTML/Javascript etc means you’re always reloading the browser to see changes.

At work I do a lot of Java web development, which normally involves compiling code, packaging into a .war file and deploying it to Tomcat (running locally). I make use of the maven tomcat plugin, so it’s just a case of calling maven tomcat:redeploy. However it still takes tens of seconds (or more if there are tests to run). For quick tweaks of css it’s nice to be able to short-circuit this process.

Tomcat unpacks the .war file to another directory after the app has been deployed. All the .jsp pages, css and javascript files can be edited in this directory and changes can be seen immediately. However getting into the habit of editing these files within this directory is usually a bad idea, as the files will get overwritten at the next deployment.

We’ve been using compass lately for css and it has a handy command:


    compass watch

That monitors .sass files for changes, then re-compiles them to css as they change, so you can see changes quickly (without needing to manually run compass each time).

So I thought I could do something similar for the editable files within the war file. So I created watch-cp.py. It simply monitors a set of files and/or directories for changes and copies over files that have changed to a source file or directory. To provide a bit of feedback it prints out when it spots a changed file, but beyond that it’s pretty brute-force in it’s approach.

watch-cp.py works in a very similar way to the cp command, but without as many options. For example:


    # recursively copy files from src/main/webapp to tomcat
    watch-cp.py -r src/main/webapp/* ~/tomcat/webapps/mywebapp

This is great as it means I can edit my sass files, have them compiled to css by compass, then copied over to tomcat without needing to intervene. It takes a second sometimes, but it’s fast enough for the most part.

Feel free to fork the gist of watch-cp.py on github.

iPhone Brighton Buses webapp/javascript front-end

Here in Brighton a good number of the bus stops have electronic boards, that tell you when the next buses are due. The data for these boards is available online and even provides data for stops that don’t have the electronic boards. In fact there’s an free iPhone app available, so you can get the data easily on the move.


Brighton Station (Stop B)

After playing around with iPhone javascript apps, I thought it would be interesting to try and create a javascript app for the bus times. I had some specific ideas about how I wanted the app to work. I was also keen on trying out some more “HTML 5” tech. Plus I do like things to be (at least in principle) cross-platform, so this has a chance of working ok on Android phones (though I’ve not tested it on one).

There are still a few rough edges, but you can try out the app yourself at:

It will prompt you to add a stop. If you type in the text field, you’ll get a list of stops that match. If your browser supports geo-location, you’ll also see a “Find nearby” button, which will list the nearest few stops.

I had the pleasure of demoing this app at the Async Javascript show’n’tell last month. I quickly outlined how it worked, which involves the following:

Getting the data

The buses.co.uk site has an API, which I used to scrape all of the bus stops in Brighton. I chose to scrape the update data from the website itself though, as I couldn’t get the API to give me the combined services for each stop (so you can see when the next 7 and 81 are coming for example). There are typically two stops for each name – one either side of the road. The updates are for both directions, so I actually merged the stops together – which makes searching easier.

All of the stop data was stored in a single SQLite database – mostly for convenience. The database is used in a read-only method in the actual running app. I’m sure I could use something a bit better, particularly when it comes to the distance queries. Currently, as there are a relatively small number of stops I’m using a brute force method to find the nearest stops, but I’m sure with the use of a proper spatial index this could be done a lot more efficiently. If this was scaled up to work for all stops in the UK, then that would be a necessity.

Geo-location

Initially the geo-location was pretty straightforward – I simply used the getCurrentPosition function and I got a latitude and longitude back. Testing in Firefox and Safari on the mac gave fairly reasonable results. However on the iPhone itself I started to notice it wasn’t very accurate. Sometimes it was out by several 100 metres, meaning that stops I was standing next to were sometimes not showing up at all! I had noticed, in the past, that the built-in map app sometimes has a bit of “lag” in getting an accurate position. So I switched to using watchPosition and polling for the position for several seconds. This worked pretty well, as the initial result would only be vaguely in the right place and then after a few seconds the position would become more accurate and the listing of nearby stops would start to look more sensible.

Look and feel

Originally I’d planned to mimic the look and feel of the iPhone’s built-in weather app. The app is built around a similar concept – you search for bus stops and add them to a list of stops that you can flick through. I tried to get a nice animated sliding action working, but kept on running into trouble on the device itself. In Safari and Firefox the animation all worked ok, but I suspect there’s an issue on the iPhone when you are dragging an area that limits redrawing. In the end I had to ditch the flip/swipe gesture too – interfering with the touch events again seemed to cause some rendering issues on occasion. So instead simply clicking on the left or right of the timetable moves between pages. It’s a slightly less complicated way of doing things, so there’s less that can go wrong really.


Old Brighton No. 5 Bus

Deployment

As this was a nice simple app (on the back-end at least), I decided to take a little time to create a Fabric file to control deployment. The app is hosted on Webfaction, where I have already setup key-based login for ssh. The app is deployed using mod_wsgi with a daemon process, so that one merely needs to copy over the new code, then “touch” the .wsgi file restart the daemon process. Not exactly tricky to do, but making it a one-button process saves making any mistakes.

To trigger the deployment I run my fab file like this:


fab --user=lilspikey --hosts=lilspikey.webfactional.com deploy:webapps/buses/app/

I actually have that in a shell script, that isn’t checked into git, so that the deployment specific username, host name and remote directory aren’t checked into source control. If I wasn’t using key-based login, I’d need to specify a password and I definitely wouldn’t want to check that into git!

Source code

You can get the source code on github in my buses repository.

Chumby to Arduino communication using PySerial

So here are a few notes on getting a Chumby to talk to an Arduino using PySerial (and Python). It’s pretty easy, but I’ll document it to make it obvious. As the Chumby is sometimes a bit slow with a few of these steps, it’s good to know it will work in the end.

First you’ll want Python on the Chumby. At the time the latest version already compiled for the Chumby is Python 2.6, so it’s pretty up-to-date.

Once you’ve got Python installed and on a USB stick you’ll also want to download PySerial – I picked the latest version PySerial-2.5-rc2.

With PySerial expanded and on the USB stick (alongside Python) you’ll want to put the USB stick in the Chumby and connect to it via SSH.

Change to the directory for the USB stick (e.g. cd /mnt/usb).

You should see (at least) two directories, one for Python and one for PySerial:


chumby:/mnt/usb-EC5C-3D0A# ls -l
drwxr-xr-x    6 root     root         4096 Jun 26 21:15 pyserial-2.5-rc2
drwxrwxrwx    4 root     root         4096 Jan 10 13:51 python2.6-chumby

You’re first instinct may be to try and install PySerial via the usual call to python setup.py install. However this appears not to work.

All is not lost though – just manually copy the relevant directory (serial) from PySerial to the python site-packages directory, e.g.:


cp -r pyserial-2.5-rc2/serial python2.6-chumby/lib/python2.6/site-packages/

Know to check that’s worked open a python prompt and try to import the serial library:


chumby:/mnt/usb-EC5C-3D0A# python2.6-chumby/bin/python
Python 2.6.2 (r262:71600, May 23 2009, 22:28:43) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> 

If you don’t see any errors (as above) then everything has installed ok.

Next step is to try out connecting an Arduino.

So first off you’ll want to ensure the Arduino has a program that can read from the serial port – to show that everything is working ok. In my case I picked my Morse Code program. This will read bytes from the serial port and toggle the built-in LED (on pin 13), so it’s handy for verifying the serial port is working.

So now you have a program loaded on the Arduino, connect it to the Chumby. The Arduino should get enough power from the Chumby to start up ok.

You need to work out which serial port the Arduino is using on the Chumby. List the tty’s in /dev and pick the most likely looking one (should have USB in it’s name):


chumby:/mnt/usb-EC5C-3D0A# ls /dev/tty*
/dev/tty      /dev/ttyS00   /dev/ttyS02   /dev/ttyS1    /dev/ttyS3
/dev/ttyS0    /dev/ttyS01   /dev/ttyS03   /dev/ttyS2    /dev/ttyUSB0

On my Chumby the serial port was /dev/ttyUSB0.

Now open up a python prompt again and try talking to the Arduino. You’ll need to configure the baud-rate of the serial port to match the program on the Chumby. In my case this was 9600.



chumby:/mnt/usb-EC5C-3D0A# python2.6-chumby/bin/python
Python 2.6.2 (r262:71600, May 23 2009, 22:28:43) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)   
>>> ser.write('sos')
3

If you are using the same morse code program you should see the LED blink out ‘DOT-DOT-DOT DASH-DASH-DASH DOT-DOT-DOT’ – confirming that the serial port works.

This is really quite handy, as the Chumby is a small low-power Linux server. Coupled with Python this means it’s really easy to get any Arduino based project online, without needing a “normal” computer constantly running. Not quite as self-contained as using an Ethernet Shield, but the Chumby is fairly small, so it and an Arduino will easily sit on a window ledge (for example).

Arduino Tone Generator/”Theremin”

So here’s another quick Arduino project. It is a “theremin” of sorts, but whereas a real theremin uses antennas to control pitch and volume this on uses a potentiometer for pitch and a push button for volume. The tone is output via a piezo buzzer (as used for generating morse tones in the previous project).


Arduino "Theremin"

The voltage from the potentiometer is read via analogRead, then is mapped to a freqency to output on the buzzer. To make things sound nicer the frequencies are limited to the twelve “well tempered” notes. As the potentiometer is turned the note played changes. There’s a little bit of smoothing (legato) in between note transitions too (so it sounds a bit more theremin-like).

All code for this Arduino “theremin” is available on github, as part of my Arduino Sketches project.

Here’s a demo of the tone generator in action:



My First Arduino Project (Morse Code)

So I finally have an Arduino. I’ve been hankering after one for a while now, after seeing what Build Brighton and others have been able to do with them. So I was very happy when my better half paid attention to the hints I’d been dropping and got me an Arduino starter kit for my birthday. That was only a few days ago and thanks to how wonderfully easy the Arduino IDE is, it hasn’t taken long for me to get things working. The simplicity of writing the code, hitting upload and seeing the effect on the Arduino within seconds makes it really quick to try out different ideas. The only bit that’s tricky (for me at least) is the electronics side of things. Due to a slight fear of accidentally burning out the 8bit AVR chip at the core of the Arduino I’m being super cautious. Though this is due to my at best high school knowledge of electronics. That and the fact that I’m pretty much a software boy.

So what to make first? Well morse code seemed like a good starting point. I’d written an app to output morse on the capslock LED before and the starter kit had LEDs, so it seeded like a good starting point. On closer inspection there was also a piezoelectric buzzer – so even better it was possible to generate a tone too!

Getting the LED to turn on and off was pretty easy and it forms the standard “hello world” program for the Arduino. Getting the buzzer to generate a tone was marginally trickier, but not that hard and basically just consisted of turning it on and off quick enough to cause a vibration and therefore make a sound. With the help of this guide to making the Arduino play the Can-Can I also had details of how to wire the circuit correctly (in particular adding in a suitable resistor to avoid overloading the AVR chip).

Using the starter kits breadboard, jumper wires, a 330 Ohm resistor, an LED and the piezoelectric buzzer I put together this:


Arduino Morse Code Circuit

The buzzer had it’s positive pin wired in to pin 4 on the Arduino and the LED was in turn wired in to pin 13. In the picture above, I arbitrarily used yellow jumper leads for “ground” and green for positive. So one green lead goes to each pin (4 and 13) and only one yellow lead goes to the “ground” on the Arduino.

Initially I hard-coded the message the Arduino was going to output, but having to re-compile each time to change the message seemed a little tedious. So I decided to get the Arduino to read from the serial port, store the characters it read in, then output the relevant morse. To achieve this the program has a 512 byte buffer that it fills up with data read from the serial port. If the buffer is full it signals this by writing back a -1 down the serial port – otherwise it echos back what it has read in. As it plays the morse it moves along the buffer looking for the next character. Once all characters are output it resets the buffer. The program is actually able to read from the serial port whilst it is turning the LED on/off and generating tones. It’s only limited by the size of the buffer it is using and the fact that it can read faster from the serial port than it can output morse code.

Most of the work in the code revolved around trying to both read from the serial port and generate tones. If the morse was known ahead of time, it would be pretty easy to right several for-loops to run through each character generating tones until we were finished. However the program would not start reading from the serial port until it had finished outputting the morse. So apart from using some basic state-machine style antics to keep track of which character we were on and whether we were currently during a dot, dash or silent period the major a-ha moment for me was realizing how to easily generate a consistent tones without using delays in the code. In previous code I’d seen for generating tones, the code looked like:


for (long i=0; i < numCycles; i++){
    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait againf or the calculated delay value
}

This is nice and easy to follow, but all those calls to delayMicroseconds mean you are hanging around waiting for the air to move to make a sound.

As I wasn't too concerned with the particular fidelity of the sound from the buzzer I opted for the following instead:


void morse_pulse_on() {
  digitalWrite(LED_PIN, HIGH);
  unsigned long period = micros() % buzzer_delay;
  digitalWrite(BUZZER_PIN, period < (buzzer_delay>>1)? HIGH : LOW);
}

This was called every time through the loop() function if a sound needed to be played. As there is no delay in calling it, one could then immediately perform other tasks, such as checking for new serial data or turning the LED on and off. It's quite simple real - the modulus operator (%) is used to get the sub-divide the current time in microseconds into a number between 0 and buzzer_delay (a value pre-calculated to let us generate the right frequency) representing the current "period". If we are halfway through this period then we set the buzzer to HIGH, otherwise we set it to LOW. By repeatedly calling morse_pulse_on we end up with (in this case) a glorious 700Hz tone.

All code for this Arduino morse code program is available on github, as part of my Arduino Sketches project. Hopefully I'll add more code to that project as I get a chance to delve deeper into what the Arduino can do.

Here's a demo of the whole thing in action:



UPDATE: not long after finishing this, I discovered the tone and noTone functions. These produce a better tone than the technique outlined above. Though they do involve use of one of the interrupts on the arduino, that's normally used for PWM on pins 3 and 11 - not that it's a problem for this project.

Chumby Podcast Client Source Code

Ok so I blogged about a podcatcher/podcast client for the Chumby quite a while ago (August 2008 to be precise). At the time I said I’d tidy things up and release the source code etc. Well that didn’t quite happen, but I figured I might as well release the source code. So seeing as I’ve been using git a lot lately and github is easy to use I thought that’d I’d best just put online what I had.

So you can now find the hybrid Python, Javascript and Flash Chumby postcast client I dubbed chumbycast, on github. I’m providing the code just for the curious – I’ve had at least one request for it, but I’m not really going to detail too much of how it works. Though some of this is outlined in the original post where I mentioned the project.

I am tempted to revive this project a bit, but probably by trying a different approach. I mostly gave up on this as I was creating a UI on the Chumby in Flash and my Flash skills aren’t exactly great, plus I was trying to use mtasc which hampered things further. Which is not to belittle mtasc – it’s just with limited time and no previous Flash experience I wasn’t exactly helping myself by not using some nice friendly Flash IDE.

I’ve since realised that if I ditched the Flash UI I could probably get quite a bit done. The Python httpserver side of things was pretty easy. So if I focussed on that I would then have a few of ways of providing a UI by hijacking existing functionality on the Chumby.

  • The Chumby runs a httpserver on port 8080 when an ipod is plugged in, which the UI uses to access playlists etc. I could mimic this approach and effectively make the podcast client look like an iPod as far as the Chumby’s UI was concerned. By plugging in a USB stick loaded up with the podcast client everything would behave the same as if you had plugged in an iPod.
  • It’s possible to create playlist files and edit the “My Streams” section programmatically. Each podcast subscribed to would create a matching pls or m3u file and be added to the “My Streams” section.
  • Create a javascript/web UI for controlling the playback and subscriptions to podcasts and other podcast management tasks (like removing old files, manually downloading older episodes etc) from another computer. Possibly adding bonjour/zero-conf support so the Chumby can be browsed to easily

I would need to see whether those first two could be made to work for my purpose, but it would make sense to just use the existing UI on the Chumby – rather than creating a new one. The existing chumbycast code already provides a javascript/web UI for controlling the playback on the Chumby. This was originally done so I could remote control the chumby, but also so that I could easily create and debug an API for the Flash UI to use.

The other major missing feature is allowing the podcasts to be paused part way through. The current client does not support this, as the audio files are streamed and not downloaded. So that would be the first change to make. Now that I’ve dug out the code maybe I’ll be inspired to play around some more. I’ve also been listening to a lot more podcasts (thanks to Huffduffer) so it might happen yet.