Showing posts with label voter. Show all posts
Showing posts with label voter. Show all posts

Wednesday, September 26, 2018

A simple 8-channel receiver voting controller for enhanced repeater coverage and usability


One of the often-overlooked means of improving the coverage of an amateur radio repeater is the use of multiple receivers in a voting configuration.  It's often the case that a user can hear the repeater fine, but for whatever reason cannot get back into it - particularly if they are using a portable radio (a handie-talkie) and a compromised antenna, such as a rubber duck antenna.  By extending the reach of the receive portion of the system with several geographically disparate receivers on the same frequency the effective, usable coverage can be increased without the need to have a linked repeater system - which may require additional frequencies - and it reduces the necessity of the user to switch between linked repeaters to maintain coverage.

While this article describes a specific 8-channel voting system, it should contain enough information to be able to implement a similar voting controller using other hardware.

Why a voter?

Figure 1:
As-built voting controller board.
The small board contains 8 LEDs to indicate which receiver(s)
are active and being voted.  This voting controller
has been in service for about 15 years - and this picture,
from a very early digital camera, is lower resolution than
one might like.
Click on the image for a slightly larger version.
Why improve the receiver coverage without a commensurate improvement in transmitter coverage?  This makes sense if the repeater is an "alligator" - that is, "big mouth, small ears" where it can be heard over a wider area than it is often possible to get into it - something that is particularly true for users of handie-talkies - especially when the repeater itself may be located at a "busy" RF site with a high noise floor that limits the sensitivity of co-located receivers.

The use of "extra" receivers also takes into account an important property related to how hams actually use repeaters:  When the signal from the repeater is weak, the user will jockey about to find a "hot spot", but when transmitting to the repeater there is no obvious means of feedback to help that same user find reciprocal hot spot - which may or may not be in the same place as for the receive.

A more subtle  problem with transmitting is that user naturally places the radio very close to their face which may not be conducive to the best transmitted signal to the repeater and it is the tendency for many people to "drop" their radios a bit, holding the antenna in a way other than vertical - something that often goes unnoticed because, while transmitting, they cannot know the quality of the signal making it to the repeater and adjust their position accordingly.

How it works:

When an FM signal gets weak, it doesn't get quieter - it gets noisier - and we can use this property to determine which, among several receivers, is getting the worst signal(s) - but how do we do this?

Figure 2, below, shows what happens.
Figure 2:
A graph representing the relative amplitude of noise with strong weak FM signals.  It is the upward tilt of the noise energy to which "Triangle" noise refers - the angle getting "steeper" as the signal degrades.  Also represented is a high-pass filter that removes the modulated audio, leaving only the noise to be detected.
From this diagram one can begin to see why pre-emphasizing audio along a curve similar to the "weak signal noise" line can improve weak-signal intelligibility by boosting the high-frequency audio on transmit (and doing the inverse on receive) to compensate for the noise that encroaches on weak signals.

When the signal is strong, the noise in the background is at quite a low level - often inaudible but as the signal gets weaker, the noise increases in amplitude with the noise at the highest frequencies getting stronger more quickly.  Because the audio (e.g. voice) occupies the lower frequencies, if we look only at the higher frequencies, we can detect this noise, more or less independently of the audio.

With amateur radio, however, we don't really us "FM" (Frequency Modulation) per se, but rather "PM" (Phase Modulation) or its equivalent.  Saving a complicated explanation and some math, the reason for doing this can be divined by taking another look at Figure 2, above.  What one notices is for a given signal - strong or weak - that the amplitude (loudness) of the noise increases with frequency.  What this means is that if we were to use "true" FM (whatever that is) on a weaker signal we would hear sharp-timbered noise at higher frequencies creep in to the signal.

In an effort to reduce the effects of this noise, in Amateur Radio the "highs" of the transmitted audio are pre-boosted (called "pre-emphasis") to counteract this effect and on the receive side, they are then "un-boosted" (called "de-emphasis") to restore them to their original frequency response.  Because of this "un-boosting" the high-pitched hiss is also reduced and the end result is that when one hears hiss on a weak signal on, say, 2 meters, the noise doesn't have that high-pitched timbre, but it sounds rather like white noise.  This has the overall effect of reducing the amount of noise that is perceived on a weak signal, allowing such signals to sound better than they would were it not for this combination of "pre" and "de" emphasis.
Figure 3:
A typical squelch circuit found in FM receivers.


An analog representation of a squelch circuit may be seen in Figure 3 with the audio typical taken from the discriminator of the receiver, before the de-emphasis as we actually want to preserve this high-pitched (ultrasonic) noise.  What all of this means is that if we have several identical receivers listening to the same frequency, we can tell something about how "good" the signal is simply by comparing the amount of this high-pitched noise is coming out of them:  The one with the highest amount of noise represents the weakest signal.

Comparing remote receivers:

The comparison of this noise is easily done if all of the receivers are located in the same place, but what about the typical situation where the receivers may be scattered about, being "connected" to the common point via radio links?  The problem with doing this is that the high-pitched noise due to weak signals received via the remote receiver can't easily be transmitted via the link owing to bandwidth concerns - and if we were to try to do this, the squelch on the link receiver itself may be fooled into thinking that the retransmitted noise was actually on the link.

For practical concerns, audio transmitted by an amateur FM transmitter is typically low-pass filtered around 3 kHz so that much of the audio above this would be just  noise in the case of a weaker signal, but in a link from a remote receiver we would take this receiver's audio - and its noise - and cut it off, causing us to lose that ultrasonic energy that we'd use to determine the signal quality.

While we would normally use this ultrasonic noise for squelch threshold determination, we can still use what is left to compare two signals.  When we listen to an FM signal with our ears, we can tell if it is weak because we hear noise in the background - and the level of this noise is constant, whether the signal is being modulated by the user's speech or not.  What this means is that if we simply look at the audio coming from two receivers - and compare them - the one that is weaker will have audio plus noise and will, overall, be a bit louder.  If we filter this audio a bit, keeping only the higher-pitched audio - say, that above about 2 kHz - we can more easily make this comparison as most of the audio power of speech is located below 2 kHz, so what we get is a greater percentage of noise and less voice, making the determination easier with simple circuitry.

