Friday, January 30, 2015

Updated version of the "Simple" PWM LED/Laser modulator

A few years ago, for our friends in the Tucson area, I threw together a "simple" PWM circuit for audio modulation of high power LEDs (but it works just as well for laser pointers) for an optical transmitter - you can read about that here:

A "Simpler" Pulse-Width Modulator for LEDs, Lasers and whatnot and a simpler foam-core enclosure - link
Figure 1:
As-built prototype of the updated PWM transmitter designed to test both
 the AGC and manual gain/tone configurations.
There is currently no circuit board pattern:  If you design one,
please let me know!
Click on the image for a larger version.

As the page describes, this was intended to be comparatively simple and flexible in its operation, providing both modulation of both audio and test tones.  While it worked just fine, it did bother me a bit that it did not have a "manual" gain mode - that is, one could not simply override the audio AGC - which does work quite well - and "ride" the audio level manually, instead.

That was 2009 - so flash forward to 2014 when, at the request of some fellow amateurs in Australia, I finally got the impetus to update the firmware to add the means of selecting a completely manual gain control to the PWM circuit, of so-desired, in addition to various tone modes, all by setting pins on the PIC processor to the appropriate logic levels.  Of course, the original AGC audio mode is still present and may be used exactly as before, if one wishes, and one could even construct the circuit so that it could be switched between manual and AGC mode.

What it's for:

