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

Update (21.3.15)


A little sniffing around on the www has unearthed the article which inspired my computer. It was indeed in Practical Electronics and was penned by one D S Coutts...

Coutts, D.S. (1979). MICROPROCESSOR EVALUATION SYSTEM. Practical Electronics, 15(5) p18

Coutts, D.S. (1979). MICROPROCESSOR EVALUATION SYSTEM - 2. Practical Electronics, 15(6) p42

Coutts, D.S. (1979). MICROPROCESSOR EVALUATION SYSTEM - 3. Practical Electronics, 15(7) p43

The first part of the series, from May 1979, is subtitled "Introduction to the CP1610 and its instruction set", which is interesting, given that I certainly built for the 1600!

The second part, from June, covers "Construction and testing", whilst July's final part is subtitled "Programming (Conclusion of series)".

It would be nice to see a copy of these articles again - anybody have old numbers of PE lurking on their bookshelves?


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

Wednesday, 19 November 2014

Swedish Encoder Taming

Leif, sm7mcd, has sent me some great photographs of his experiments using capacitors to tame the output of rotary encoders - and he has given given me permission to publish them here...

Leif starts by showing that the encoder is capable of generating perfectly clean output in clockwise rotation...


However, the same encoder can also generate "glitches" in its output as the switch contacts bounce, clearly seen here...


Similarly, in counter-clockwise rotation (notice how the bottom quadrature trace now lags the top trace, indicating the different sense of rotation), clean output is possible...


but the switches can also bounce with the resultant glitches...


Leif has added some (enormous) 100nF Mylar capacitors...


and this generates the sort of pulse shape I suggested in the previous post...


Leif shows how the capacitors "eliminate" the glitches caused by the contact bounce...


Notice that the switch's bouncing closure does not have chance to discharge the capacitor and pull the voltage down to zero - we would need to include a discussion of the (small) switch contact resistance and the equivalent inductance in the circuit to describe this behaviour.

Certainly, as I commented in my last post, and as Leif's photos beautifully demonstrate, the capacitors "modify switch bounce". They also add the clear exponential shape to one side of the pulse which (with the addition of the threshold operation in the logic) gives the pulse width increase. 

I remain unsure of the exact mechanism that is taming the encoders - I do not know for certain if it is about switch bounce or pulse width. But I quote from Leif: 

"I experienced the same problem with reading errors from the rotary encoder and it's nice to see that we found the same cure. I did some testing in rapid spinning of the encoder and I found 100 nF almost optimal also for real rapid spinning."

Leif is a member of den Kalmar Radio Amatör Sällskap (Kalmar Amateur Radio Society), who are using some of the m0xpd / Kanga shields in their projects this year. I'm looking forward to any excuses for collaboration with Leif and his fellow members of KRAS.

Tack så mycket, Leif 

...-.- de m0xpd




Saturday, 15 November 2014

Taming the Rotary Encoders

My Rotary Encoders have had it easy - it is time to introduce some tough love...


Ever since the earliest days of the Occam's Microcontroller project, the Arduino QRP transceiver that preceded it (or even the earliest games with the Raspberry Pi) I have used a simple software interface to my rotary encoders. Critics could (with some justification) call it a lazy software interface - but I will defend the word "simple"...

All my (Arduino) code observes the state of the rotary encoder switches once per "loop". This has the considerable benefit of simplicity (as advocated by the KISS principle, by our belovéd Franciscan, etc). It also has the considerable risk of inadequacy!

If the encoder is to be read accurately, it must be sampled sufficiently frequently. One danger of my "simple" approach is that the "one observation per pass through the loop( )" will not constitute a sufficiently high sample rate to satisfy Shannon's sampling theorem, such that neither direction nor speed of the encoder can be deduced. Errors will result.

Both the "correct" solutions (fast, interrupt-driven sampling of the encoder or explicit connection of the encoder to inputs with edge transition detection capability which can trigger interrupts) feel way-too complicated to me and offend against my sense of "appropriate engineering". But the simple approach was always known to be standing on thin ice - that ice has just melted, forcing me into action. Two things prompted my activity...