In the case of the voting controller described, the method of "the lowest noise above 2 kHz is the best signal" is used.  This makes it fairly easy to use several signals from disparate receivers to achieve a comparison.

Comment:
There are other methods of determining "which is the weakest signal" - but they all rely on determining which signal is noisiest.
Another method that is used by some voting systems - one that does not rely on high-pass filtering - is an "inverse peak" detector that measures the maximum "quiet-ness" of the signal being received.  By determining how quiet the "quiet parts" are (between words, etc.) the best signal may be determined because a noisy signal will have more noise in the quiet parts than a "full quieting" signal.  This method typically employs a logarithmic detector to permit useful measurement of the wide dynamics between audio peaks and dead silence.   

A simple voting controller:

Figure 4, below, shows the schematic of the voting controller.


To simplify things, this voting controller sits in "front" of an ordinary repeater controller, taking the audio and COS inputs from the various receivers and outputting a single audio and COS signal.

If the repeater system in question uses subaudible tones, it is recommended that "discriminator" audio (e.g. that which has not been de-emphasized) that has not been subject to a squelch or tone detector audio gate be applied to the voting controller from the link receivers as well as any "local" receivers as this will assure that the voted audio will contain the subaudible tone.

By having audio that is not gated by the squelch or tone detector the response of the voting receiver system will be much faster and less-subject to drop-outs as it moves between receivers.  Having the subaudible tone detector following the voter will assure faster, more consistent operation, provided that one is careful to make sure that the received phase of the subaudible tones being received by all receivers (e.g. from a single transmitter being heard by all receivers) is as close to the same as possible.

Figure 4:
 The schematic of the as-built voting controller.
An alternate notch filter is depicted in Figure 6, below.
Click on the image for a larger version.
How it works:

Microcontroller:

The heart of the voting controller is U8, a PIC microcontroller.  Originally, a PIC16C84 was used with an R/C clock oscillator - but this device has long been discontinued, but a minor firmware change was made several years after it was put into service and was replaced with a somewhat more modern, pin-compatible device like a PIC16F628 or PIC16F819.  Even a more modern device like a PIC16F88 or a PIC16F1847 could be used with no wiring changes. Because there are no critical timing requirements, the on-board oscillator is used.

The job of the microcontroller is simply to look for active COS inputs and then select the audio sources and do a "noise comparison" to see which one is best and select it.

Audio source selector:

There are really two identical audio source selectors:  For the moment we'll talk only about "MUX A" using U2.

U2, a CD4051 CMOS 8-channel MUX is used to select the audio inputs:  This device is a genuine 4000-series device and is run from the 12 volt supply to minimize its internal resistance as well as allow the widest-possible swing of the input analog voltages.  To interface it with the 5 volt logic of the PIC, Q1-Q3 are used for logic level conversion, the "inverting" of the bits taken care of in software.

For U2 (MUX A) the selected audio also gets buffered by U4D which is passed to the repeater controller as the "voted" audio.

High-pass filter/noise detector:

Each of the MUX's inputs are capacitively coupled and biased at mid-supply (approx. 6 volts) and the selected output is buffered by U5A, a unity-gain follower and then applied to a 3 kHz high-pass filter.  This high-pass filter - which doesn't really gain its true effectiveness until below around 2 kHz - removes most of the lower-frequency energy related to the speech, leaving mostly any background noise (hiss) from weak signals.

Following the high-pass filter is a rather high-gain non-inverting amplifier that boosts the filtered audio significantly.  Because most of the audio energy of a "clean" signal is below the 2-3 kHz range, the total amount of energy that remains is quite low, but by amplifying it, even low amounts of "hiss" can be detected.  During normal use, this noise amplifier will often be driven into clipping, but that's OK as a poorer-quality signal (e.g. noisier) will still have, overall more total audio energy.

The energy from this amplifier is rectified and smoothed by diodes D1 and D2 - with a small amount of DC bias for the diodes provided by R25, a 1 Megohm resistor which slightly improves low-signal sensitivity - particularly when several signals being received via the receiver(s) are at or near full-quieting.

Signal quality comparator:

At this point it's worth mentioning again that there are two audio paths - the "MUX A" path input via U2 mentioned above, and an identical audio path that uses U3 and the same amplifier and noise detector arrangement:  The only difference is that it is only the audio being selected by "MUX A" path (via U2) that is passed to the repeater controller, so that is always going to be the "best" signal if more than one is present.

Having two separate "noise" voltages, a simple analog comparator, U6, is used to see which one is the "noisiest".  In this case, an LM311 comparator is used, relying on microcontroller's internal pull-up resistor to provide a logical "high" signal - and this handily does the logic level conversion as well.  An LM339 would have worked fine, but since we need only a single comparator - and the '339 has four - I just used an LM311.  In a pinch it's possible that an op-amp could have been used as a detector, but care must be taken to assure that the chosen op amp will work properly with signals that are very near ground and can go up near the positive supply rail.

Comment: 
The originally-used PIC16C84 did not have a built-in A/D converter or comparator, but many more modern PICs do - and either one could be used in this case to compare the two signal paths' noise voltages.  Because the more modern processor was a retrofit for the original 'C84, there was no reason to get rid of the comparator.
If an internal A/D converter or comparator is used, be aware that the analog voltages from the noise detectors could easily exceed the maximum 5 volt rail of the processor so appropriate clipping/scaling should be applied.


COS Mux:

For each of the (up to) eight receivers, there is a corresponding "COS" input - that is, a line that is pulled to ground (typically by an open collector or drain) when that receiver picks up a signal that opens its squelch.  To convey these eight signals to the microcontroller, U1, a 74HC168 8-input shift register is used.  During normal operation the controller will strobe the current states into the register via the "/PL" line and then, using the clock and data lines, read them serially - all using just 3 processor pins instead of 8.

