Adding a Bluetooth serial terminal to Raspberry Pi

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. 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. 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.

Bad Kids Jokes

Lost Tractor

what did the farmer say when he lost his tractor?

where’s my tractor?

Old Man

why is it when a old man with one kid people thinks ”stranger”, but when its a old man with 20 kids people think ”school trip” . im on to you old people

Mountain Climbing

Q) why did’nt the man clime up the mountain

A) because there wasn’t a mountain

— from Bad Kids Jokes (via)

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.

the happiest sound

Click image for sound [mp3].

That’s the rapid clatter of chopping up Kothu Roti at Amma at the end of our street. You know that tasty spicy food is imminent when you hear that sound. I’m really pleased that Amma’s back under the original management. The other proprietors just didn’t care as much about their food.

python + Arduino + Tk: Toggling an LED

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.

Pwned by King James V

The Earl of Northumberland had dismissed as mere bragging the expressed intention of the Scottish government to try to do something about the Liddesdale robbers. Like Sim the Laird, he believed the Armstrongs were far too powerful for King James. But he was wrong. The young king had undertaken to “proceed to the sharpe and rygorouse pwnyssching of all transgressioune apone the bordouris”, and he now went to work, beginning with a gentle approach.

—  from The Steel Bonnets, by George MacDonald Fraser, chapter 27.

Yes, the Scots. We may have been the bunk at spelling, but we’ve been pwning since 1529.

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 …

 

 

pretty-printing Arduino sketches

I don’t often need it, but the code printing facility in the Arduino IDE is very weak. It has some colour highlighting, but no page numbering, no line numbering, and no headers at all.

a2ps will sort you right out here. Years back, it was a simple text to PostScript filter, but now it has many wonderful filters for pretty-printing code. The Wiring/Arduino language is basically C++, and a2ps knows how to deal with that. So, to create a PostScript file with a nice version of the the most basic Blink sketch:

a2ps --pro=color -C -1 -M letter -g --pretty-print='C++' -o ~/Desktop/Blink.ps Blink.ino

If you’re somewhere that uses sensible paper sizes (in other words, not North America), you probably don’t want the -M letter option. a2ps is supposed to have a PDF print option (-P pdf), but it doesn’t work on my installation, so I just splat the output through ps2pdf. The results are linked below:

Not bad, eh?