Saturday 26 January 2013

Raspberry Whispers

After success with the "human readable" QRSS modes of FSK Morse and (my version of) "Hellschreiber", as seen here received by Steen Erik, la5goa up in arctic Norway,


I decided to add WSPR to my RPi Beacon's repertoire, to make it truly "multi-mode". I don't mean porting the WSPR code onto RPi (though doubtless this can be done - a Linux version is available). I mean cooking up my own WSPR signals in Python and transmitting them from inside the beacon previously described.

For anybody that doesn't know, WSPR is a true digital radio mode (in the sense that it is intended to be read by machines, rather than humans), developed by Joe Taylor, k1jt. I have enjoyed sending WSPR signals from my PIC-based multi-mode beacon - so I know the steps required. However, things have changed since the first time I trod the lonely path - so here's a description of how to do it today.

When I first played with generating WSPR signals, back in the summer of 2010, the secret was to use the command line version of k1jt's "WSPR" program. However, typing "WSPR" into a DOS command line these days just brings up the standard WSPR GUI. Fortunately, there's an alternative path...

The program "WSPRcode.exe" exists specifically to generate the WSPR message, which encodes the transmitting station's call sign, locator and power (in dBm). The locator is four symbols in the Maidenhead System which - for my home - is "IO83". The power is given in dBm (i.e. dB relative to 1 mW) and - as I'm producing around 200mW, I entered "23", making my message "m0xpd IO83 23".

Simply appending this string as an argument for the WSPRcode executable does the job...