Note that there are two resistors on each input of U1:  R16(a-h) being used to pull the input up to 5 volts and series resistors R17(a-h) used to protect the input of U1 in the event that the COS input happens to go above 5 volts.

PTT Output:

If any COS input is active, the PTT signal from pin 2 of U8, the microcontroller goes high.  This signal then enables Q7 an NPN transistor that is used to pull the repeater controller's PTT line low.

Active channel indicator:

To indicate which receiver's audio is currently being passed to the repeater controller, U9, a 3-8 decoder - is used, monitoring the address lines for MUX A.  If no COS signals are active, U9's "E3" input, which is tied to the same microcontroller pin that asserts the PTT to the repeater controller, goes low, turning off all of the LEDs.

Comparing signals:


At this point it's worth talking about how the signals are compared and voted on.

MUX A is always used by the best receiver after voting so that it will be passed to the repeater controller.  MUX A is therefore always used as the basis of comparison to any other channels that might be active.
  • If there is one receiver active as indicated by its COS line, MUX A is used to select it, which pipes the audio to the output, to the repeater controller.
  • If there are two receivers active, the first one to have been detected active is set to MUX A and the second one is set to MUX B.
    • If the receiver on MUX B is "quieter" than the one on MUX A, the output of U6 will be generally low because of higher noise coming from the MUX A channel.  In this case, the microcontroller will swap the two signals, putting the "better" one on MUX A where it can be passed to the repeater controller.
  • If there are more than two receivers active, MUX B is used to switch between these other active receivers, comparing them to that "active" receiver on MUX A:  If another of these others suddenly has a better signal, it's immediately moved to MUX A where it can be output to the repeater controller.
  • If the COS for the receiver on MUX A suddenly disappears but there is at least one other signal present, the lowest-number signal is immediately switched to MUX A and the voting process resumes.
  • If there are suddenly no active COS signals, the output PTT signal from the microcontroller is dropped immediately.
How it works in Software:

(Note that the source code, in "C", is included below if you wish to "play along".)


In the "main()" loop of the software, the "update_sr()" function is called every time it executes, making certain that the COS inputs are updated very frequently. 
When the microcontroller is in it's "idle" state (no active COS input) both the "A" and "B" audio MUXes are set to receiver 1.  Besides being a convenient starting point, this allows easier adjustment of the noise detector circuits as they would be fed with the same signal, making it very easy to set them identically.


If, after being idle, a COS input goes active, the first one that the it runs across is assigned to MUX A and the PTT output is set active.  After assigning the first signal to MUX A - which causes that receiver's audio to be passed to the repeater controller - another portion of the code is then executed that looks for other active COS inputs.

If one or more active COS inputs are detected, it assigns the first one to MUX B.  Allowing time to for the readings to settle, the controller then does a bit of simple averaging over the next 25 loop cycles (which takes about 25 milliseconds) to see if the signal on MUX B seems to be "better" than the one on MUX A.

If the signal currently on MUX B is better, MUX A is switched to this input.  If the signal on MUX B is not better, the controller sequentially switches MUX B to other currently-active COS inputs and makes the same comparison.

In this same loop, an eye is kept on the COS status of the channel to which MUX A is currently set:  If this COS goes inactive, the code immediately re-scans to find another active COS input, assigning it to MUX A to make sure that audio from an active receiver is being passed to the repeater controller.  If it is determined that there are no active COS inputs, the PTT line is immediately dropped so that the repeater controller may do its normal "hang time" operations.


Other means of implementation:

For the original implementation I used a PIC microcontroller because I've long been familiar with them and have had the appropriate development tools, but it could be done using something like an Arduino if they'd existed when I first built this:  Even the cheapest, low-end UNO would even be overqualified for the task!

To do this, one would simply substitute the Arduino and its I/O pins for U8:  While the Arduino has available comparators and A/D converters, it would be almost as easy to use an outboard comparator rather than trying to get rid of it unless, as noted above, you are prepared to scale voltage appropriately.

It is possible for the entire device to run from a single 5 volt source, but if this is done rail-to-rail input and output op amps are strongly recommended and very close attention should be paid to the peak-to-peak voltage swings of all the analog signals:  Worst-case is typically the "no signal" condition where the radio is outputting noise and if an analog voltage goes above the supply voltage or "below" ground (as can happen with capacitive coupling) many analog MUXes will spuriously conduct this noise into other, de-selected channels, causing very annoying "popping" in the audio.

Using a "voting" tone:

Many voting systems include a tone that is sent along the circuit when no signal is present - and for best performance, such is recommended here.

For example, each remote receiver is configured with a 3.5kHz oscillator that is activated when the squelch closes and the audio being receive and then transmitted along the link to the voting site is muted - followed by a short (half-second or so) "hang time" with the remote receiver/link transmitter transmitting only this tone.

The reason for this is to minimize the number of "noise bursts" that one might hear as a user popped in and out of more than one receiver.  For example, if the user was "weak but solid" into receiver "B" but was popping in and out of "A" - often with a good signal - then the voter would select receiver "A" when the user was solid into it, but reverting back to "B" when the signal dropped out.

If the link transmitter were to key on and off every time the user dropped in and out of "A", the link receiver at the voting site would get a burst of squelch noise every time - and this would inevitably come across the link in the instant before it was detected, making the signal sound more "multipathy" and noisy than it really was.

If, instead, a strong 3.5kHz tone was sent down the link as soon as receiver "A" dropped out, the voter would detect this tone as if it were noise - but much more strongly so - and the voter would immediately switch away from it, to receiver "B", handily avoiding that burst of noise that would otherwise be transmitted from both the receiver "A" and its link transmitter dropping out at the same time.

This typically works because, in a voter system, one rarely drops instantly out of one receiver, but in the case of multipath this fade can happen very quickly:  Having the tone switch on helps make the voter switch more quickly with the squelch on the receiver "A" closing before the signal is completely gone.

Having this tone does mean that to those listening, a brief burst of that tone will come through - particularly if only one receiver is in use:  In that case, there is no "better" receiver to switch away from which means that the 3.5 kHz tone will blast out during the link transmitter's brief hang time.

