Sunday, 21 December 2014

Arduino SDR IV

Time to try once again to squeeze a quart into a pint pot...


One of the failings of my Arduino SDR, with its limited (12-bit) input stage, is the tendency to be swamped by big guns. The resulting distortion is of the particularly ugly "digital" variety that takes no prisoners.

At present, I'm dealing with this by knocking my ATU way off tune whenever a strong station comes on - but this is hardly an elegant solution.

Sure - I could add a simple potentiometer on the RF input - but that would never be addressable by anything other than my hand - barely an improvement over the ATU approach. I thought about adding a digital potentiometer at the RF input - but a quick look at the data sheets reveals that this approach is a non-starter.

Accordingly, I decided to play with a digital potentiometer in the "IF" of my software-defined radio which (of course) is actually in the high audio frequency range.

I happened to have an AD5242 in the "junk box" - as used in the experiments with the Digital Tube Screamer. This is a two-channel device (I needed a two-channel device to scale both the In-phase and Quadrature components of my system). The particular AD5242 in my collection was the 1MOhm variant.

The device features an I2C digital interface  - which was a bit of a concern, as I'd never had much joy with I2C and the Arduino DUE.

Fortunately, Rob Tillaart's library seemed to compile fine for the DUE and worked pretty much first time (once I had figured which of the two available I2C interfaces on the DUE was being used, with the help of my Ripoff logic analyser). I soon had the DUE talking to the AD5242 and implementing various resistances, tracking d.c. voltages read from a potentiometer...


Having confirmed I could control resistor values at will from the DUE, I thought about building a twin-channel, variable gain amplifier. It uses another Analog Devices chip from the "junk box", this time a quad OpAmp, which will run on a 3v3 supply - the AD8608...


Now, the physical potentiometer generates a voltage which is read into the DUE and then generates a control code to set the GAIN of the amplifiers. This gain varies between 6.5 dB and -41.5 dB. The (partial) schematic below gives you an idea of what I'm up to...


So - now the variable gain amplifier is added into the SDR receiver's input path...


It is, as you can see, very much a temporary "lash-up" at this stage. But it works fine. I have the ability to take shelter when the big guns open up. I also have a little more gain available to increase overall sensitivity. Plus, I've retained the variable receive bandwidth control from before.

But what - you might ask - is the advantage over putting the potentiometer on the RF input, just as I mentioned at the top of this post? Well...

One day soon, I will be able to allow the DUE to take over control of the AD5242 - to give automatic level control.

For the moment, I'll satisfy myself with manual control and focus on those other distractions the next few days have to offer.

...-.- de m0xpd

Sunday, 14 December 2014

R(F)duino DUE

An idle moment this weekend gave me opportunity to upgrade the R(F)duino to include the Si5351...


You've seen the original R(F)duino with its brace of AD9850 DDS modules, doing fine service in the Parallel IF rig. That system, being first, now should be called R(F)duino "UNO" (not that we're being influenced here).

Readers will know that I'm keen on the little Si5351 device, which offers a number of advantages over the AD9850s. Having already used the Si5351 in my RF generator scheme in the Breadboard BITX, I was keen to make a custom system - thus was born the second R(F)duino - the "DUE"...


As you see, I took very much a "minimum effort" approach to development of the DUE, simply plagiarising my design for the greater part of the UNO and swapping out the left hand side (as seen in the orientation above). The board has stayed at its rather large size for two reasons - first to accommodate all the connectors and second to make an easy retro-fit into the Parallel IF rig!

The features of the R(F)duino DUE are highlighted in the following annotated picture...


The schematic is here...


The code is essentially the Si5351 code that already has been published (but with extensions to support the Parallel IF functions, band change and SSB / CW transmit, which are some of the extra features of my transceiver). I couldn't resist differentiating it with a childish change of the banner line, just for this photo, taken during testing...



Now I need another idle moment or two to swap out the old R(F)duino in the Parallel IF rig for this new, improved, DUE version. I've just looked at the Christmas double issue of the Radio Times - doesn't look like there will be any trouble finding idle moments!

...-.- de m0xpd

Thursday, 11 December 2014

Parallel IF