The channel symbols describe which of the four frequencies which constitute the WSPR signal must be transmitted in each sequential interval. The WSPR "standard" tells us these frequencies must 1.4648Hz apart and that each interval lasts a little over 682 milliseconds. Also, a WSPR message must start 1 second into an even minute (that's to say the 0th, 2nd, 4th ... minute of the hour) in order to be received and understood.

It is clear that not only good timing - but accurate synchronisation to ABSOLUTE time is required.

Most WSPR transmissions come from computers, which keep good time (and may even be synchronised to time servers on the internet). Simple little beacons (like my PIC-based system) need to be started at precisely the top of the hour and keep good time thereafter. My PIC beacon hacked the timing framework developed by Gene Marcus, w3pm, who even included features required to synchronise to a GPS-derived timecode (though I haven't used that option recently).

In the case of the new Raspberry Pi beacon, timing remains the critical aspect of WSPR operation. Fortunately, unlike most PIC or AVR/Arduino alternatives, the RPi usually lives hooked up to the 'net, so absolute time is readily accessible. 

Here's the simple additional lines needed in my Python beacon code to transmit WSPR...

 'WSPR_Message' is the vector of channel symbols (obtained from WSPRcode.exe, above). WSPR_freq is the desired transmission frequency and WSPR_df is the frequency spacing between the channels ( = 1.4648 Hz). My code has a main timing loop which waits for the start of each minute and calls either FSK-CW, Hellschreiber or (now) WSPR routines at the appropriate point in a 10-minute cycle, by setting the "Proceed" variable to non-zero value. Proceed = 1 initiates a WSPR transmission.

I tried the Raspberry-flavoured WSPR signal on the 30m band and was immediately spotted by the University of Twente's 'Experimentele TelecommunicatieGroep Drienerlo', pi4tht and by Jorgen, oz7it.

Here are the reports of these spots from the WSPRnet reporting system...

WSPRnet also has a map report...


Here's a snapshot of the map taken as I write, showing the last 24 hours of spots (the thickness of the line between me and a receiving station indicates the number of times that station reported receiving my signal - so it's a measure of the quality of the link to that receiver). The map includes the Raspberry Pi's best "dx" (distance) to date - the 2552 kilometers to Alexander, ua3arc's receiver in Moscow.


Please let me know if you detect a whiff of raspberry on 30 or 40 metres over the next few days

...-.- de m0xpd

Sunday 20 January 2013

Multi-mode Beacon on the RPi

Inspired by some comments from Jim on Bill Meara's Soldersmoke Blog, I dusted off the m0xpd PayPal account (again!!!) and splashed out on one of the AD9850 DDS Modules from eBay...


Of course, you also need some kind of controller to make any use of these little synth modules. Fortunately, inspired by their beer-budget price, the modules are generating quite a buzz at the moment, so there's a lot of supporting software out there.

Andy Talbot, g4jnt, has written about the eBay modules in the current number of RadCom (but the dear old RSGB hasn't got around to updating their website at the time of blogging, so the link points to the previous edition - funny how the paper copy can be more up -to-date than electronic news!).

You can find Andy's PIC-based controller on-line - start with his description here .

Rather than follow the rest of the flock with a PIC controller (having already played with a PIC controller for DDS devices), I thought I'd like to use my new Raspberry Pi, so I had a further sniff about the 'net and found Ron, nr8o's blog, where he presents an Arduino sketch for setting up the AD9850.

I hacked that Arduino sketch into a piece of Python code for the Pi, which might be useful for others... 



Having got the synth to run, I wanted something to do with it - so I built up a "beacon" transmitter...


You can see (from the left) my GPIO breakout (here in the "High Rollers' edition"), then a quad bi-directional level converter module I made to couple the 3V3 signals from the RPi into the 5V world. Next there's the eBay module.

Its signal goes to a little QRP PA I knocked together (drawing on the PA stage in my "Funster Plus" rig) and a low-pass filter for 40m. Currently, I'm measuring 5.8V RMS at the output of the filter which (if we were to allow ourselves to be comforted by the delusion that the load thereafter is 50 Ohms) implies that I'm throwing a rather healthy 600mW at my half-g5rv. I'll throttle back to more sociable power levels when I get a chance.

Here's the amplifier...


and here's the filter...

See how my obsession with Plugin Modules is getting worse!

With the work I'd already done on sending Morse Code from the RPi, it was easy to get the system to send my call (this time at QRSS speeds, with a 3 second dit length).

Here's the first spot (in the red box) of my transmissions at pa9qv's "Double Dutch" grabber...


With all the processing resource of the RPi, it was also easy to transmit Hellschreiber messages making this a multi-mode beacon (in the spirit of my original).

Here's my multi-mode signal arriving in the Netherlands...


I've added the annotation in red to help you see it! I only transmitted the rather flamboyant "Raspberry Pi" element of the message for fun. After the buzz subsides, I'll go back to sending just my call!

I guess the next step is to get the RPi beacon to send WSPR as well - but first, I must get onto 30m - there are more grabbers on that band - so more chance of seeing my Raspberry Pi proclaim itself to a waiting world!.

 ...-.- de m0xpd

Update :-

The beacon is now even more "multi-mode" than before ... in addition to FSK-Morse and "Hellschreiber", it now also transmits the digital "WSPR" mode.

Friday 18 January 2013

Rotary Encoders on RPi

I've been playing with an incremental rotary encoder on the Raspberry Pi - for no better reason than the mountaineers' lame excuse "because it's there"...


The incremental rotary encoder produces two quadrature square waves (as you can learn by reading any of a number of descriptions including this one). By detecting the relative phase of the square waves, you can figure the direction of rotation and (if you are really keen to encode angular velocity accurately) the speed of rotation too.

I settled for a clumsy attempt to decode direction alone, using this circuit...


Of course, you need some code too - I wrote the following simple demonstration in Python. It detects positive-going transitions on "PinA" and looks at the state of PinB during these transition events to figure the direction in which the encoder has been moved.



After the fun-and-games with the MIDI controller, I'm really excited about object-oriented software for the RPi, so here's an elaboration which includes a class for Rotary Encoders, connected to any two GPIO pins on the RPi. There's also facility to read a push-button (which some encoders - including mine - feature).


Here's a screen shot showing me running the second program ...


The code works - but only just...

It is important to sample a rotary encoder at a sufficiently high sample rate to avoid aliasing which - in this case - results in missed "moves" or even moves of incorrect direction.

I cannot get the RPi to sample fast enough to guarantee that every movement is perfectly observed, whether in the "while" loop seen in the programs above, or in a tkinter ".after()" command with a delay argument of 1 millisecond. What's worse, the little graph of processor utilisation at the bottom right of the RPi desktop (like the PC's "Task Manager" or the Mac's "Activity Monitor") reveals that the processor is working hard to sample the encoder at this rate (as you can just see in the screenshot above). I don't know enough about RPi to know if an interrupt-driven approach, such as would be easy and obvious on a PIC, is possible or desirable.

Having said all that, the code above works well enough to let me add a "knob" to my simple RPi MIDI controller, making it much more user-friendly than the original mouse drag-able sliders.

Next, I hope to use the rotary encoder to control the frequency of the DDS generator module from eBay that's just arrived on my doormat - watch this space!

...-.- de m0xpd

Monday 14 January 2013

RPi GPIO Breakout for High Rollers

Having described the initial low rent version, I'm pleased to announce the arrival of an upmarket edition of my simple connector...


Notice how I've dodged the possibility of inadvertently connecting something unhealthy to the proscribed pins by the simple expedient of pulling out the corresponding pins from my device. I couldn't now "connect" if I wanted to!

The Cheapskate's version might not look so classy, but it wins hands down - drilling fifty two holes is a chore!

 ...-.- de m0xpd

Friday 11 January 2013

MIDI Controller on the RPi

Here's the story of my attempts to squeeze MIDI out of my new RPi. The How To's and Gotcha's concerning configuration, the hardware interface details and the full code examples make it something of a tutorial, which will allow others to build their own Raspberry-flavoured MIDI controller (should they be foolish enough to try)…


It started with my newly-MIDIfied Tube Screamer, which was all ready waiting for a controller. Of course I could continue to generate control signals in MIDI-OX, but I wanted to make something a little more specific to the Tube Screamer. Sat there on the bench was my new RPi waiting for a new application - so why not kill two birds with one stone? 

Unfortunately, the RPi can't generate MIDI straight out of the box, for a few good reasons;
  • the UART is doing something else by default - it's configured to serve up Linux Kernel messages
  • the UART doesn't offer the correct baud rate for MIDI serial comms
  • MIDI needs a hardware interface layer to implement the current loop
Fortunately, all these problem can be overcome, more-or-less simply…

In what follows, I'm referring to the standard, "Mini UART" accessible on the GPIO pins. There are dark whispers about a second, more flexible UART buried within the Broadcom device, but that's not for newbies like us. Also, there is the possibility of plugging in a USB - MIDI device to one of the USB sockets but that's not in the hack/knack spirit, so we're staying with the simple UART…

First job is to kill off the messages squirting out of the serial port by default. You need to edit the cmdline.txt file to remove (that's to say delete) the parameter:

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

Easy.

Next, you'll also want to disable the serial login ("getty") in /etc/inittab, by commenting out the line similar to this one:

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

just by prefixing it with a hash.

After a reboot, you shouldn't have any more unwanted stuff squirting out of your Mini-UART Tx pin. There's any number of detailed tutorials explaining how to achieve the steps above, including this one .

Next, you need some software to allow you to interact with the UART - I was intending to program in Python, so I installed the pySerial module, which is available for download here as a tar.

Once you have pyserial installed, you can try to use the UART to send MIDI data - only you'll hit a problem…

The Mini-UART only supports a few baud rates and the MIDI rate of 31250 is not one of the available set! If you set the baud rate to 31250, it will send serial data happily - but at a higher baud rate (of 38400 - the nearest available "standard" value).

Fortunately, this is a mountain that has been climbed by others before us, so there's a trick that we can use…

We can fool the UART into sending serial data at the correct speed by changing its master clock. If we saw our intended 31250 baud data actually being output at 38400, that is an error ratio of 38400/31250 - it is sending 23% fast. So , if we reduce the master clock speed by the same ratio, everything should be fine. 

There's opportunity to edit the config.txt file by adding a line of form…

init_uart_clock = 3000000

This line is shown above in the default clock rate of 3 MHz - we can change it (by taking 3MHz * 31250/38400 = 2441406) to:

init_uart_clock = 2441406

I did it and - guess what - it did ABSOLUTELY NOTHING! The serial data was still pumping out at 38400.

It turns out that you also need to add another parameter to cmdline.txt, as taught by Dom in this important post. Dom, who's a moderator at RaspberryPi.org and obviously knows what he's doing, suggests

"Can you try adding :

bcm2708.uart_clock=3000000

to cmdline.txt"

I tried and - guess what - is still did ABSOLUTELY NOTHING! The serial data was STILL pumping out resolutely at 38400 baud.

I thought about it (for quite a long time, involving caffeine, alcohol etc) and eventually started to wonder if there was a clue lurking in the filename 'cmdline.txt' …

I wondered if the addition had to be part of ONE LINE, rather than just part of a file. Sure enough, it does - adding Dom's suggestion to the ONE LINE in cmdline.txt suddenly made everything work as intended - serial was being produced at 31250 baud.

I can hear all the Linux experts laughing at me. But, in truth, the joke is on them - this is a piece of legacy code from the days when Linux/Unix expected me to be a bearded, cardigan-wearing geek, typing lines on a serial console. OK - so I have a beard. OK - so I often wear a cardigan. Linux still includes some dumb, laughable, pre-historic features.

Now we've got the UART running, we need some code to generate MIDI. I'll show you three species of increasing complexity.

First, a simple command-line Python program …


This program prompts the user for a MIDI channel and a controller number, identifying a unique controller. It will pass a sequence of values to this controller (values are like function arguments for the controller), until you break the program with a "ctrl-c" input from the keyboard.

Here's a screenshot of my console when running it…


In the case above, I chose the MIDI channel 9 and the controller 12, which corresponds to the "Level" control of my Tube Screamer (I arbitrarily assigned these values in writing the PIC code for the Tube Screamer).

The Control Change Message format contains three bytes; the first has 0xB as its high nibble and the channel number-1 as its low nibble. 0xBn is the code for "Control Change" on channel n+1 and the channel can run from 1 to 16, so channel-1 (=n)  will fit into the lower nibble's four bits. The second byte is the controller number, which can run from 1 to 127, encrypted as the seven least significant bits - in my case this is 12 (0x0C). The final byte is the value selected. In the screenshot above, I entered two values; 20 and 127.

 Here's the signal that appears on the UART Tx pin (GPIO 8) for the first Control Change Message (value = d'20' = 0x14)…


You can see that MIDI message bytes have a "0" start bit and a '1' stop bit. Also, the data is transmitted LSB first, so 0xB8 (=b'10111000') appears reversed as b'00011101 (=0x1D) etc. You can also see that the signal is switching between 0 and 3.3 volts - we need some hardware…

MIDI is a serial protocol, much like RS232. It uses a current loop to transmit and receive data and we need to ensure that we are capable of sending the correct currents, without damage to the RPi. Luckily, it's easy - the current required is just a few milliAmps, having only to light an LED in the receiving device's opto-isolator - we all know that the GPIO pins of a RPi are well able to turn LEDs on and off! This implies that we just need a current-limiting resistor and an appropriate connector (which, for MIDI, is a 180 degree 5-pin DIN socket). However, we'll be a little more "proper" than that and transpose to the correct working voltages using a level converter to switch from the RPi's native 3.3 volt signals to the more common 5V.

In my case a 74HCT14 was staring at me from the "junk box", so I pressed it into service, just as others have done before me


You can see the realisation of this interface in the photo at the top of this post.

At this point, having confirmed correct operation of the command-line interface program above, I decided to try to build a GUI interface, so I installed 'tkinter' (other fine GUI programming toolkits for Python are [no doubt] available) and started to learn something about GUI programming in Python. It is easy!

Here's a little program that generates a GUI to send data to a single MIDI control in response to movement of a slider…

 
The comments in the program listing should be sufficient for you to figure out how it works - here's how it looks when it runs (you open the program from the terminal and the GUI window appears)…


This is all very well - but most MIDI devices have more than one control (why, even a simple device like the MIDI Tube Screamer has four!). This ought to be reflected in the controller - so we need to think about how to work with number of controls. Hang on a minute - that sounds like an opportunity to get involved in some "Object-Oriented Programming", which is just the sort of thing Python ought to be good at. Let's see if we can make an object-oriented controller…

 The Tube Screamer has three controls which take input argument 0:127. These "continuous" controls (which are called "Drive", "Tone" and "Level") correspond to the three potentiometers on the original device (and on Dolly the clone). I assigned control numbers 13,14 and 12 to these controls in my PIC code.

There's another control - associated with the footswitch - which switches the effect On or Off (actually, its on all the time - it just bypasses the effect for "off"). This "two-state" or "Boolean" control really only needs a single bit input - but the MIDI Control Change Message doesn't support this, so we still take the wasteful approach of sending a whole byte. Some controllers interpret 127 as on and 0 as off (or vice-versa). Heaven knows what they do if they receive anything other than 127 or 0!

I took the approach of interpreting anything greater than 63 as "On" and anything less than 63 as "Off" (in other words I just look at the highest bit of the seven bit "value"). These "continuous" and "Boolean" controllers sound rather different - but they can both be handled as instances of one class of MIDI controller...

Here's the resulting GUI, offering remote access to all the MIDI Tube Screamer's controls...

With the object-oriented structure it is easy to set up more instances of controllers - and GUI widgets to operate them, whether sliders or buttons. In fact, the greatest problem is arranging the widgets in the window!

Let me know if you construct any MIDI applications using these building blocks.

Today I ordered a DDS module hosting an AD 9850 chip - perhaps the next RPi application will be at RF rather than AF !

 ...-.- de m0xpd

Sunday 6 January 2013

RPi GPIO Breakout for Cheapskates

I told you in an earlier post how much I admire Adafriut's Pi T-Cobbler breakout for the Raspberry Pi. I got as far as finding a UK reseller who listed them (for more GB Pounds than Adafruit charge in US Dollars) but they're on long-term back order - good thing, given the price! I resorted to my native parsimony...

I soon had a copper pattern laid out for a "straight" version which, although it didn't have the elegance of the Adafruit "T" configuration, was (like the T-Cobbler) only 0.3 inches between pin rows, thereby preserving as much breadboard area as possible.


Unfortunately, the XYL smashed my nice old laboratory thermometer over the holidays - serves me right for leaving it in the kitchen (she says). The thermometer is important in my new photo PCB process (to check the temperature of the photoresist developer), so PCB processing is on hold until the replacement arrives from eBay. Undaunted, I looked around for alternatives...

The junkbox yielded up a scrap of stripboard and I stock single and double row headers, so I quickly collected the key ingredients...


I cut the break in the copper tracks using a dental burr in my pre-historic horizontal milling machine, but I'm sure you could do the same job with a knife (it is between holes, you see - so you can't rely on the usual track cutter / drill). A little judicious soldering (after forceful re-arrangement of the pins in the single row headers to make best use of available length) and you have it...


Here's the new baby on the breadboard (still hosting the LED for my Morse Code GMail Notifier and test buttons for my RPi Keyer)...


All that's needed now is a ribbon cable and some IDC connectors - fortunately, the junkbox came up trumps again, serving up an old IDE disk cable...


However, that cable is bigger than the Pi and the breadboard together, so I broke the habit of a lifetime and dusted off the m0xpd PayPal account to order something more appropriate (£2.99, delivered in moments, from PC Supplies Limited - usual disclaimer)


Now the whole shebang looks a lot neater...


Next I've got to figure how to get the UART to send MIDI to my latest monstrous creation at 31250 baud - the widely touted solution of  suppressing the console UART (in cmdline.txt), getting rid of the getty (in inittab.tcxt) and modifying the UART clock speed with a line in config.txt of the form:

init_uart_clock=2441406 

isn't working for me. In fact, it isn't doing anything - serial is coming out resolutely at 38400 baud.

Any reader who sends a solution ( to shack.nasties "at gee male dot com") will get a prize. A very small prize of zero monetary value and no physical substance - but a prize none the less!

Update: The competition is closed - and I claimed the prize (I'm beginning to regret the "zero monetary value" status). I now have the RPi sending MIDI and controlling my MIDI Tube Screamer - I'll tell you all about it in a later post

 ...-.- de m0xpd

Saturday 5 January 2013

MIDIfied Tube Screamer

My Tube Screamer clone (Blogs passim) now sports a MIDI interface and can be controlled externally by MIDI "Control Change" messages...


I've played with sending MIDI from PICs a lot - that being the essence of my Virtual Organ Project; both in generating Note On / Note off messages from my MIDI bass pedals and various Control Change messages from organ drawbars, switches and other controls. But MIDI Tx is easy. It turns out that receiving MIDI is only slightly more tricky but interpreting and acting on MIDI messages is a whole lot tougher!

In the aerial photograph above, you can see the new MIDI elements at top right. There's another Breadboard Module with the obligatory 5-pin 180 degree DIN socket. There's also a little bit of electronics to squeeze MIDI into the PIC. MIDI is a current loop interface and needs an opto-isolator to terminate the Rx end correctly. I had some 4N25s in the junk box, but couldn't get these to work sweetly. Fortunately, I also had some CNW 136s and these worked very well.

Here's my MIDI Rx schematic...


After this simple circuit, the MIDI signal goes to the Rx pin on the 16F887 at the heart of my Digital TS. Of course, masochists can use bit-banging methods to receive the serial MIDI data (just as I continue to use Ross Bencina's code for sending MIDI in the Virtual Organ). However, for MIDI reception, you really need to use the PIC's UART (or EUSART, as Microchip insist on calling it).

There are any number of experts out there who will explain how to set up the UART for MIDI reception (standard 8-bit at 31250 baud). They will have you looking at the RCIF flag bit of the PIR1 register to see when data has arrived. You'll soon appreciate that you need to do this in an interrupt service routine, such that you can get on and do other things in the meantime (such as servicing the local control interface with its buttons and display). After some messing around, you'll get a MIDI stream into your controller - but what do you do with it?

The hard part isn't the reception of MIDI data (despite what you may think if you're struggling to get it going). The hard part is making your system react to it. Here's how I went about it...

Currently I have four "controls" in the digital tube screamer, matching exactly the user controls of the original guitar effect pedal. These controls are 'Drive', 'Tone', 'Level' and 'Bypass'. I want to be able to send values for each of these controls via MIDI from a control device.

MIDI has a feature exactly matched to this requirement (no surprise, since this is exactly what MIDI was conceived for), called "Control Change Messages". These messages identify a particular control on a particular MIDI channel (together constituting an "address" for that control) and pass it a numerical value (an integer between 0 and 127). It is the job of the receiving hardware to understand the message and to apply the value to the control (equivalent in this case to setting the position of one of the knobs on the Tube Screamer or operating its Bypass switch).

Here's my interrupt service routine which does the job...
You can modify this code to parse a MIDI stream for your own application - the only thing it doesn't (try to) do at the moment is handle "System Exclusive" messages. In my case, I'm happy to take the (very small) risk that one such message might mess with the controls of my Tube Screamer.

I tested my MIDIfied Tube Screamer by generating MIDI using the superb MIDI-OX software. I guess the next step is to make a little controller to replace the computer and MIDI-OX.

Wait a minute - wouldn't it have been easier to just put knobs on the Tube Screamer? Now there's a thought...

 ...-.- de m0xpd