To prevent this ear-piercing tone from being obnoxious, the schematic in Figure 4 includes a notch filter to reduce this 3.5 kHz tone.  As mentioned in the notes below this small diagram, it is strongly recommended that the pairs of capacitors and resistors be carefully matched to obtain the best notch depth (which should be well over 25dB).  It is suggested that this filter - or one of similar function - be placed on the audio output before it is passed along to the repeater controller.

Block diagram of an example system:

In Figure 5, below, is a block diagram of an example system.

Figure 5:
Block diagram of an example voting repeater system with two remote receivers and one receiver co-located with the transmitter.  An example of a "tone decoder module" is given in Figure 6, below.
Click on the image for a larger version.

Remote RX site:

The remote receiver (one of several, perhaps) is located at a site that offers complementary coverage - or perhaps to fill in a particularly badly-covered area where users may be able to hear the repeater well (perhaps noisily) or in an area where it may be advantageous to have a "local" receivers to allow good coverage via low-power handie-talkies (say, an area where public service events are commonly held.)  This remote site should include a rudimentary repeater controller capable of producing hang-time, legal identification and time-out should a signal get "stuck" on the receiver's input.

If the system is to be used with a subaudible tone it is recommended that the tone decoder not be located at the remote receiver, but rather that it be normal "COS squelch" and that the tone be able to be passed directly from the receiver to the transmitter:  Many receivers and transmitters have high-pass filters to prevent exactly this so it may be necessary to select the gear carefully and/or make some modifications to allow this.  The reason for this is that subaudible tones are quite slow to be decoded meaning that if a signal is weak or choppy, a lot of content can be lost during these portions of a transmission as the already-slow tone decoder will be even slower to respond if the signal is noisy.  If a subaudible tone is decoded at the link transmitter, expect there to be more "holes" in the audio as users transition between the two receiver sites than otherwise!

When the COS of the received signal drops, a 3.5 kHz tone is switched in instantly to "un-vote" the signal from that receiver:  This "loud" tone will instantly be detected by the voting controller as one that is "bad" (e.g. lots of high-frequency content - a stand-in for the noise of a poor signal) and it will vote "away" from this receiver - assuming that another receiver is still active.  If no other receiver is active, the notch filter (in the voting controller) will remove this tone so that users can't hear it during the remote site's transmitter's hang time.

The reason for the hang time (where the remote site is transmitting only a tone) is to reduce the amount of audible "chop" that might be heard when a signal is dropping in and out of a receiver.  By having a bit of hang time (with tone) the voter will be given a chance to "switch away" from it when a signal drops without there being the burst of squelch noise when the link transmitter drops, before the receiver at the voter site's squelch closes.

Repeater transmitter site:

At the repeater's transmitter site there may be one or more "link" receivers - but there may also be a "local" receiver.  As seen, the voting controller sits between the receivers and the repeater controller, the idea being that the voting controller will make the multiple receivers look like a single receiver.

In the simplest case, all receivers simply connect to the voting controller via their (unsquelched!) audio and their COS lines:  As with the remote receivers, the link receiver should be COS-only with no subaudible tone for the same reasons as mentioned above.  The subaudibletone decoder should only be present in the signal after the voting controller to provide the best response to rapidly-changing signals.

"Voting tone":

To prevent the shrill 3.5 kHz tone from blasting through the repeater during the hang time of a link receiver, the 3.5 kHz notch filter is depicted in the audio path between the output of the voting controller and the repeater controller.  At 3.5 kHz, this notch will have little or no effect in the quality or timbre of the received signals.

Figure 6:
 An example of a tone detector that can be adjusted to 3.5 kHz
along with another example of a notch filter for the tone.
This diagram also includes a de-emphasis circuit in the event
that were needed.  Note that all capacitors NOT used
for power supply bypassing (e.g. those in the de-emphasis,
notch filter and tone decoder) must be temperature-
stable plastic capacitors and not disk ceramic.
Click on the image for a larger version.
Also included in the diagram is a "voting tone" decoder designed to respond to the 3.5 kHz tone sent from the remote site and this is useful if it's desired that the hang time of the remote link transmitter (while the tone is active to "un-vote") be removed from the equation.  Its purpose is simply to detect that 3.5 kHz tone and de-assert the COS signal, causing that receiver to be not only "un-voted", but also to allow the COS from the voting controller to un-key immediately even if the receiver in question is one of the remote receivers with its own hang time.  This also has the effect of eliminating a "double kerchunk" caused when the user unkeys, and then again when link transmitter unkeys and its receiver's squelch closes.

It should be noted that if there is a direct wire connection between the receiver and the voting controller - as would be the case for a local receiver - none of this 3.5 kHz nonsense is required as there is, by definition, no extra "squelch noise" burst on that receiver as would happen on the remote receiver when its link transmitter un-keyed.

Final comments:

If you do plan to have an analog voter of any kind, also note that you must use a purely-analog receiver:  While tempting, radios that use "all in one" chips (such as Baofengs and other imported brands) are probably not usable as they tend to have a bit of delay, they may have no easy way to defeat the filtering of subaudible tones, and they also tend to automatically switch in a low pass filter on noisy signals - something that would mess up any comparison that you would hope to do - and this assumes that they actually have a "COS" output that is actually fast enough to be useful!

What about voting for a digital system?

While implementing a voting repeater system for an analog repeater is straightforward, the same cannot be said for digital signals.  To an extent, a radio could "know" of several different linked systems in a given coverage area, but having several systems not only requires a lot of resources (gear, frequencies) but it is arguably less convenient and less effective than having a voting system to increase the "grasp" of a receive system.  In theory, one could have very carefully designed receive systems that "seamlessly" switch between two receivers without corrupting bits (very careful attention to phase and timing would be required!) but the noise-like nature of digital signals makes their direct quality comparison a bit more difficult.

If some sort of voting system is used, it might also have individual digital demodulators at each site and then convey that digital signal to a more complex voting system that performs re-timing of the received signals and then monitors the apparent error rate, feeding the "best" result to the original repeater:  Such a system is beyond the scope of this article.