Now that the January 2015 number of RadCom has started hitting the newsstands (even though I'm still looking forward to Christmas), I guess the cat is out of the bag...


The journal contains my article "A parallel filter architecture for flexible IF processing" (page 78) which - in turn - prompts me to reveal the true identity of the rig which I have been struggling to conceal in these pages for the past year.

What I have been clumsily calling the "multi-band rig" or (worse still) the "multi-band, BITX-inspired development platform" is, in fact, the Parallel IF rig...


I explain in the RadCom article how and why two ordinary crystal filters with disjoint pass-bands can sit next to each other - in parallel - quite comfortably. If these filters have different bandwidths, the whole rig can change receiving bandwidth simply by using the appropriate IF frequency required to select one or other of the filters. NO SWITCHING of any kind is required - just a change of oscillator frequencies.

You can imagine how easy this change of oscillator frequencies is to achieve with the RF Generator scheme that Pete Juliano and I already have published in SPRAT 158 and described in many blog posts, as summarised on this page.

The Parallel IF rig pictured above has two such crystal filters, between two of the ordinary bidirectional amplifiers familiar to builders of the BITX...


You can see my embodiments of these filters in the following photo, in which you'll note the absence of switches, relays and the like...


The software of the Parallel IF rig is a super-set of the m0xpd "Dual DDS" code - it includes an additional menu option to switch between the two IF frequencies required to operate one or other of the IF filters.

It is presented (of course) simply as a choice between the two receiving bandwidths...


The scheme works - very well.

Two weeks ago I presented a method for directly visualising overall receiving response - from RF to audio (magnitude) frequency response. Now you understand why!

With the disclosure of my new Parallel IF architecture, it is now time to use the new measurement method in anger...

Here's the measured response of the Parallel IF rig in SSB mode (a result you've already seen)...


Here's what happens if you keep the tuning the same but "switch" to the alternative IF path, giving a tighter overall response, appropriate to CW...


Formally, this is what might usually be called CW(R) mode as it is in lower side band; CW is more usually received in USB - this is just a convenience associated with the technique I've used to send CW from my rig, as described in SPRAT 159. The method works just as well with CW in USB - but would not allow a direct comparison with LSB reception in 40m, as above.

RSGB members can learn more about the method from the article in their copy of RadCom - other readers will be hearing very much more about the method over the coming months.

I am honoured to be working with Pete Juliano, n6qw, on the development of a new rig - a project specifically to showcase this "Parallel IF" principle. We will be publishing construction details of this new rig in 2015, hopefully in QRP Quarterly (subject to confirmation).

I am further honoured to have been invited to speak at QRP ARCI's Four Days in May 2015 - "the biggest and best QRP event in the World" (at least it was, before they invited me along HI HI).


You will not be surprised to hear that my subject will be this new method of achieving variable receive bandwidth in simple superhet rigs at very low cost.

I'm excited about it!

...-.- de m0xpd

Sunday, 7 December 2014

Continual Interruptions

This is the story of doing the job properly: tracking the rotation of rotary encoders using an interrupt-based approach. The story leads to updated versions of the m0xpd VFO code for AD9850 and Si5351 systems.

I have explained how a desire for simplicity kept the early designs published on this blog based on a simple "polled" rotary encoder architecture. In truth, there was a little more to it than just a "desire for simplicity"...



The Kanga / m0xpd DDS shield has a user-configurable pin assignment for the DDS module pins. However, it is biased towards the use of pins D2:D5 - these are the easiest pin allocations to make, as you see in the photo above. This will use up the pins D2 and D3 on the Arduino UNO which are the only two which support hardware interrupts. Accordingly, the systems which used the DDS shield tended to occupy pins D2 and D3, making interrupts inaccessible.

Ever since the appearance of the Dual DDS scheme and, specifically, its embodiment in the R(F)duino, I have intentionally freed up pins 2 and 3 for the Rotary encoder in my own builds, with the intention of - one day - moving to an interrupt-driven interface.



That day has arrived.

Its arrival was ushered in by two additional factors. First was the appearance of the Si5351, which sits on the I2C interface and completely frees up all the digital pins originally squandered on the DDS module. Second - and most important - was inspiration from Tom Hall, ak2b's beautiful receiver, which I saw on Tom's You Tube video. Correspondence with Tom finally persuaded me I HAD to act...

The problem with the original "polling" interface is one of visibility - the encoder is largely invisible to the code.

It is as if the encoder is obscured behind a brick wall, glimpsed only for an instant within the course of each execution of the main program loop, through a gap in the wall...


The code executing in the continuous "loop" function passes this "gap" in the wall only once per cycle and has to look for a change in the encoder's state since the last time the device was polled. It is seen that there is a rather precarious dependence upon the time it takes for the other tasks which the code has to perform in the one pass around the loop (and, hence the sample rate) and the speed of rotation. This explains my recent preoccupation with capacitors on the encoder output!

The code associated with this polling approach is not elegant, dealing - as it must - with the consequences of the two possible changes in observed state...


By contrast, the interrupt approach allows a complete brick wall between loop( ) and the encoder, but establishes a second process - the Interrupt Service Routine ('ISR')- to count the pulses from the encoder.

The ISR has 20:20 vision of the encoder.



In my implementation, I've arranged for the Interrupt Service Routine to maintain a variable, "Turns", which counts the number of "clicks" from a start time until reset. Clockwise rotation adds to the count, whilst counter-clockwise subtracts...