Firstly, I was getting errors from the Rotary Encoder in my own rig.


I could understand this - my rig was running way-bigger code than anything I'd released to the public (there's more in there than I've told you about - YET!), so my own "sample rate" was even lower than that of any of my "customers". Also, I had a rather long cable run from my board to my Rotary Encoder and I had a pretty hostile operating environment. Most importantly of all, I could readily ignore complaints from this source - even though the errors from my encoder were getting to be pretty bad!

The second thing that happened was much more significant - it really catalysed ACTION. A real, live reader of this blog, named Richard, came up to me at the Rishworth mini-convention and described the problem. He didn't complain - but he could (and perhaps should) have done.

In response to Richard's input, I've finally done something, which has fixed my own rig (above) and which seems to offer a useful "taming" of the Rotary Encoder - I've added two capacitors!


The capacitors are placed in parallel with the two "switches" in the rotation sensing part of the encoder, as shown in the schematic above.  In fact, I had tried this previously (in building the encoder system for the "VFO" for the SI5351-based BITX), where I found it to work very well.

Action of the additional capacitors is understood if you remember that there are resistors (shown dotted in the schematic above) - either fitted explicitly as extra components or embodied as internal pull-ups in the microcontroller. The combination of these resistors and the additional capacitors are going to define a time-constant (making appropriate choice of the capacitor value dependent upon the resistor) which modifies the switching action as sensed by the microcontroller...

The sketch below shows one switch closure with- (bottom) and without- (top) a capacitor fitted.


The downward transition isn't changed. But when the switch opens, the capacitor has to be charged to build up the voltage, introducing a time delay Δt before the voltage read on the microcontroller input pin reaches the logic high value. This "stretches" the pulse width. If the pulse is stretched wider, it can be observed successfully at a lower sample rate.

The capacitors also modify switch bounce (although I think this is irrelevant, given my lamentably slow sample rate) and suppress high-frequency noise which might be induced on the otherwise high impedance line.

I can't confirm the exact mechanism that is taming my Rotary Encoders - all I can report is that the addition of the 100nF capacitors, as shown, is doing an excellent job. I recommend that you add them to all the m0xpd rigs, VFOs, etc that use Rotary Encoders read by Arduino software.

Thanks Richard!

...-.- de m0xpd

Update (16 Nov)


Fred, wa1dlz, has been experiencing problems with my code, including the problem with the Rotary Encoder - see his comment below. In subsequent private correspondence, Fred told me that the capacitors described above made no difference at all on his system - in fact "the 100nf caps actually made things worse".

This information from Fred prompted me to try to visualise the "stretch" in the pulse from the rotary encoder to confirm that it actually exists.

I set up a system (running the "Double DDS" code) and instrumented the rotary encoder pins using my ripoff logic analyser. This claims to interpret VHIGH as being anything greater than 1.4V.

Given that the pulse widths from the encoder are controlled by the rotation speed - which itself is controlled by my hand - the entire experiment is rather difficult to construct. I decided to use one "side" of the encoder as a reference and to add the capacitor to the other "side", as suggested in this schematic...


The resistors (as shown dotted above) are the internal pull-ups in the ATmega328P microcontroller.

I made several measurements, in which I sought to rotate the encoder at roughly similar speed, with and without the capacitor Cx.

The following results are representative...


Whilst I don't suggest this is marked by rigor, I do think there is indication of an increase in the relative width of the "off" phase of the B signal as the capacitor Cx is increased.

Fred's findings show that the capacitors are - by no means - a panacea. They haven't helped him at all -but they have transformed my rig's tuning control from a frustration to a joy.

The "stretch" seems real.  But it may not stretch to solving your problem - please let me know, one way or the other!

Saturday, 8 November 2014

Dodgy Si5351s