Addendum:

* * *
Source code:

What follows is source code, in "C", targeted for a now-ancient version of the CCS compiler.  This version of code assumes the use of a PIC16C84 microcontroller that used external R/C oscillator components.  (I couldn't find the version updated for the newer processor - but the changes required were very minor.)

It is not expected that one would use this code as-is, but rather use it as an example as to how the logic worked so that it could be applied to other platforms.

This code is supplied as-is with no expressed or implied warranty regarding usefulness or fit for any purpose.

* * *

/*
This code is for an 8-input voting controller.  There are two noise-detect channels on 8-input
MUXes:  Channel A is the "primary" channel:  This channel, when selected, outputs the selected
channel's audio.  Channel B is used to compare against channel A and if it is *better* than
channel A, then THIS channel gets transferred to A (thereby selecting it as the audio source.)
Note that ONLY those channels with active COS are compared.

Revision History:

0.01  20000610    Started work
0.02  20000611    First operational version (I think...)

Notes:
   - It is highly recommended that the audio inputs from the various
      receivers be UNMUTED by the COS.
   - When an input signal is active, the respective input COS signal goes
      LOW.  This is usually accomplished with an open collector at the
      receiver.
   - Unless ALL of the receivers are local, the audio inputs MUST
      be de-emphasized.
   - All audio inputs are to be adjusted identically at their
      respective receivers.  The more closely matched, the less difference
      will be heard when the voting occurs.
   - This voting controller does NOT affect the audio passed through it in
      any way (assuming that the amplifiers aren't clipping) other than by
      selection of the audio source.  Once the receivers are adjusted for
      EQUAL output levels, THEY SHOULD NOT BE READJUSTED!  Doing so will
      require complete realignment of the system/voting controller.  If
      additional transmit deviation is needed, this should be done by
      adjusting the CONTROLLER and *NOT* the the receivers!

Adjustment procedure:

   - This procedure assumes that the highest audio input level will occur
      with squelch noise.
   - The following test points are used:
      TP1 - Noise detector Channel A output voltage
      TP2 - Noise detector Channel B output voltage
      TP3 - Noise Channel A output level (highpass audio)
      TP4 - Noise Channel B output level (highpass audio)

   This procedure is to set the noise channel outputs (TP3 and TP4) to the
      highest level possible (without excessive clipping) so that, for the
      same signal, the detector voltages (on TP1 and TP2) are as close to
      identical as possible.

   1) MAKE SURE THAT ALL RECEIVER OUTPUTS ARE MATCHED IDENTICALLY WITH THE
      SAME AMOUNT OF DEVIATION!  That is, with 3 KHz of deviation, all
      receivers should be set to output the SAME audio level.
      Additionally, the audio equalization should be matched as closely as
      possible for all receivers.
   2) With *no* COS signals active and with (unsquelched) audio going into
      RX audio 1, connect an oscilloscope to TP3 (noise Channel A Highpass
      output) and adjust potentiometer RA for the maximum audio level that
      results no or only a slight amount of clipping.
   3) Move the oscilloscope to TP4 and adjust potentiometer RB for the same
      level as on TP3.
   3) Connect a voltmeter to TP1 (MUX Channel A noise detector output) and
      note the voltage.  It will bounce a bit as the noise, so note the
      "average" voltage reading.
   4) Move the voltmeter to TP2 and adjust it to the same average voltage
      as read on TP1.
   5) Using the oscilloscope, compare the outputs at TP3 and TP4.  If one
      is much higher than the other, reduce the highest one somewhat and
      set the other channel to the same using a similar procedure to the
      above.
   6) When done, make sure that TP1 and TP2 are approximately equal
      voltages (i.e. closer than 0.1 volts of each other.)

*/

#OPT 9

#include    <16c84.h>    // define use of 16c84a

#define        PORT_A_ADDR    0x05    // port A address
#define        PORT_A_TRIS    0b00001    // port A I/O mask (LSB in, RA1-RA4 out)
#define        PORT_B_ADDR    0x06    // port B address
#define        PORT_B_TRIS    0b10000000    // port A I/O mask (LSB and MSB in, others out)

#define     WAIT_TIME   7     // time, in milliseconds, that we should
                              // wait before starting to make any decision
#define     VOTE_TIME   25    // The number of "cycles" through the quality
                           // decision loop.  Each cycle takes about 1
                           // millisecond
#define     QUAL_THRESH 15    // this is the number "good hits" that are
                              // required during the "VOTE_TIME" to decide
                              // if "this" one is really better

#byte        PORT_A = 5
#byte        PORT_B = 6
#fuses        RC, WDT, NOPROTECT, PUT
// RC Oscillator, watchdog, no code protect, Power Up Timer, no
//brownout protect


#use delay(clock=225000, RESTART_WDT)  // 225 KHz = 33k & 82pf

#use    fast_io(a)        // set port A for fixed-mode of I/O direction
#use    fast_io(b)        // set port B for fixed-mode of I/O direction

// System definitions:


#bit SR_INDAT = PORT_A_ADDR.0 // Serial data from parallel-input shift register
#bit SR_CLK = PORT_A_ADDR.1   // Shift register clocking
#bit SR_PLOAD = PORT_A_ADDR.2 // Shift register parallel load
#bit COS_OUT = PORT_A_ADDR.3  // "voted" COS output (1 = active)
// PA4 is reserved
//
#bit MUXA_A = PORT_B_ADDR.0   // audio mux A LSB
#bit MUXA_B = PORT_B_ADDR.1   // audio mux A
#bit MUXA_C = PORT_B_ADDR.2   // audio mux A MSB
#bit MUXB_A = PORT_B_ADDR.3   // audio mux B LSB
#bit MUXB_B = PORT_B_ADDR.4   // audio mux B
#bit MUXB_C = PORT_B_ADDR.5   // audio mux B MSB
// PB6 is reserved
#bit COMP_IN = PORT_B_ADDR.7  // signal quality comparator (0 = "B" is *BETTER* than "A")

byte  cos_data;


#ZERO_RAM        // This macro causes code to wipe all memory locations

// This function gets data from the input shift register

update_sr(void)
{
   char x;

   SR_CLK = 0;             // initialize sr clock
   SR_PLOAD = 0;           // load data into shift register
   SR_PLOAD = 1;           // 'freeze' data in input shift register

   cos_data = 0;           // clear Carrier Operated Squelch input shift register

   for(x = 0; x <=7; x++)  {
      SR_CLK = 0;
      cos_data <<= 1;         // shift next bit of input data into position

      if(SR_INDAT)   {
         bit_set(cos_data, 0);   // Set the LSB of "cos_data" (this is a one-instruction PIC operation) if SR output is high
      }
      SR_CLK = 1;           // shift the data in
   }
}

void  setmux_a(byte b)     // this function sets MUX channel A
{
byte  temp;

   temp = PORT_B;             // read port B output register
   temp &= 0b11111000;     // clear 3 LSBs for MUX A
   b ^= 0xff;              // invert contents to account for inversion of level converter
   b &= 0b00000111;        // make sure nothing is in anything but bottom LSBs
   temp |= b;              // overlay MUX A data
   PORT_B = temp;          // send it out
}

void  setmux_b(byte b)     // this function sets MUX channel B
{
byte  temp;

   temp = PORT_B;             // read port B output register
   temp &= 0b11000111;     // clear the 3 bits for MUX B
   b <<= 3;                // shift the current MUX data to match bit positions
   b ^= 0xff;              // invert to compensate for level conversion
   b &= 0b00111000;        // make sure nothing is in this but the correct bits...
   temp |= b;              // overlay MUX A data
   PORT_B = temp;          // send it out
}


void main(void)
{
byte  x;                      // multipurpose counter
byte  qualcnt;                // "quality" counter
byte  mux_a;                  // holder/counter for mux_a
byte  mux_b;                  // holder/counter for mux_b

short cos_scanflag;           // flag bit used in scanning for COS activity
short recheck_flag;

   setup_counters(RTCC_INTERNAL, WDT_144MS);

    SET_TRIS_A(PORT_A_TRIS);    // set I/O direction for ports
    SET_TRIS_B(PORT_B_TRIS);
//
   PORT_B_PULLUPS(TRUE);

   COS_OUT = 0;               // clear output COS line...
   mux_a = 0;                 // initialize MUX selectors
   mux_b = 0;
   recheck_flag = 0;

   update_sr();               // grab data (to initialize shift register)

   while(TRUE) {
      update_sr();               // get current COS status
      restart_wdt();
         if(cos_data == 0xff) {  // is there *NO* COS activity? (bits go low when COS is active)
            COS_OUT = 0;         // yep - indicate such.
            mux_a = 0;           // always put both mux channels on 0
            setmux_a(mux_a);     // when no COS inputs are active...
            mux_b = 0;
            setmux_b(mux_b);
         }
         else  {              // there *is* COS activity.  Find out which one it is...
            if(!COS_OUT || recheck_flag)   {    // the output COS is not yet active *or* ONE
                                                //  became inactive, we need to find one that
                                                // is active is hearing the signal
               recheck_flag = 0;
               mux_a = 0;        // always make sure it we are starting out at zero...
               mux_b = 0;        // init mux B count
               cos_scanflag = 1; // init flag used for scanning COS bits
               while(cos_scanflag)  {     // this keeps happening while the flag is set
                  if(!bit_test(cos_data, mux_a)) {    // is it *THIS* bit that is active?
                     setmux_a(mux_a);                 // yes - set MUX to this address
                     COS_OUT = 1;                     // set COS activity
                     cos_scanflag = 0;                // clear flag so we don't go thru this again
                  }
                  else  {
                     mux_a++;       // bump count to next input
                     if(mux_a > 7)  {        // did we exceed our maximum count?
                        cos_scanflag = 0;    // yes - we bail out...
                        COS_OUT = 0;
                     }
                  }
               }
            }
            else  {     // COS *IS* active - lets look at other inputs to see if they are active
               if(!bit_test(cos_data, mux_b)) {    // is *this* COS bit active?
                  setmux_b(mux_b);     // change MUX to new channel...
                  delay_ms(WAIT_TIME);             // wait for comparator to settle
                  qualcnt = 0;
                  for(x = 0; x < VOTE_TIME; x++)  {
                     delay_ms(1);
                        if(!COMP_IN)    { // is this NEW a better signal?
                           qualcnt++;
                        }
                  }
                  if(qualcnt >= QUAL_THRESH)  {   // has the signal been better for enough samples?
                     mux_a = mux_b;                // yes - set both MUXes to the same place...
                     setmux_a(mux_a);              // set output to new signal put it there...
                  }
                  COS_OUT = 1;                     // make SURE we have COS output enabled
               }
               mux_b++;    // bump to next mux count
               mux_b &= 0b00000111;       // mask mux address
               if(mux_b == mux_a)   {     // are we attempting to look at the same input?
                  if(bit_test (cos_data, mux_b))  {   // is *this* COS bit INactive now?
                     recheck_flag = 1;                // yes - this signal went away - get new COS
                  }
                  mux_b++;                // yes - go to the *next* address
                  mux_b &= 0b00000111;    // mask mux address
               }
            }
         }
      }
}




This page stolen from ka7oei.blogspot.com

[End]

Thursday, January 17, 2013

Two repeaters, one frequency (part 4) - Voting receivers

This is an ongoing series of posts:  For the most recent, previous post in this series, see Part Three (link).

In the other three parts of this string of posts I described the two repeaters, how their operation is greater than the sum of their parts and how the two transmitters can share the same frequency without causing mutual interference.

This time, it's the "Voting Receivers".

In order to achieve reasonable parity with a multiple-transmitter system, we also need to duplicate the effect on receive which means that we have to take the users' signals from both sites and then decide how to use them on transmit and for this, we have a "Voter" system.

As its name implies, the voter "looks" at all of the signals that it is getting from the various receivers and somehow decides which one is best - and that one is sent to all of the transmitters in the system.  The result of this is that during a user's transmission, it's possible that the receiver being used might change several times as the signal fades from one receiver and is picked up by another - particularly in areas where coverage overlaps!

Now, then, does one "vote" on a signal?

First, let's talk a bit about what happens to an FM signal as it gets weaker.

Unlike AM, in which the audio can get weaker as the signal gets closer to the noise, the audio from an FM signal stays constant no matter how weak or strong the signal might be - although something interesting happens when it gets to be too weak:  It doesn't get quieter, it gets noisier!

What is happening is that as the signal gets weaker, the detector - which looks for the "frequency wobble" of an FM signal - starts to have trouble distinguishing between the desired signal and the background noise, so that noise starts to creep into the audio.  There is a threshold at which a slight decrease in signal starts to result in a very marked increase in noise and for a number of reasons, this is often referred to as the "limiting threshold."
Figure 1:
The front panel of the voting controller showing the indicators
of the input channel status (green) as well as various
status/health indicators of the unit itself (red.)  A DE-9
jack provides access to the RS-485 bus for configuration
and status monitoring.
Click on the image for a larger version.

What this means is that if you have two copies of the same signal from two different receivers, you can tell which one is the weaker signal NOT by how loud or quiet its audio might be, but looking at how much extra noise it contains:  If the receivers are otherwise identical, of the two versions of the same signal, the noisier one will always be the weaker one!

How, then, does one compare noise?

There are two common techniques:
  • Compare "quiet-ness".  In the pauses and spaces between words, there will be brief pauses of silence - or, at the very least, portions that aren't as loud as the peaks of the audio.  The weaker signal will have more noise, so it won't be as "quiet" during these pauses as the strong signal.  The receiver that has the highest "minimum" audio level will be the one that is weaker.
  • Compare total loudness.  As it turns out, as a signal gets weaker, the noise gets added to the audio which means that if you look at the total amplitude of the two signals, the one that's louder overall (that is, there's the audio plus noise) will be the one that is weaker.