If you have ever been to the web site link  (which I'll admit to having quite a lot to do with...) you will know that it has a lot to do with optical communications - mostly using high-power LEDs, but it also touches a bit on using low-power laser modules as well.

For modulating audio onto LEDs, onto LEDs, one of the easiest ways to do this is via linear current modulation, a process that is explained on the web page Linear Modulator for high-power LEDs - link.

Figure 2:
Examples of waveforms used to generate PWM signals,
from the web page "The Luxeon:  
New Light of Hope for Optical Communications"
by Chris Long

Another way that LEDs may be modulated is by turning them on and off in a manner that simulates linear modulation using a method called PWM, or Pulse Width Modulation - a system that is very easy to do using digital hardware such as counters and is often found in microcontrollers.

For laser diodes such as those found in laser pointers, current modulation is NOT very good for a number of reasons, including the fact that the brightness-current curves of laser diodes isn't particularly linear over a wide range, nor is it predictable at which current a diode will start to laser under a given set of conditions (e.g. temperature, age) or up to what current a specific diode can be safely operated!

For amplitude modulation, it is always preferable that one modulates as deeply as possible to achieve the best-possible signal-noise ratio and if one is trying to current-modulate a laser diode, this becomes problematic as the bounds of safe and reliable operation are difficult to know!  It is more convenient, then, to simply turn it on and off, operating it at a known, safe current when it is on and varying the duty cycle using PWM.

If the switching frequency of the PWM is sufficiently high it will be compatible with a "conventional" analog optical receiver that was intended for amplitude-modulated light sources as the PWM waveform will be integrated by the low-pass response of the receiver's front end.  At the very least, the PWM frequency must be at least twice that of the highest modulating frequency of the audio to be carried  and if necessary, a simple low-pass filter could be added to an existing receiver to remove any residual switching components - see Figure 2 for a pictorial of how a "slow", low-pass response can smooth out the PWM frequency components.

How it works:

Figure 3:
Diagram of the version with audio AGC.
Click on the diagram for a larger version.
This circuit uses a PIC12F683, an 8 pin microcontroller internally clocked at 8 MHz.  Using its PWM hardware, it generates a waveform with a clock rate of 31.25 kHz that is pulse-width modulated at a resolution of 8 bits - suitable for voice.

Audio can come from one of two places:  A built-in tone generator, or an external microphone/line-in audio source.

Using DDS techniques, audio sine waves can be generated at frequencies from a few 10's of Hz to several kHz and these are applied to the PWM generator, producing tones with 100% modulation depth.

Audio from the microphone or line input is first amplified and then low-pass filtered to remove high-frequency content and applied to the 10 bit A/D input of processor where it is digitized at a rate of 31.25 kHz and also passed to the PWM output.

"AGC" mode:

In diagram depicted in Figure 3, the circuit is configured to use an audio AGC to assure that the modulation is kept at a consistently-high level.  The audio level is monitored continuously to determine if its level is within 6 dB of clipping.  If it exceeds that level, a counter is incremented, but if it does not, a counter is allowed to self-decrement.  If the counter exceeds a pre-set value indicating that the audio level has been high recently, the processor pins that control the gain on the amplifier stage are adjusted to reduce the gain to the next, lower step.  If the counter self-decrements below a pre-set value indicating that the audio level has been consistently low, the gain is adjusted to increment.

There is also a built-in 12 dB gain adjustment in software:  If the audio has been low and the audio gain is near maximum, a 12 dB gain step can be switched in which is done by first limiting the A/D values in software to ostensible 8 bit values and then shifting the A/D data to the left by two bits and offsetting.

When switched to the "tone" mode, instead of audio being applied to the A/D input, the voltage from potentiometer R220 is applied instead allowing a variable voltage to be used to set the tone mode:
  • <=0.5 volts:  1 kHz tone
  • >0.5 to < 4.5 volts:  Variable frequency audio tone
  • >= 4.5 volts:  Tone sequence
Having a fixed 1 kHz tone is useful if using a computer or other device when setting up end-to-end alignment of an optical path as narrow detection bandwidths may be employed to maximize the overall sensitivity of the detection scheme.  Because this PIC's oscillator is not crystal-based, the actual frequency can vary by several percent, but it should be easily spotted with spectral analysis programs such as "Spectrum Lab" by DL4YHF, Spectran or Argo (to name but a few).

In the variable tone mode the frequency may be set from a few 10's of Hz (below mains frequency) to a bit over 2 kHz as desired.  Finally, the "tone sequence" mode is designed to emit a musically-dissonant series of notes (C4, E5#, F4#, E6) that really stick out of the noise:  By being dissonant, spanning over an octave and non-continuous they avoid "ear fatigue" and are more likely to be heard amongst other sounds that may be being heard from power mains and electric signage that might be intercepted.

Manual gain mode:
Figure 4:
The version with manual gain control
Click on the image for a larger version.

While the audio AGC works quite well to assure that ones voice fully modulates the LED to maximize "talk power" and signal-to-noise ratio, one may prefer to have a manual gain control instead and manipulation of several of the pins on the processor allows the selection of that mode as depicted in Figure 4.

In this version the audio gain is set with R309, but one can effect a "software" gain setting two switch in an extra 12 dB of gain via appropriate strapping of pin GP4.  As with the "AGC" version, there a variable "tone" mode is available but there are also some "fixed" tone modes that may be selected via appropriate strapping of pins GP3, GP4 and GP5 if you don't wish to use a potentiometer.

Minimalist version:
Figure 5:
Minimalist version.
Click on the image for a larger version.

Finally, Figure 5 depicts a somewhat minimal approach to the circuit, using only a single op-amp section with no active low-pass filter, manual gain control and the optional selection of a tone mode if you choose to implement switch SW301.

At its very simplest, one would connect GP3 (pin 4) to the +5 volt line to put the PIC into audio mode all of the time, but the triviality of adding just one SPST switch and a resistor would provide the facility of a tone generator, doing so would be hard to resist!

Getting the code:

If you are interested in building a modulator for an LED or laser using this device and are interested in the .HEX file for programming the PIC yourself, please let me know.  If you don't have a way to program the PIC and want a pre-programmed device, I can arrange that, too.

More information:

For more information about Free Space Optical Communications for the amateur, be sure to visit the Modulated Light page -


This page stolen from "".

Tuesday, January 27, 2015

Update on the mcHF transceiver - Adding features to the original code

For an follow-up article, see this link.

It has been a few months since I have posted anything on the mcHF transceiver  (my previous post may be found here - link) so unless you have been following the mcHF Yahoo group (link - membership required) you would be forgiven for thinking that I had abandoned work on it.

Figure 1:
The mcHF transceiver in operation, showing signals on 10 meters.
Click on the image for a larger version
Quite the contrary, a lot of features have been added to the code, starting with the fine foundation written by Chris, M0NKA based on version 0.0.181.  Considering that he pulled the disparate pieces together pretty much single-handedly, it is quite amazing what was there when I started!

Of course, this is open-source and the whole idea behind it is to allow multiple contributors:  It would be the height of hubris to think that just one person had a monopoly on good ideas, let alone the time to implement a fraction of them, so a group effort is key here.  Even if the majority of the group does not actually contribute directly to writing code, getting user-feedback is absolutely vital to knowing if one is going down the proper path and the detection and fixing of the inevitable bugs that creep in when work is done!

What is the mcHF?

I've had a few people ask me about this transceiver, wondering what it is, some apparently under the mistaken impression that it connects to a computer somehow like many SDR products.

This is, in fact, a completely stand-alone SDR transceiver capable of operating on all bands from 80 through 10 meters. *

RF goes in/out through a BNC connector, DC is applied, one listens to audio on a speaker or headphone, and "talks" with a microphone or an attached CW key/paddle/bug.  If so-desired, you can even connect it to a computer (or smart phone) and run some "sound card" digital modes like PSK31, RTTY, Olivia, WSPR, DV2 or SSTV if you like via its Line in/Line out jacks. **

The "heart" of this transceiver is the ARM Cortex M4 processor (made by ST) running at something under 200 MHz, a reasonably-powerful device, but not super powerful, which makes for some interesting challenges when one is trying to squeeze in various features - more on that in later posts.

* 160 meters is possible too, with just a bit of "hacking" - maybe just as simple as adding an outboard 160 meter low-pass filter.
** Because it is an SDR it should, in theory, be possible for the mcHF to run some digital modes stand-alone as well, but there is the problem of "too many desired features and too little time"!

Why did I do this?

You might think that I started this project knowing all about SDR and DSP.

You would be wrong.

The reason that I tackled this project was that I DID NOT  know all that much about SDR and DSP.  To be honest, I do have a programming and electronics background (but almost entirely self-taught) and I "knew" how SDR radios and DSP worked at the high level, but I'd really never gotten my hands dirty - so this was my chance to get myself drenched, not just my feet!

Not having worked with the Cortex M4 processor before or the CooCox programming environment, but being familiar with the "C" programming language in general (I've used it for many years in programming PICs and other things) I found Chris' source code to be fairly easy to follow, fairly well documented, and the programming software pretty easy to use and I was soon able compile my own code successfully - so I started adding features.

In the next few posts I'll describe the "behind the scenes" of a few of the features that I added.

* * * * *

Adding features - AGC:

As it happened, just as I got started with this project, Chris had other obligations that diverted his attention for a while, but he was happy to see progress being made:  He did make it open source, after all!

The first major change that I made was the implementation of an AGC in the receiver - something that had been missing from the beginning.

Admittedly, I had no pre-conceived notion as to how to do this in code and I purposely did not look at other open-source implementations, but since I knew exactly how an AGC circuit worked, so I simply wrote some code that emulated the rapid charging of a capacitor in the presence of a signal and the slow discharge in its absence and adjusted the "gain" of the audio path in the process simply by multiplying the "live" audio by the floating point number on-the-fly.

In a nutshell, it works like this.

In a loop, operating on each audio sample:
  • Take the absolute value of the pre-AGC, post-filter audio signal.
  • Multiply it by the current AGC value.
  • If the resulting value is above the AGC "knee" value, reduce the AGC value quickly (e.g. the AGC "attack") by an amount proportional to the current AGC value, but if it is below the AGC "knee" (e.g. the AGC "decay") increase the AGC value comparatively slowly by a proportional amount.   The rate of the "decay" is the AGC "hang" time.
  • Enforce limits to minimum and maximum AGC values.
  • Multiply the audio signal by the AGC value.
  • Use the linear AGC value to calculate the logarithmic S-Meter reading.

To my amazement, it actually worked the first time!

Not mentioned above is the fact that a bit of delay is added to the audio path, allowing the AGC correction to be applied "before" the signal was too high:  Doing this "look ahead" properly can completely prevent AGC overshoot when there is a (suddenly) strong signal in the passband.

Signal path gain control:

As often happens, tweaking the software leads to tweaking the hardware - which leads back to more tweaking the software.  Originally there had been an N-channel JFET across the RF signal path ("Q2" on the RF board) to provide a manual attenuation control.  The problem was that, due to an oversight it was not possible to completely bias this JFET to an OFF state as there was no way to apply a negative gate bias, so it was always causing a bit of signal attenuation (typically 6 dB) even when the attenuation control (and gate voltage) was set to "zero."

I'd also noticed that, while tuning around the bands, particularly 40 and 80, that some strong signals would cause terrible distortion so I put the transceiver on my service monitor and observed that its receiver would overload badly, with clipping of the A/D converter occurring at around -55dBm!


This transceiver uses a Wolfson WP8371 (which is very similar to the pin-compatible TI TLV320AIC23) which contains both a 16 stereo A/D and D/A converters.  In receive mode, the A/D converter takes the quadrature I and Q channels from the receive mixers and digitizes them, sends them to the MCU (processor) and then the D/A converter produces the receive audio.  In transmit, the A/D converter takes the transmit audio which is processed by the MCU and the I and Q channels are sent out via the D/A converter to the transmit mixers.

Upon inspecting the code I noted that the internal gain control of the codec was set to maximum which made me wonder if I could extend the dynamic range of the receiver with the codec's own gain control.

A bit of quick experimentation showed that by setting the codec gain to minimum the signal overload point of the receiver was raised from about -55dBm to around -19dBm - a significant improvement!

Note:  This "overload" level applied to signals within the A/D passband, +/- 24 kHz of center.  The "overload" level of signals beyond this range is approximately -5 dBm or so, the level at which the mixer, RF amplifiers and operational amplifiers started to compress/clip.  This is possible due to hardware-based "brick-wall" filtering within the codec chip that removes out-of-band signals beyond this +/- 24 kHz range plus the intrinsic low-pass filtering of the signal chain that attenuates signals that are much farther removed than that.

A bit more "hacking" at the code yielded the final result - an additional "AGC" loop wrapped around the main AGC loop:

  • The output of the A/D converter is monitored.  If the output exceeds 1/8th full-scale, the codec gain is reduced by one "step" ("several" dB) immediately.  At this same instant other places in the receive signal chain (e.g. audio, S-meter) are rescaled by the same amount to compensate.
  • If the output of the A/D converter never exceeds 1/16th full scale for "a little while" the gain is increased by one step.  In other words, when the strong signal(s) disappear, the gain is increased relatively slowly.  A lower threshold is used for the gain increase to add hysteresis and reduce the likelihood of constant "hunting".
  • If the output of the A/D converter is higher than 1/4 full scale, the bottom portion of the S-meter scale - which is normally white - is displayed in red to indicate a possible overload condition.  This does not indicate a malfunction, but is mostly for informational purposes and it could be useful if one decides to override the "Automatic" codec gain control and use the "manual" codec gain control instead.
  • Internally, the "front end" gain of the codec is tracked and this value is used to compensate, on the fly, those other values that require the input level to always be properly scaled with respect to the RF signal's input level.  Such parameters include the S-meter, spectrum scope/waterfall and the digitized audio from the A/D converter itself.  Where this not done the aforementioned items would "jump" as the codec's gain was adjusted, affecting their operation!
The upshot of the above is that on a "busy" band with strong signals one will occasionally see the bottom portion of the S-meter flash red, but it is extremely rare for the receiver to overload.  Even though reducing the gain of the A/D converter does reduce the ultimate sensitivity of the receiver, in practice this is almost never noticed since, on a very busy band where there are very strong signals, one would probably not "miss" an S-unit or two of sensitivity at the bottom end of sensitivity, anyway!  In other words, we are more prudently using our limited, available dynamic range!

This also meant that by changing the code and taking advantage of the hardware gain control built into the codec, the "iffy" JFET attenuator circuit could be completely eliminated as this new method of "attenuation" was much more effective, anyway!

The next time I write about the mcHF:  Implementing audio filters and fractional I/Q phase adjustments with limited processor horsepower - follow this LINK.


This page stolen from