Dodgy (for the benefit of international readers) is an informal British adjective meaning "dishonest or unreliable", with further connotations of "potentially dangerous" and "of low quality". I have recently had a batch of dodgy Si5351s foisted upon me - caveat emptor!

You will have seen my infatuation with the Si5351 developing whilst she was clothed in the Adafruit Breakout Board. I was - quite naturally - keen to undress the device and play with her in the flesh.

Fortunately, a batch of naked Si5351s arrived. Unfortunately (given my poor eyesight and cack-handedness), I had first to deal with the "terrible miscalculation of scale" and mount the bare devices on MSOP-10 to DIL carrier boards...



Credit where it is due - I had the devices MOUNTED on the carriers - thanks, Nigel and Dennis!

With objects that I could now both see and handle, I could contemplate making an operating environment for them - I chose (not surprisingly) the environment of an Arduino shield...



Here (above) you see a socket ready to receive the Si5351, a 25 MHz crystal to clock it and a level converter circuit to translate I2C signals from the Arduino UNO lurking beneath the shield to 3v3.

The level-converter circuit is - ironically - the same circuit I used to perform the same role for the earlier, much beloved, Silicon Labs RF generator (the Si570). The same circuit I have used many times in my modular level converter plug-ins. Most ironically of all, it is the same circuit her Ladyship uses on the Adafruit Si5351 Breakout board.

Yes - dear reader - underneath those big labels there are some more pieces of circuitry which I am deliberately concealing from you. It isn't time to show you yet -  Pete calls this the "Fan Dance"!

I put the new Si5351s in the socket - my heart pumping slightly faster than its normal resting rate - and - nothing happened.

I tried all my code (which I knew worked, from experience with the Adafruit board). I tried all the "test" example programs (from Jason and Adafruit). Nothing.

In the end - in desperation - I tried running an I2C "scanner" program, which searches for the presence of any I2C device, and reports what it finds.

Here's what happened...


No wonder nothing was happening - the Si5351 code was anticipating a device at I2C base address of (hex) 60. Instead, the actual device appeared at 6F.

Let's be clear - this is WRONG. This is OUT OF SPEC. Here is an extract from the Data Sheet that defines what an Si5351 IS...



The extra commentary (in the red box) is from your humble servant. Our little 10-pin device only has one I2C address : 0x60. Fancier devices (with more pins) can use one of those pins to give an optional choice of 0x60 OR 0x61. But our little Si5351A is just specified to be there on 0x60. End of.

I knew that my shield with its level converter circuitry was working fine, because I could put the Adafruit Breakout board into the socket and the I2C Scanner could see the Si5351 at the correct address..,



Then - I discovered that the dodgy Si5351s would actually respond, as long as I modified the base address in the libraries to correspond to the (incorrect) 0x6F value that their hardware embodied. This is achieved easily enough in Jason, nt7s' library by an edit of one character of the si5351.h file. But it does nothing to recover the dodginess of the batch of rogue devices...

I want to use Jason's library with ALL my Si5351s - I'm not prepared to have two different versions of software "drivers" to handle some real devices (on the Adafruit boards) and some dodgy ones. This has to be about interoperability.

Finally, I got a second batch of Si5351s and had them mounted on DIL carriers. I put them into the shield and ran the scanner...



At last - the real thing!

Batch 1 came from Mouser (UK). Batch 2 came from Digi-Key.

Jason, nt7s, has previously blogged:

"it seems obvious that Mouser has some oddball parts; perhaps they were custom parts that inadvertently escaped Silicon Labs. I'm still waiting to hear back from Mouser about the issue, but in the meantime, I would recommend you order from a different distributor until they fix this problem."

The evidence above shows that parts from Mouser in the UK also display the same dodgy behaviour.

At the time of writing, Mouser have kindly agreed to refund the purchaser of the Batch 1 devices.

I can continue my romance with some pukka Si5351s.

Pukka, (for the benefit of international readers) is a informal British adjective, meaning "first class" or "genuine" and having Hindi and Urdu origin, (where it originally meant "cooked, ripe").

...-.- de m0xpd