Comment: 
One can also look at the level of ultrasonic noise from the discriminator, but this is not easily done on sites connected only via a voice-bandwidth audio link and may be discussed in a later blog entry.
For a number of reasons, we chose the second method for our voting system.

It makes the job a bit easier if one looks only at the higher-frequency audio - say, that above about 2 kHz - as this has less speech energy in it overall, yet the noise will increase at the high frequencies of the de-emphasized audio just as readily as it will at the lower frequencies.  By "looking" only at these higher frequencies it becomes a bit easier to ignore the voice energy when trying to make comparisons of quality between multiple channels of the same audio.

There are some complications, however:

As you can imagine, no matter what method of voting you pick, it's important that all of the audio sources are as identical to each other as possible in terms of amplitude (loudness) and frequency response.  Consider the following example.
  • One receiver is louder than the other due to a misadjustment.  The louder receiver - even if it has a perfectly good signal - will look "worse" than a quieter one since more total audio energy will be detected from it.  In other words, compared to the the other, quieter receiver, the loud one will be considered noisier.  Because of this, the voter will "prefer" the quieter signal, even if it is a bit noisier.
  • One receiver has better "highs" than the other.  Since the noise from a weak signal will readily appear in the "highs", if two equally-noisy signals appear at once, the receiver with the stronger "highs" will be considered the worse one and the voter will prefer the other signal.  Since our system looks at the audio above 2 kHz, a receiver with extra "highs" makes things even worse!