In the new code, the main program loop (which, in the user-friendly world of the Arduino, is called "loop( )") has vision of the count variable, "Turns", AND can reset it back to zero.

The frequency adjustment routine, equivalent to the one above, now becomes...


Notice that if more than one "Turn" event occurs in one pass through the loop( ) it is is now handled correctly, rather than just counted as one (or missed altogether). Accordingly, the frequency adjustment (etc) is very much smoother.

The new interface to the rotary encoder depends upon an Arduino library, Rotary, which can be downloaded from Przemek, sq9nje's Github repository.

I have used the new interrupt handling approach to produce a revised version of the Dual DDS VFO code and the Si5351 VFO Code, both of which can be found here. Reports, please, from anybody who tries them (I've tested "personal" versions of these new interrupt-driven programs with great results in my own rigs, including the Breadboard BITX and the Multi-band rig).

The same methods can be used by readers who wish to modify any of the previous m0xpd systems (such as the Occam's projects or the Kanga VFO systems) but this will require re-allocation of pins 2 and 3 which presently are assigned to the DDS - a simple enough task.

...-.- de m0xpd

Saturday, 29 November 2014

Directly Observing Radio Reception

I've messed with instrumenting (or, at least, visualising) IF behaviour before but now I've decided to stop messing around with just one part of the receiver chain. I want to observe the WHOLE reception process process directly - from RF in to the antenna input of a radio all the way to AF out of the amplifier...


My scheme uses the (inevitable) Arduino and DDS combo to generate an RF sweep, which is attenuated and passed directly into the Radio under Test. The resulting output voltage to the speaker (or headphone) is sampled by an RMS to d.c. converter and read back to the Arduino, which reports both the RF frequency and the level of the generated AF signal to a program running on a host computer, such that a graph can automatically be produced...


I have implemented the Arduino / DDS combination using a MEGA and an early prototype m0xpd DDS shield I had lying around...


My initial tests today have been for lower side-band on 40m, so I arranged for the RF sweep to be DOWNWARD from a start frequency, FStart, for a span of 10 kHz in 50 Hz steps. The Radio under Test would be tuned to FStart, such that the resulting AF output should be an UPWARD sweep from 0 to 10 kHz (more explanation below...).

The code was a simple hack of my earlier sketch for the IF work.

For the sake of speed and convenience, I implemented the RMS to dc conversion (what we might also call "detection") operation using a Bruel and Kjaer Electronic Voltmeter (seen in the image at the head of this post), which conveniently has a d.c, output proportional to its meter reading. The d.c. output was fed straight into pin A0 of the Arduino.

My first tests were made on the "Breadboard BITX" radio...


A processing sketch running on the PC initiated the sweep on the Arduino and collected and graphed the response data, which is shown below...


This is the overall receiving response of the radio from RF to audio, measured and graphed automatically with an (approx.) S9 input in about 15 seconds! Note that it is not "calibrated" in absolute "sensitivity" terms - I'm interested only in the shape of the receiving response.

See how the frequency axis is labelled as running DOWN from FStart at 7,117 MHz to FEnd at 7.107 MHz. This downward sweep of RF is interpreted by the radio, tuned to 7,117 MHz in lower side-band mode, as an upward sweeping audio tone - which is why the graph above is formatted the way it is. 

Think of the frequency axis as being not only the (falling) RF axis (seen at the bottom of the figure below) but also - equivalently - the (increasing) AF axis (seen at the top of the figure below) ...


OK - now I've got this handy new trick, I can use it to prove to you that my Arduino SDR radio's Rx bandwidth really does change - just as I claimed last weekend.

I set  up the Arduino SDR rig as the Radio under Test...


and put a voltmeter on the wiper of the potentiometer that generates the control voltage for Rx bandwidth. Then I made a bunch of receive bandwidth measurements at increasing settings of the control voltage...









As you see, there's a nice smooth increase of Rx bandwidth with increasing control voltage, all the way up to the maximum.

Last of all (for the moment) I took out my multi-band, BITX-inspired development platform and set it up for 40m...


I was quickly able to confirm what is obvious from listening (particularly after listening to the breadboard BITX or - even more so - the SDR): the receiving bandwidth is too narrow...


This is a great way of directly measuring the overall response of a radio system - warts and all - all the way from incoming RF to the output to the speaker. It works like a dream. I am going to neaten it up - possibly by replacing the Bruel and Kjaer element with a custom piece of electronics and by making the RF side a little more "formal" - because I have some important tasks for this new measurement technique in the near future.

Watch this space!

...-.- de m0xpd

Monday, 24 November 2014

Vintage Microprocessors

Whilst preparing some slides for a talk, I needed a picture of my first microprocessor which (I have to admit) was the General Instruments CP1600.

I was surprised to find the internet isn't exactly falling over itself with images of my "first date" - but there is an old example here in the junk box. So, by way of a public service, here's some vintage micro "porn"...


The nMOS CP1600 had an unusual 16-bit architecture, which it inherited from the PDP-11 minicomputer.

The spotty, teenage proto-m0xpd saved his pennies and purchased a CP1600 from Watford Electronics (it was far too exotic to be available from anywhere in Luton back in the 70s),

Here's Watford's logo and storefront...


I got my CP1600 to build a "computer" which was described in one of the magazines of the day - Practical Electronics or something similar. A quick internet search hasn't identified which magazine it was (if any readers remember - please let me know).

All I can remember of that computer is that I was too poor to be able to afford 16 switches to enter data - so I started off with an array of 16 pairs of 2mm sockets (one for logic "true" and one for logic "false") and 16 2mm plugs on short flying leads. The "switch array" was very much in the style of the PDP-11 (at least it would have been, if I had been able to afford switches).

Oh yes - one other thing - my computer had 256 words of memory. Those were the days.

The dalliance with the CP1600 was short-lived - I soon converted to the 6502 (the cheapskate's choice) here's a later example (evidently from RadioSpares)...


Interestingly, General Instruments "became" Microchip - I was to spend even more time playing with their products.

Now there are the sophisticated  distractions of Atmel and ARM etc - but I still enjoy looking at pictures of the simple, exciting processors of my youth - and I still have some of them here, hidden away, but "living with me". Don't tell the XYL!

...-.- de m0xpd

Sunday, 23 November 2014

Arduino SDR 3

When I was pulling together the "slides" for my recent talk on the Arduino Software-Defined-Radio at Rishworth, I realised just how long it had been since I had touched the code - or, indeed, any technical aspect of this interesting radio. I had, indeed, left undone what I ought to have done.


I decided this weekend it was time to make amends - I started by practicing what I have preached over the past few posts and added some 100nF capacitors on the tuning rotary encoder...


That trivial job done (and tuning duly improved -  although the SDR is not as good as my other rigs as the processor is groaning under a close-to 100% computational load), I went on to awaken a dormant "feature" of the code: the ability to implement variable receive bandwidth.

Early in my relationship with the Arduino DUE, I described experiments with variable bandwidth filter design. I used this same filter design routine - at IF - in my software-defined radio experiments. Previously, I never exercised the capability to interpret the edges of the bandpass filter in the radio as variables. Now, it was time to warm that feature up...

I had previously used an analog input on one of the ADC lines of the DUE to control the filter design algorithm - this was repeated in slightly modified form with the double (quadrature) inputs from the Tayloe detector...



My code reads the voltage developed on the bandwidth control potentiometer into a variable called POTO. If this does not change, the code doesn't respond. But if a change is observed, the new voltage is read and used to design upper and lower frequencies for a bandpass filter.

At the lowest setting, (POTO = 0) this will yield a VERY tight CW filter, centred on 600Hz. On the widest setting (POTO = 4096), this will yield a VERY wide SSB filter.

Here's the code that responds to the POTO values...


[No - I'm still not showing you FilterDesign( ) !!]

The rig is no longer "shackled" to a PC - but I can still connect a computer to the USB port for programming and diagnostic duties. That's why there are Serial.print( ) calls in the code segment above. Here's what happens when I adjust the new bandwidth control...

If we steal something like the "hairpin" crescendo / diminuendo idea from musical notation and rotate it through 90 degrees (see the red lines below), you can see what happens when I increase bandwidth from "normal" to "wide" SSB and back again...


Similarly, you can see what happens when I pull back to a really tight CW bandwidth...


All this is all very well - but what does it SOUND like?

Well - I know from the earlier "baseband" (that's to say, audio frequency) filter experiments that the filtering works and sounds fine. But the filter design takes a finite time - so filter re-design isn't instant. Accordingly, I tried stopping the audio when the filters were re-designed, by turning off the interrupts. That made a clear break in the audio, which was pretty disruptive.

Then I got bold and just let it happen. Sure  - you can hear an odd "digital" noise when the filters change, but it isn't objectionable. In fact, it is much LESS objectionable than muting the signal,

Then I decided I would try to make a recording, so you could hear it. I set up to record dj2xb reading the RSGB news this morning on 40m. But there was all sorts of trouble and the beginnings of a Anglo-French war over some ungentlemanly QRM that I decided not to dignify by recording.

You'll have to wait to listen to the sound of my variable bandwidth system - suffice to say, it works.

Update (30/11/2014): there are some measurements which show the receiving bandwidth here.

Here is the new bandwidth control, implemented - for the moment - on a little trimmer.



More to follow - I'm beginning to enjoy playing with SDR again!

...-.- de m0xpd