Category: computers suck

  • qrclock, the demo reel

    classy cable for the Quite Rubbish clock

    The video of the Quite Rubbish Clock isn’t running the same code that’s in the listing. Here it is, showing off some of the handy code that’s in bgreat’s nokiaSPI Python class:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # qrmovie
    
    import time
    # need to use git://github.com/mozillazg/python-qrcode.git
    import qrcode
    from PIL import Image, ImageFont
    import ImageOps
    # uses bgreat's SPI code; see
    # raspberrypi.org/phpBB3/viewtopic.php?f=32&t=9814&p=262274&hilit=nokia#p261925
    import nokiaSPI
    
    noki = nokiaSPI.NokiaSPI()              # create display device
    qr = qrcode.QRCode(version=1,           # V.1 QR Code: 21x21 px
    error_correction=qrcode.constants.ERROR_CORRECT_M,
    box_size=2, border=1)
    bg = Image.new('1', (84, 48))           # blank (black) image background
    
    # intro
    noki.cls()
    noki.led(0)
    time.sleep(3)
    for i in range(0,769,32):
        noki.led(i)
        time.sleep(0.04)
    
    # display is 14 columns by 8 rows
    noki.centre_word(1, 'scruss.com')
    noki.centre_word(3, 'presents')
    time.sleep(3)
    noki.cls()
    noki.centre_word(1, 'qrclock')
    noki.centre_word(2, 'the')
    noki.gotorc(3,3)
    noki.text("[Q]uite")
    noki.gotorc(4,3)
    noki.text("[R]ubbish")
    noki.gotorc(5,3)
    noki.text(" Clock")
    time.sleep(3)
    
    elapsed=0
    start_time = time.time()
    while (elapsed<12):
        qr.clear()
        newbg = bg.copy()                   # copy blank background
        s = time.strftime('%Y-%m-%d %H:%M:%S')
        qr.add_data(s)                      # make QR Code of YYYY-MM-DD HH:MM:SS
        qr.make()
        qrim = qr.make_image()              # convert qrcode object to PIL image
        qrim = qrim.convert('L')            # make greyscale
        qrim = ImageOps.invert(qrim)        # invert colours: B->W and W->B
        qrim = qrim.convert('1')            # convert back to 1-bit
        newbg.paste(qrim, (18, 0))          # paste QR Code into blank background
        noki.show_image(newbg)              # display code on LCD
        time.sleep(0.4)                     # pause before next display
        elapsed = time.time() - start_time
    
    noki.cls()
    noki.centre_word(1, 'for')
    noki.centre_word(2, 'more')
    noki.centre_word(3, 'details')
    time.sleep(3)
    noki.cls()
    noki.load_bitmap("blogpost-nokia.bmp", True)
    time.sleep(7)
    noki.cls()
    noki.centre_word(3, 'fin')
    noki.centre_word(5, 'scruss, 2013')
    time.sleep(1)
    for i in range(768,-1,-32):
        noki.led(i)
        time.sleep(0.05)
    time.sleep(1)
    noki.cls()
    

    (This source, plus nokiaSPI class: qrclock-movie.zip)

    Lines 43-58 show off the QR clock for a maximum of 12 seconds. Any more, and you’d get really bored.

    The screen handling functions I used are:

    • cls() — Clears the screen.
    • led(brightness) — sets the backlight to brightness. For me, full brightness is at 768. A value of zero turns the backlight off. If you don’t have the screen LED connected to one of the Raspberry Pi’s PWM pin, this will either be full on (for any brightness >= 1), or off, for brightness=0. This is used to fade up the screen in lines 24-26, and fade it down far too theatrically in lines 72-74.
    • show_image(PILImage) — display a single bit depth black and white Python Imaging Library object PILImage. This can be no larger than 84×48 pixels.
    • load_bitmap(file, Invert) — load a single bit depth black and white BMP file of maximum size 48×84. If Invert is true, keep the colours as they are, otherwise swap black and white to make a negative image. nokiSPI flips images by 90°, so the image I loaded to show the URL of the blog post looks like this:
      blogpost-nokia
      (I know, I could have generated this in code, but I’d already made the image using qrencode. I couldn’t be bothered working out the image size and offsets.)

    The text handling functions I used are:

    • gotorc(row, column) — move the text cursor to row, column. The screen only has 14 columns by 8 rows if you use the standard 6×6 pixel font, so keep your text short to avoid disappointment.
    • text(text) — write text at the current cursor position.
    • centre_word(row, text) — write text centred in row row. Since the text rows are a maximum of 14 columns, text with an odd number of characters will appear slightly off-centre.

    There are many more functions in the nokiaSPI class; watch the demo, have a dig through the source and see what you can use.

  • The Quite Rubbish Clock

    Hey! This article is really old and probably doesn’t work any more: things have changed a lot in Raspberry Pi world since 2013

    Update 3: code for the demo video is here.

    Update 2: In which I actually post working code.

    Update: Eep! This post was featured on the Raspberry Pi blog today. Thanks, Liz!

    And now for something completely different:

    … a clock that isn’t human readable. You’ll need a QR code reader to be able to tell the time.

    Nokia screen on Raspberry Pi

    This, however, is not the prime purpose of the exercise. I was looking for an excuse to try some direct hardware projects with the GPIO, and I remembered I had a couple of Nokia-style surplus LCDs lying about that could be pressed into service. These LCDs aren’t great: 84×48 pixels, 3V3 logic, driven by SPI via an 8-pin header which includes PWM-controllable LED backlighting. They are cheap, and available almost everywhere: DealExtreme ($5.36), SparkFun ($9.95), Adafruit ($10, but includes a level shifter, which you really need if you’re using a 5V logic Arduino), Solarbotics ($10) and Creatron (about $12; but you can walk right in and buy one). Despite being quite difficult to use, helpful people have written drivers to make these behave like tiny dot-addressable screens.

    I’d been following the discussion on the Raspberry Pi forum about driving the Nokia LCD from a Raspberry Pi. Only when user bgreat posted some compact code that was supposed to run really fast did I dig out the LCD board and jumper wires. Building on bgreat’s nokiaSPI.py class and a few other bits of code, here’s what I built to make this singularly pointless clock:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # qrclock - The Quite Rubbish Clock for Raspberry Pi - scruss, 2013-01-19
    
    import time
    # need to use git://github.com/mozillazg/python-qrcode.git
    import qrcode
    from PIL import Image
    import ImageOps
    # uses bgreat's SPI code; see
    # raspberrypi.org/phpBB3/viewtopic.php?f=32&amp;amp;amp;amp;t=9814&amp;amp;amp;amp;p=262274&amp;amp;amp;amp;hilit=nokia#p261925
    import nokiaSPI
    
    noki = nokiaSPI.NokiaSPI()              # create display device
    qr = qrcode.QRCode(version=1,           # V.1 QR Code: 21x21 px
                       error_correction=qrcode.constants.ERROR_CORRECT_M,
                       box_size=2, border=1)
    bg = Image.new('1', (84, 48))           # blank (black) image background
    
    while 1:
        qr.clear()
        newbg = bg.copy()                   # copy blank background
        s = time.strftime('%Y-%m-%d %H:%M:%S')
        qr.add_data(s)                      # make QR Code of YYYY-MM-DD HH:MM:SS
        qr.make()
        qrim = qr.make_image()              # convert qrcode object to PIL image
        qrim = qrim.convert('L')            # make greyscale
        qrim = ImageOps.invert(qrim)        # invert colours: B-&amp;amp;amp;gt;W and W-&amp;amp;amp;gt;B
        qrim = qrim.convert('1')            # convert back to 1-bit
        newbg.paste(qrim, (18, 0))          # paste QR Code into blank background
        noki.show_image(newbg)              # display code on LCD
        time.sleep(0.4)                     # pause before next display
    

    (Convenient archive of all the source: qrclock2.zip, really including bgreat’s nokiaSPI class this time …)

    To get all this working on your Raspberry Pi, there’s a fair amount of configuration. The best references are bgreat’s own comments in the thread, but I’ve tried to include everything here.

    Enabling the SPI kernel module

    As root, edit the kernel module blacklist file:

    sudo vi /etc/modprobe.d/raspi-blacklist.conf

    Comment out the spi-bcm2708 line so it looks like this:

    #blacklist spi-bcm2708

    Save the file so that the module will load on future reboots. To enable the module now, enter:

    sudo modprobe spi-bcm2708

    Now, if you run the lsmod command, you should see something like:

    Module                  Size  Used by
    spi_bcm2708             4421  0

    Installing the WiringPi, SPI and other required packages

    WiringPi by Gordon is one of the neater Raspberry Pi-specific modules, as it allows relatively easy access to the Raspberry Pi’s GPIO pins. For Raspbian, there are a few other imaging libraries and package management tools you’ll need to install here:

    sudo apt-get install python-imaging python-imaging-tk python-pip python-dev git
    sudo pip install spidev
    sudo pip install wiringpi

    Installing the Python QR code library

    Finding a library that provided all the right functions was the hardest part here. I ended up using mozillazg‘s fork of lincolnloop‘s python-qrcode module. mozillazg’s fork lets you use most of the lovely PIL methods, while the original hides most of them. Since I had to do some image compositing and colour remapping to make the image appear correct on the Nokia screen, the new fork was very helpful.

    To install it:

    git clone git://github.com/mozillazg/python-qrcode.git
    cd python-qrcode/
    sudo python ./setup.py install

    The tiny 84×48 resolution of the Nokia screen doesn’t give you many options for sizing QR codes. For the time display of the clock, a 21×21 module Version 1 code with two pixels per module and one module margin just fits into 48 pixels. Using a medium level of error correction, you can fit the 19-character message (such as “2013-01-19 18:56:59”) into this tiny screen with a very good chance of it being read by any QR code reader.

    (In the video, there’s a much larger QR code that’s a link to this blog post. That’s a Version 7 code [45×45 modules] at one pixel per module and no margin. This doesn’t meet Denso Wave’s readability guidelines, but the Nokia screen has large blank margins which seem to help. It won’t read on every phone, but you’re here at this link now, so you don’t need it …)

    Wiring it all up

    (Do I really need to say that you’ll be messing around with the inner delicate bits of your Raspberry Pi here, and if you do something wrong, you could end up with a dead Raspberry Pi? No? Okay. Just make sure you take some static precautions and you really should have the thing shut down and powered off.)

    You’ll need 8 female-female right-angled ones). Note that the thick border of the LCD is the top of the screen. These boards are made who-knows-where by who-knows-whom, and there’s a huge variety of labels and layouts on the pins. My one appears to be yet another variant, and is labelled:

    1. VCC
    2. GND
    3. SCE
    4. RST
    5. D/C
    6. DNK(MOSI)
    7. SCLK
    8. LED
    screen labels

    This is how I wired it (from comments in bgreat’s code and the GPIO reference):

     LCD Pin       Function      Pi GPIO Pin #   Pi Pin Name
    ============= ============= =============== =============
     1 VCC         Vcc            1              3.3 V
     2 GND         Ground        25              GND
     3 SCE         Chip Enable   24              GPIO08 SPI0_CE0_N
     4 RST         Reset         11              GPIO17
     5 D/C         Data/Command  15              GPIO22
     6 DNK(MOSI)   Data In       19              GPIO10 SPI0_MOSI
     7 SCLK        Serial Clock  23              GPIO11 SPI0_SCLK
     8 LED         Backlight     12              GPIO18 PWM0
    GPIO wiring
    back of screen

    Wire it up, and fire up the program:

    sudo ./qrclock.py

    Yes, code that accesses GPIO needs to be run as root. Pesky, but helps you avoid running code that accidentally scrams the nuclear power station you’re controlling from your Raspberry Pi …

  • Too many QR Codes

    I have, of late, been rather more attached to QR Codes than might be healthy. I’ve been trying all sorts of sizes and input data, printing them, and seeing what camera phones can scan them. I tried three different devices to scan the codes:

    • iPhone 4s – 8 MP, running either i-nigma (free) or Denso Wave’s own QRdeCODE ($2). QRdeCODE is better, but then, it should be, since it was created by the developer of the QR Code standard.
    • Nexus 7 – 1.2 MP, running Google Goggles.
    • Nokia X2-01Catherine‘s new(ish) phone, which I can’t believe only has a 0.3 MP VGA camera on it. Still, it worked for a small range of codes.

    QR Code readability is defined by the module size; that is, the number of device pixels (screen or print) that represent a single QR Code pixel. Denso Wave recommends that each module is made up of 4 or more dots. I was amazed that the iPhone could read images with a module size of 1 from the screen, like this one:

    hello_____-ei-m01-300dpi

    On this laptop, one pixel is about 0.24 mm. The other cameras didn’t fare so well on reading from the screen:

    • iPhone 4s – Min module size: 1-2 pixels (0.24-0.48 mm/module)
    • Nexus 7 – Min module size: 2-3 pixels (0.48-0.72 mm/module)
    • Nokia X2-01 – Min module size: 3-4 pixels (0.72-0.96 mm/module)

    So I guess for screen scanning, Denso Wave’s recommendation of 4 pixels/module will pretty much work everywhere.

    I then generated and printed a bunch of codes on a laser printer, and scanned them. The results were surprisingly similar:

    • iPhone 4s – Min module size: 3-4 dots (0.25-0.34 mm/module)
    • Nexus 7 – Min module size: 4-5 dots (0.34-0.42 mm/module)
    • Nokia X2-01 – Min module size: 8-9 dots (0.68-0.76 mm/module)

    A test print on an inkjet resulted in far less impressive results. I reckon you need to make the module size around 25% bigger on an inkjet than a laser, perhaps because the inkjet is less crisp.

    I have to admit I went a bit nuts with QR Codes. I made a Vcard: my vcard

    (and while I was at it, I created a new field for ham radio operators: X-CALLSIGN. Why not?). I even encoded some locations in QR Codes.

    Just to show you what qrencode can do, here’s a favourite piece of little prose:

    a_real_man

  • Adding a Bluetooth serial terminal to Raspberry Pi

    Hey! This article is really old. The advice given here will not work on a Raspberry Pi 3, and will need some care with recent versions of Raspbian.

    Sometimes you find a computer component that’s so cheap, that works so well, that you’re amazed you managed to live without it for so long. The JY-MCU Arduino Bluetooth Wireless Serial Port Module is that component for me right now.

    JY-MCU Arduino Bluetooth Wireless Serial Port Module from dx.com
    JY-MCU Arduino Bluetooth Wireless Serial Port Module from dx.com

    This little board is a cheap ($8.50!) Bluetooth serial port. It’s happy with the Raspberry Pi’s 3.3 V logic levels, and will communicate at standard rates between 1200 and 1,382,400 baud. It even comes with a nifty little cable which is just the right polarity for the Raspberry Pi’s GPIO pins. It’s really meant to do serial comms on an Arduino, but it’s not limited to that.

    What this board allows you to do is connect to your Raspberry Pi’s serial console via Bluetooth. That way, you can have your Raspberry Pi hidden away somewhere, and yet still log in as if you were talking to it directly through a serial cable. Combine this with a USB wireless adaptor (like the Belkin N150 that I use) and you’ve got a wireless device you can always connect to, even if your network goes down.

    In order to use this device with your Raspberry Pi, you’re going to have to do some reconfiguration. Exactly what reconfiguration you do depends on some additional hardware:

    1. If you have a USB-TTL Serial converter (like an FTDI Friend, FTDI Basic Breakout – 3.3V, or the one I use, the OSEPP FTDI), you can reconfigure the Bluetooth module to run at 115,200 baud, the default speed of the Raspberry Pi’s serial port.
    2. If you don’t have the serial converter, you’ll need to reconfigure the Raspberry Pi’s serial terminal to run at the JY-MCU Bluetooth adapter’s default 9600 baud.

    To reconfigure the Bluetooth module to run at 115,200 baud

    (I chose this option, as it allows me to use the Bluetooth module with Firmata on an Arduino, too.)

    The JY-MCU board comes with no instructions, but all the reconfiguration commands you’ll need are explained here: hc06_linvor_1.5_at_command_set [[hc06_linvor_1.5_at_command_set]] (cached copy; original has gone) While you’re setting the communications speed, you’ll probably also want to change the device name (so you can more easily recognize your own board, as the default is something like “Linvor”) and PIN (for that warm feeling of security that only a four digit code can provide). The device is configured using AT commands (or as we eldsters call them, Hayes commands) by plugging it directly into a USB-TTL Serial device attached to your computer. Here’s how you wire it:

    USB-TTL Serial    Bluetooth Serial
    ================= =================
    GND               GND
    VCC               VCC
    TXD               RXD
    RXD               TXD

    Note that TXD and RXD are crossed. The Bluetooth unit runs on a 3.6-6V supply, but 3.3V logic. To enter the AT commands, start a serial terminal (Hyperterm, minicom, screen …) at 9600 baud talking to the USB-Serial adapter, and copy and paste these commands in:

    AT+NAMEBluey
    AT+PIN4321
    AT+BAUD8

    You’ll have to disconnect the terminal and reconnect at 115,200 baud, as that last command just reset the Bluetooth device’s speed. You might want to use other settings than Bluey for the name and 4321 for the PIN, too.

    Update: check that your Raspberry Pi’s /boot/cmdline.txt contains:

    console=ttyAMA0,115200

    You will not get a login prompt otherwise.

    Now go to Using the Device.

    To reconfigure the Raspberry Pi’s serial terminal to run at 9600 baud

    Serial terminals traditionally ran at 9600 baud, and that seems a bit slow these days. But, if you don’t have a way of setting up the Bluetooth device differently, 9600 is what you’re stuck with. You’ll need to edit your Raspberry Pi’s /boot/cmdline.txt so that the part that previously read:

    console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

    to

    console=ttyAMA0,9600 kgdboc=ttyAMA0,9600

    Note that this file should only contain one line, so be careful you don’t add extra line breaks or your Raspberry Pi won’t boot. Save the file, reboot your Raspberry Pi, and go to the next section.

    Using the Device

    On your Raspberry Pi, connect the Bluetooth Wireless Serial Port Module as follows:

    Raspberry Pi      Bluetooth Serial
    ================= =================
    5V  (GPIO Pin  2) VCC
    GND (GPIO Pin  6) GND
    TXD (GPIO Pin  8) RXD
    RXD (GPIO Pin 10) TXD

    (Despite the minimum 3.6V rating, I’m happily running mine from the 3V3 power, GPIO Pin 1. YMMV.)

    When the board gets power, but isn’t paired, the LEDs on the Bluetooth module flash quickly. Now you need to pair the device with your computer (use 0000 as the PIN, or whatever you chose if you changed it), and it will appear as a serial port on your machine. On my Mac, that’s a device called /dev/tty.Bluey-DevB. The LEDs stop flashing when the port goes into use. Open up a serial terminal, set the device and speed correctly, and if all goes well, you should see:

    Debian GNU/Linux wheezy/sid raspberrypi ttyAMA0
    
    raspberrypi login:

    Success!

  • X10 home automation with Raspberry Pi: heyu

    I never quite get the hang of setting timers for lights. Either I forget daylight savings completely, or I set something so general that I find the lights coming on mid-afternoon when it’s still light. Minor annoyances require the over-application of technology, and fast!

    I scored an X10 ActiveHome Starter Kit for cheap(ish) on eBay. X10 is a pretty old technology (1970s! Scottish!) and has some severe limitations (slow! prone to interference! unencrypted!) but has a large user base, and did I mention it’s pretty cheap?

    The key component of a computer controlled X10 system is the CM11 computer interface. It takes serial commands from a computer, and pushes them out (slowly) as signals modulated over your house wiring. Various plug-in modules pick up these signals, and if the device address in the command matches that of the module, the module turns on (or off, or dims).

    Since the version of the CM11 interface that I have is serial, I’ll need a USB→Serial converter. All I had lying around was a very old Prolific PL2303 interface, which works fine with Raspbian, but I’d prefer an FTDI one for more reliability. Long-term stability of USB Serial on the Raspberry Pi is currently questionable; there’s some good discussion on kernel parameters that might help.

    To send X10 commands from a Raspberry Pi (or indeed, any Linux computer) you need heyu. You have to build it from source, but the instructions are clear, and it takes about 10 minutes to build on a 256 MB Raspberry Pi. The install script asks you where your serial port is, and for my device it is /dev/ttyUSB0.

    (Update: I re-imaged the Raspberry Pi that runs these tasks today and rebuilt heyu without success. Don’t assume you can do a ./configure; make; sudo make install here. You have to run heyu’s own ./Configure.sh first before make. It does some non-obvious magic. Read the README and you’ll be fine, unlike me …)

    Most of the lights in our house are fluorescent, which is a problem for the standard X10 lamp modules. CFLs are not dimmable, and the standard lamp module doesn’t work with them. The lamp modules don’t work very well with low-voltage halogen lamps, either; extreme buzzing ensues, with a faint brownish light oozing out from the bulb and a vague burning smell. Best avoided, and better to use an appliance module, which is a simple mechanical relay.

    The only controller that came with the kit that would work with my lights was the X10 transceiver, which also includes an appliance switch. I gave this device an address of H9 (house code H, unit code 9), and plugged in a lamp. To turn it on, I issued this command:

    heyu on H9

    After about 8-10 a couple of seconds and a loud CLUNK from the controller’s relay, the light came on (if it’s taking longer, read this comment). To turn it off, I told it:

    heyu off H9

    Whoa! Raw power! I can now turn AC devices on and off from my Raspberry Pi (Martin Creed, watch out!). I guess I could set up cron jobs to control the lights, but cron doesn’t know about solar time (Sunwait and SunCron do, if you want to futz with them). I’ve got MisterHouse running on the Raspberry Pi for more clever control, but more on setting that up later.

    Incidentally, if you’re in Europe, Marmitek sell a variety of 220 V 50 Hz X10 modules. Their website is much clearer than the angry-fruit-salad that is x10.com. It looks like X10 have updated their starter kit to include the newer CM15 USB interface which will likely not work with heyu.

  • The shell of dead media lives on

    You have to be of a certain age to recognize this:

    … not just as an artist’s travel palette, but as a repurposed case for a 9-track tape spool. While tape drives were iconic for mainframe computers (so much so, there’s a Unicode glyph for them: ✇), the last drives and tapes came off the line a decade ago. They’re not truly dead until everybody forgets what these cases were originally for.

  • Mesmerizing, isn’t it?

    This is my profile on Microsoft’s new social thing, socl:

    Every link produces no content, and the name looks suspiciously like “sod” if over-kerned. Well, at least it’ll make Google+ feel busy.

    I can’t seem to do anything; creating a post gives me this:

  • Sorry, folks …

    Sorry, folks at 10 PRINT, I think the Amstrad CPC’s version simply pwns the C64:

    10 PRINT CHR$(199+2*RND);: GOTO 10

  • Raspberry Pi as a USB audio capture device

    The Raspberry Pi’s hardware and software support has come a long way in the few months it has been in the wild. I first tried this application in the summer, and the results were dismal. Now, thanks much improved USB driver support under Raspbian, I’m pleased to say it works flawlessly.

    Earlier this year, I bought a turntable (ack!) for transferring vinyl to mp3. I have a TC-772 USB phono preamp, which spits out a 48 kHz stereo audio stream. If you plug the USB output of the preamp into a Rapberry Pi (running Raspbian Wheezy with all the updates), it’s instantly recognized as an audio device:

    $ lsusb
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
    Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
    Bus 001 Device 004: ID 08bb:2902 Texas Instruments Japan PCM2902 Audio Codec

    If you install the ALSA recording utilities (sudo apt-get install alsa-utils pulseaudio – this should pull in a whole bunch of necessary packages), you can record directly from this device with the following command:

    arecord -D 'pulse' -V stereo -c 2 -f dat -d 900 out.wav

    which records from the ‘pulse’ audio device, displaying a stereo text VU meter (handy for setting levels), writing to a two channel 16-bit 48 kHz file called ‘out.wav’ for a maximum of 900 seconds (15 minutes). arecord has a baffling number of recording source options; arecord -L will show them. ‘pulse’ was the first one I tried.

    So how does it sound? Here’s a 30 second excerpt from the only single I owned for years, The Music Tapes‘ “The Television Tells Us/Freeing Song by Reindeer”: Freeing Song by Reindeer – excerpt [mp3]. I’ve saved an even smaller snippet as lossless FLAC so you can see that the waveform’s pretty clean: FreeingSongbyReindeer-tiny_excerpt [flac].

    Sounds pretty good. Not quite as good as having Julian play it in your house, I’ll allow, but not bad for a first try with a $35 computer.

  • Ever heard the term “Appropriate Use of Technology”?

    Well, this is not that: For He’s a Jolly Good Fellow [mp3], as played on this:

    — an Arduino driving a stepper motor driving a Sankyo musical box. And yes, heat-shrink tubing ‘reinforced’ with dental floss doesn’t make a very robust flexible coupling.

  • Potentially handy Raspberry Pi power source

    This looks handy; it’s the Globe Electric 2-Outlet Tap with Surge Protection and 2 USB Chargers (#46082). The USB outlets are rated at 1A. It was $12 at Loblaws. I’ll let you know how it works out for powering the Raspberry Pi.

    Update: Yes! It works!

  • python + Arduino + Tk: Toggling an LED

    Whoa! This is so old I don’t even know where to start!

    • It’s using Python 2, so if it works at all it probably won’t for much longer, and Tkinter is something completely different under Python 3
      (grrreat planning there, Python guys …)
    • pyfirmata is likely ancient history too.

    Phil sent me a note last week asking how to turn an LED on or off using Python talking through Firmata to an Arduino. This was harder than it looked.

    It turns out the hard part is getting the value from the Tkinter Checkbutton itself. It seems that some widgets don’t return values directly, so you must read the widget’s value with a get() method. This appears to work:

    #!/usr/bin/python
    # turn an LED on/off with a Tk Checkbutton - scruss 2012/11/13
    # Connection:
    # - small LED connected from D3, through a resistor, to GND
    
    import pyfirmata
    from Tkinter import *
    
    # Create a new board, specifying serial port
    # board = pyfirmata.Arduino('/dev/ttyACM0') # Raspberry Pi
    board = pyfirmata.Arduino('/dev/tty.usbmodem411') # Mac
    
    root = Tk()
    var = BooleanVar()
    
    # set up pins
    pin3 = board.get_pin('d:3:o') # D3 On/Off Output (LED)
    
    def set_led():  # set LED on/off
        ledval = var.get()
        print "Toggled", ledval
        pin3.write(ledval)
    
    # now set up GUI
    b = Checkbutton(root, text = "LED", command = set_led,
                    variable = var)
    b.pack(anchor = CENTER)
    
    root.mainloop()
    

    This is explained quite well here: Tkinter Checkbutton doesn’t change my variable – Stack Overflow. I also learnt a couple of things about my previous programs:

    • You don’t really need to set up an Iterator unless you’re reading analogue inputs
    • My “clever” cleanup-on-exit code actually made the script hang on Mac OS.
  • Power Cost Monitor signals — for reals!

    After doing almost nothing with the Arduino and the elusive Power Cost Monitor signal, I’m finally getting something from it. Matt Colyer’s Power Monitor sketch does all the heavy lifting, for he managed to reverse engineer the protocol. His solution is a rather complex one, involving ethernet shields and Ruby. All I wanted was a simple serial logger, so I cut down Matt’s code, and modified the network output to simple print statements:

    == Waiting (38464857ms, 1676 bytes) ==
    == Sending (38467858ms, 1668 bytes) ==
    sample[data]=0000000a
    sample[data]=0000015a
    == Waiting (38467863ms, 1676 bytes) ==
    == Received (38592156ms, 1670 bytes) ==
    == Waiting (38592157ms, 1676 bytes) ==
    == Sending (38595158ms, 1668 bytes) ==
    sample[data]=00000000
    == Waiting (38595159ms, 1676 bytes) ==
    == Received (38624334ms, 1670 bytes) ==
    == Waiting (38624335ms, 1676 bytes) ==
    == Sending (38627336ms, 1668 bytes) ==
    sample[data]=ffffe746
    == Waiting (38627337ms, 1676 bytes) ==
    == Received (38688007ms, 1670 bytes) ==
    == Waiting (38688009ms, 1676 bytes) ==
    == Received (38688045ms, 1670 bytes) ==
    == Waiting (38688046ms, 1676 bytes) ==
    == Sending (38691047ms, 1668 bytes) ==
    sample[data]=00001748
    sample[data]=00000008
    == Waiting (38691052ms, 1676 bytes) ==
    == Received (38720026ms, 1670 bytes) ==
    == Waiting (38720027ms, 1676 bytes) ==
    == Sending (38723028ms, 1668 bytes) ==
    sample[data]=00000000
    == Waiting (38723030ms, 1676 bytes) ==
    == Received (38783686ms, 1670 bytes) ==
    == Waiting (38783687ms, 1676 bytes) ==
    == Sending (38786688ms, 1668 bytes) ==
    sample[data]=00000011
    == Waiting (38786689ms, 1676 bytes) ==
    == Received (38815636ms, 1670 bytes) ==
    == Waiting (38815637ms, 1676 bytes) ==
    == Sending (38818638ms, 1668 bytes) ==
    sample[data]=fffff322
    == Waiting (38818639ms, 1676 bytes) ==
    == Received (38847547ms, 1670 bytes) ==
    == Waiting (38847548ms, 1676 bytes) ==
    == Sending (38850549ms, 1668 bytes) ==
    sample[data]=00000001
    == Waiting (38850550ms, 1676 bytes) ==
    == Received (38879444ms, 1670 bytes) ==
    == Waiting (38879446ms, 1676 bytes) ==
    == Sending (38882445ms, 1668 bytes) ==
    sample[data]=0000374f
    == Waiting (38882446ms, 1676 bytes) ==
    == Received (38911210ms, 1670 bytes) ==
    == Waiting (38911211ms, 1676 bytes) ==
    == Sending (38914212ms, 1668 bytes) ==
    sample[data]=00000043
    == Waiting (38914213ms, 1676 bytes) ==
    == Received (39006981ms, 1670 bytes) ==
    == Waiting (39006982ms, 1676 bytes) ==
    == Sending (39009982ms, 1668 bytes) ==
    sample[data]=00000000
    == Waiting (39009983ms, 1676 bytes) ==
    == Received (39038895ms, 1670 bytes) ==
    == Waiting (39038896ms, 1676 bytes) ==
    == Sending (39041897ms, 1668 bytes) ==
    sample[data]=00000001
    == Waiting (39041898ms, 1676 bytes) ==
    == Received (39102999ms, 1670 bytes) ==
    == Waiting (39103000ms, 1676 bytes) ==
    == Sending (39106001ms, 1668 bytes) ==
    sample[data]=00000000
    == Waiting (39106002ms, 1676 bytes) ==
    == Received (39134880ms, 1670 bytes) ==
    == Waiting (39134881ms, 1676 bytes) ==
    == Sending (39137882ms, 1668 bytes) ==
    sample[data]=00000001
    == Waiting (39137883ms, 1676 bytes) ==

    Now it’s just a small matter of programming to work out what Matt’s Ruby code does. Ruby always looks to me like two programmers started coding at different ends of the same line, and collided in the middle. I’m hoping there’s enough processing power in the Arduino to do the conversion in the chip, and output useful log data as a serial stream.

    More later …

     

     

  • The MagPi

    Yay! My article on Arduino and Raspberry Pi is this month’s cover of The MagPi! Read it on Issuu, or download the PDF.

    Thanks to Ash and the rest of the team at the magazine.

  • Servo Control from pyfirmata + arduino

    Hey! This article is really old! So old, in fact, that I clearly thought that saying (ahem) “w00t w00t” was a good idea. Information here may be misleading and possibly wrong. You probably want to be using a newer client library and you definitely want to use an Arduino IDE ≥ 1.6 and not the ancient one that comes with Raspbian.

    pyFirmata‘s documentation is, to be charitable, sparse. After writing Raspberry Pi, Python & Arduino *and* a GUI (which should be making an appearance in The MagPi soon, w00t w00t yeet!), I looked at pyFirmata again to see what it could do. That pretty much meant digging through the source.

    Firmata can drive hobby servos, and if you’re not driving too many, you can run them straight from the Arduino with no additional power. I used a standard cheapo-but-decent Futaba S3003, which gives you about 180° of motion. The particular one I tried started to make little growly noises past 175°, so in the example below, that’s hardcoded as the limit.

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # move a servo from a Tk slider - scruss 2012-10-28
    
    import pyfirmata
    from Tkinter import *
    
    # don't forget to change the serial port to suit
    board = pyfirmata.Arduino('/dev/tty.usbmodem26271')
    
    # start an iterator thread so
    # serial buffer doesn't overflow
    iter8 = pyfirmata.util.Iterator(board)
    iter8.start()
    
    # set up pin D9 as Servo Output
    pin9 = board.get_pin('d:9:s')
    
    def move_servo(a):
        pin9.write(a)
    
    # set up GUI
    root = Tk()
    
    # draw a nice big slider for servo position
    scale = Scale(root,
        command = move_servo,
        to = 175,
        orient = HORIZONTAL,
        length = 400,
        label = 'Angle')
    scale.pack(anchor = CENTER)
    
    # run Tk event loop
    root.mainloop()
    

    The code above makes a slider (oh, okay, a Tkinter Scale widget) that moves the servo connected to Arduino pin D9 through its whole range. To set the servo position, you just need to write the angle value to the pin.

    I haven’t tried this with the Raspberry Pi yet. It wouldn’t surprise me if it needed external power to drive the Arduino and the servo. This might be a good excuse to use my Omega-328U board — it’s Arduino code compatible, runs from an external power supply, and has Signal-Voltage-Ground (SVG) connectors that the servo cable would just plug straight into.

  • a paucity of pi posts

    I would have been posting more Raspberry Pi posts, but my latest Made-in-UK 512MB board seems to have a raft of problems. Left to its own devices, it will happily corrupt any SD card I put in it. This is some fairly typical dmesg output:

    [36218.109865] mmc0: final write to SD card still running
    [36228.126345] mmc0: Timeout waiting for hardware interrupt - cmd12.
    [36228.127534] mmcblk0: error -110 sending stop command, original cmd response 0x900, card status 0x900
    [36248.152121] mmc0: final write to SD card still running
    [36258.163655] mmc0: Timeout waiting for hardware interrupt - cmd12.
    [36258.164865] mmcblk0: error -110 sending stop command, original cmd response 0x900, card status 0x900
    [36269.084446] mmc0: final write to SD card still running
    [36279.101766] mmc0: Timeout waiting for hardware interrupt - cmd12.
    [36279.102953] mmcblk0: error -110 sending stop command, original cmd response 0x900, card status 0x900
    [36309.899006] mmc0: Timeout waiting for hardware interrupt - cmd25.
    [36309.899047] mmc0: resetting ongoing cmd 25DMA before 4096/4096 [84]/[96] complete
    [36309.902774] mmcblk0: error -110 transferring data, sector 1721928, nr 848, cmd response 0x900, card status 0xc00
    [36309.902964] mmc0: DMA IRQ 6 ignored - results were reset
    [36309.903200] end_request: I/O error, dev mmcblk0, sector 1722649
    [36309.903227] end_request: I/O error, dev mmcblk0, sector 1722656
    ...
    [36309.903462] end_request: I/O error, dev mmcblk0, sector 1722768
    [36309.903823] Aborting journal on device mmcblk0p2-8.
    [36310.460263] journal commit I/O error
    [36310.653420] EXT4-fs error (device mmcblk0p2): ext4_journal_start_sb:327: Detected aborted journal
    [36310.667118] EXT4-fs (mmcblk0p2): Remounting filesystem read-only

    I’m not alone in having this problem; it’s reported by other people at Raspberry Pi • PI freezes and Filesystem corruption on the SD card – Stack Exchange. I don’t see any solutions or responses from the Foundation yet.

    Update: for no reason I can explain, setting over_voltage=2 in the /boot/config.txt file seems to make this problem go away. For me, at least.

  • LaunchPad MSP430 pomodoro timer using Energia

    I know a lot of people who bought the Texas Instruments MSP430 LaunchPad development kit but never really got into it. I’m one of them; the $4.30 purchase price was compelling, but the requirement to install a huge proprietary IDE (with its own embedded C dialect) was just too much.

    For this reason, Energia is great. It’s a fork of the Wiring/Arduino development environment for the MSP430. Looks just like Arduino, but quite red:

    The basics of the language are the same, although the pin names and functions are different from the Arduino. The basic board also has a red and a green LED, a user button, and the obligatory reset button.

    Just to try out Energia, I wanted a useful project that only used the onboard hardware. I came up with a version of a pomodoro timer, similar to the one used in The Pomodoro Technique® time management method. The one I made has the following features:

    • 25 minute “green light” work period
    • 5 minute “red light” rest period
    • At the end of the rest period, the green and red lights flash. You can choose to restart the timer (with the reset button), or turn the lights off with the user button.
    • You can turn the timer off at any time with the user button, and restart it from zero with the reset button.

    For me, this electronic version has several advantages over the wind-up official timer:

    • it doesn’t tick or ring distractingly
    • it’s cheaper than the real thing
    • it always resets to the same time.

    It does have a couple of possible disadvantages, though:

    • it doesn’t give an indication of time left
    • it’s not very accurate, since it uses the MSP430’s internal oscillator. Mine seems to give an approximately 26 minute work period, with a rest time that’s proportionally longer.

    Here’s the code (tested on a MSP-EXP430G2 board, version 1.4):

    /*
    
     launchpomodoro - simple task/rest timer for TMS430/Energia
    
     On reset: Green LED on for 25 minutes
     After 25 minutes: Red LED
     After 30 minutes: Flashing Red/Green LED (until reset)
     On button press: all lights off.
    
     scruss - 2012-10-15
    
     */
    
    // 25 minutes
    #define ENDWORKTIME 1500000
    // 30 minutes
    #define ENDRESTTIME 1800000
    
    unsigned long start=0;
    int red=1; // for light flashing state at end of rest time
    int green=0;
    
    void setup() {
      pinMode(GREEN_LED, OUTPUT);
      pinMode(RED_LED, OUTPUT);
      pinMode(PUSH2, INPUT);
      digitalWrite(GREEN_LED, HIGH); // start work
      digitalWrite(RED_LED, LOW); // stop rest
      start=millis();
    }
    
    void loop () {
      if ((millis()-start)>ENDWORKTIME) {
        digitalWrite(GREEN_LED, LOW); // stop work
        digitalWrite(RED_LED, HIGH); // start rest
      }
    
      if ((millis()-start)>ENDRESTTIME) {
        flicker(); // warn that we've overrun
      }
    
      if (digitalRead(PUSH2) == LOW) { // push quiet/off switch
        off();
      }
    }
    
    void flicker() { // toggle LEDs and wait a bit
      red=1-red;
      green=1-green;
      digitalWrite(GREEN_LED, green);
      digitalWrite(RED_LED, red);
      delay(333);
    }
    
    void off() { // appear to be off
      digitalWrite(GREEN_LED, LOW); // lights off
      digitalWrite(RED_LED, LOW);
      while (1) { // loop until reset
        delay(50);
      }
    }
    

    (or if you’d rather have the archived sketch: launchpomodoro-121015a.zip.)

    It would be trivial to port this to Arduino, but you would need some external LEDs, resistors and a pushbutton.

  • optar: paper-based archiving

    I’ve spent most of the day messing around with Twibright Optar, a way of creating printed archives of binary data that can be scanned back in and restored.  It looks like it was written as a proof-of-concept, as the only way to change options is to modify the code and recompile. Eppur si muove.

    To compile the code on OS X, I found I had to change this line in the Makefile from:

    LDFLAGS=-lm

    to

    LDFLAGS=-lm  `libpng-config --L_opts`

    After trying to print some samples at the default resolution, I had no luck, so for reliability I halved the data density settings in the file optar.h:

    #define XCROSSES 33 /* Number of crosses horizontally */
    #define YCROSSES 43 /* Number of crosses vertically */

    It’s quite important that your image prints and scans with a whole number of printer dots to image pixels. This used to be quite easy to do, before the advent of PDF’s “Scale to fit” misfeature, and also printer drivers that do a tonne of work in the background to “improve” the image. Add the mismatch between laser printer resolutions (300, 600, 1200 dpi …) and inkjets (360, 720, 1440 dpi …), and you’ve got lots of ways that this can go wrong.

    Thankfully, there’s one common resolution that works across both types of printers. If you output the image at 120 dpi, that’s 5 laser printer dots at 600 dpi, or six inkjet dots at 720 dpi. And there was peace in the kingdom.

    Here’s a demo, based on this:

    So I took this track (which I used to have as a 7″, got at a jumble sale in the mid-70s) and converted it to a really low quality MPEG-2.5: MichelinJingle8kbit — that’s 175KB for just shy of three minutes of music (which, at this bitrate, sounds like it’s played through a layer of socks at the bottom of the Marianas Trench, but still).

    Passing it through optar (which I wish wouldn’t produce PGM files; its output is mono) and bundling the pages into a PDF, I get this: optar_mj.pdf (760KB). Scanning that printout at 600dpi and running the pages through unoptar, I got this: optar1_mj.mp3. It’s the same as the input file, except padded with zeros at the end.

    Sometimes, the scanning and conversion doesn’t do so well:

    • mjoptar300dpi.mp3 — this is what happens when you scan at too low a resolution.
    • mjx.mp3 — I have no idea what went wrong here, but: glitchtastic!
  • ATTiny programming board

    It’s amazing what you can do when you raid your parts bin …

    Featuring fully configurable M-F jumpers so I can program (pretty much) any Atmel ATTiny microcontroller up to 28 pins. Might be able to do some ATMegas too.