When we first installed the voter, we had all of these problems, but we expected that we'd have to tweak a few things, but several things caught us off-guard:

  • The first one was that the "local" receiver was connected to the voter via copper wire, while the other receiver was connected via a UHF radio link.  The local receiver had better "highs" in its audio than the receiver on the UHF radio link and the "highs" in the voices of the users on the local receiver caused the voter to "think" that the signal was worse than it really was and it would jump back-and-forth while people were talking.
  • Due to a design flaw in the local receiver it was discovered that it would start to clip if the received signal's deviation was greater than about +/-3 kHz.  Interestingly, this flaw had gone unnoticed in the 30 years that this receiver had been used because no-one had looked for it, and it really didn't sound that bad since the transmitter removed the speech harmonics, anyway.  Coupled to this was the fact that pre-emphasized audio - common on our VHF and UHF bands - boosts the highs as compared to the lows, further masking the clipping.  With all of that distortion, the voter was "seeing" plenty of audio energy above 2 kHz and voting "away" from it in favor of the receiver connected via the UHF radio link.
The first problem required that we put a low-pass filter on the audio from the local receiver to make it "look" like the audio coming across the UHF link and for this, a filter was installed that scraped off the audio above about 3 kHz.

The second problem - the receiver distorting - was a bit trickier.  Once on the workbench, I noticed that the clipping was asymmetrical and I traced it to an emitter-follower audio stage coupling from the discriminator chip with insufficient headroom, trying to go "below" ground.  Poking around with an oscilloscope, I noticed that the input signal to this emitter-follower stage was "clean", so I modified it by turning it "upside-down" and using a PNP with its collector connected to the ground side instead of an NPN with its collector connected to the V+.  Doing this moved its clipping threshold "upwards", toward the V+ supply instead of ground.

That problem solved, I then noticed that I still couldn't go above about +/- 3 kHz deviation without significant distortion - but this time I traced it down to the 10.7 MHz IF crystal filters.  As it turned, one or more of these had gone bad and the filtering was no longer "flat" across the required 15 kHz IF bandwidth of this single-conversion receiver.

Fortunately - because of another project - I had on hand some extra 10.7 MHz crystal filters and I was able to replace those in the receiver and nicely flatten out the response.  The ultimate result was that the receiver could accept about +/-7 kHz of deviation modulated with a 1 kHz tone before it started to distort badly.  The measured IF bandwidth was now about 16 kHz at the -3dB points and much more than 20dB down at 20 kHz.

Re-installing the receiver, the audio levels from the remote receiver (via the UHF link) and the local receiver were very carefully matched and the voter behaved a bit better - but it was still favoring the "remote" receiver slightly.  Fortunately, when I designed the voter I included a number of software parameters that could be tweaked and I was able to "bias" the voter slightly toward the local receiver.

The voting controller:

Figure 2:
The main voter board.  As you can see, it is all hand-wired on
glass-epoxy prototyping board.
Click on the image for a larger version.
The voter itself is homebrew and uses a PIC18F4620 processor at its heart.  Capable of accepting up to 8 receivers, it has two voting channels:  The "current" receiver - the one that is being selected for on-air, and the "other" channel that is being compared to the on-air receiver.


If there is just one receiver active, the choice is simple:  Select it - no voting required!

If there are two receivers active they are compared against each other, the "better"one being put on-air and the worse one on the "other" channel:  If, at any time the signal on the "other" receiver gets to be better of quality than the one that is on-air, they flip positions.

If more than two receiver go active at the same instant it will grab the lowest-number receiver first and then compare, one-at-a-time, the quality of the other receivers against it.  If it finds that one of these other receivers has a better signal, it will put that receiver on the air and the process repeats itself with the processor constantly seeing if any of the other receivers have a better signal than the one that's currently on-air.

In the audio chain of the voter is a digitally-programmable potentiometer that is used to set the gain of each selected receiver (on both the main, on-air channel and the "other" channel) to the levels that allow the audio of each receiver to be perfectly matched.  There is also a "phase selector" switch that allows either a 0 or 180 degree phase change of the receiver to account for the fact that there may be an audio inversion somewhere earlier in the audio chain.

Both the selected "on-air" and the "other" receiver are passed through a 2 kHz high-pass filter which then goes to a rectifier circuit, the result being that a DC voltage is produced that is proportional to the amount of audio energy.  While some of the energy above 2 kHz is going to be voice energy, some of it will also be the added noise on a weaker signal, so that "noisy" channel (e.g. the one with the poorer signal) will have a higher voltage than the other.  The two voltages are digitized by the computer and used to make the decision as to which receiver has the better signal.

Cleaning up the squelch noise:

One issue with using a link receiver for connecting receivers for voting is the fact that if there's a "choppy" signal, the remote receiver's squelch will constantly open and close - but how do you convey that fact to the voter?

One way is to simply turn the UHF transmitter on and off and follow receiver squelch, but this gets a bit messy, particularly since there will be a burst of noise every time that happens (e.g. the "ker" in "kerchunk"!)

To avoid this, the instant the squelch of the remote receiver closes, a 3.2 kHz "voting tone" is sent down the link.  At the voter, this tone is detected and treated in the same way as dropping of the link transmitter and this causes a "squelch" indication from that remote receiver to show that the input signal has gone away.  After the tone is detected, the link transmitter can shut off and that extra "ker" (e.g. burst of noise) won't ever be heard by the user!

This tone also has another purpose:  Since it is a very strong 3.2 kHz tone it will be intercepted by the voter's noise detector as a full-scale indication of "bad signal noise" and the voter will instantly "see" it as a signal of inferior quality and jump away from it in favor of another signal, if available.

Other circuits:

In order to meet FCC rules, the UHF link transmitter must occasionally ID and this is done using a 2.44 kHz tone frequency, a frequency above most of the audio content.  2.44 kHz notch filters are used in front of the tone detector (but NOT in the audio path to the audio output of the voter) in each of the voter's channels (e.g. the one that is on-air, and the "other" one) to remove the link IDer and keep it from affecting the voting as well as a notch filter to remove the 3.2 kHz "voting tone" that is sent on the UHF link.  If the link IDs with no-one talking, the 3.2 kHz voting tone will already be on, keeping an "open squelch" indication from being passed to the voter and prevent that ID from even keying up the repeater.  If an ID happens to occur while someone is talking through the voter, there's no harm as the pitch of the ID is fairly high and most people don't ever notice it!
Figure 3:
Inside the voter's die-cast metal box with the circuit board removed.
All input/output signal lines go through feedthrough capacitors
and ferrites to remove any RF energy that might be coupled
onto them - an absolute necessity since the repeater site
has extremely high levels of RF energy!
Click on the image for a larger version.


Another circuit an 8-channel multiplexed input that is very rapidly scanned to determine which COS (squelch) output lines from the receivers are active, this being done so that the voter knows which receivers are actually active!  The voter also has the capability of producing "courtesy beep" tones which are used to identify the various remote receivers by pitch allowing users to determine into which a particular user is being received.  Since most of our users come across the main receiver, this one doesn't have a beep!

The voter - like the disciplined oscillator - has an RS-485 bus on it which allows it to be configured via a serial port as well as be queried and configured remotely.  As it turns out, one can kludge an RS-485 interface to talk to most RS-232 ports by using just one of the receive/transmit lines and this is brought out on a DE-9 front-panel connector.  In this way, one can look at the configuration of the voter - even make adjustments - while on-site as well as talk to any other device that is also hanging on the RS-485 bus!

Finally, the voter has 16 front-panel LEDs, 8 of which indicate which receiver is (or recently was) active while the other 8 LED indicate the various states of the hardware for monitoring and diagnostic purposes.


Final comments:

This voter was installed in October of 2009 and has been in continuous service ever since.  In the first month, the code was tweaked slightly to allow more-detailed tweaking of the noise detection algorithm to minimize the likelihood of "false voting" and to permit one receiver to be favored slightly more than the other.  The only "major" change was to add a minimum "dwell" time to the voting - that is, once a particular receiver was selected, it had to stay there for a minimum amount of time before another receiver was allowed to be selected unless, of course, that receiver dropped out!

The only hardware tweak was increasing the gain of the noise detectors to allow the voter to better-determine the relative quality of signals that were already nearly "full-quieting":  Before doing this the voter couldn't tell the difference between signals that were better than about 18dB quieting, but now this has been extended to about 25-27dB quieting - a noise level below that which most users even notice!

[End]

This page stolen from ka7oei.blogspot.com