Sequencing the transition from receive to transmit and back again in a safe way.

Design Intent

Listening for very weak signals refected back from the moon requires some very sensitive radio equipment, with a very good low-noise front-end. This is usually acomplished by using a tuned low-noise rf preamplifier (LNA) ahead of the radio itself.
So far, so good. But what about bypassing the LNA when the radio is transmitting? It turns out that most radios do have an externally accessible TX signalling line to allow external equipment to be switched on or off for transmit. What they don't have is any guard time. So as the TX signal line is asserted, rf is already making its way out of the radio to the output of our fancy preamplifier.

A sure way to pop the sensitive GaAsFET in the LNA!

Hence this project. A simple bit of hardware to sequentially enable/disable other bits of hardware in such a way that no damage can be inflicted by the inadvertant random button pressing of a distracted user - me, that is!

Hardware Design

A quick google search will show you that designs for such a sequencer are legion, from the sublimely simple to the unbelievably complex.
My version sits somewhere in between. I used a microcontroller to allow for some more precise timings between states (as compared to an R-C timing circuit), but moreover to allow individual states to be bypassed without changing the sequencing timings.
This makes the sequencer more flexible in use.
The ATMEGA16 microcontroller was chosen for this project. A simple low pin count micro with more than enough performance to do the job, and resorce to spare for any future additions.
The sequencer hardware is kept quite simple. A "transmit request" signal input (or Press To Talk, PTT) from the radio is used to trigger the sequencer Finite State Machine. The TS2000 has an external Automatic Level Control (ALC) line input, which is used here as a transmit inhibit line by the sequencer.
In operation this works really well, except for the (rather long) release time constant of the ALC in the radio - it takes around 1.5 seconds from the time that TX Inhibit is released to full output power of the radio.


Microcontroller Schematic

Relay Schematic

State Diagram

This is the State diagram od the sequencer logic.

Front Panel


Back Panel

One project where labelling the back panel is more important than the front!

Software Design

The software is simplicity itself. Two state vatiables are maintained, which hold the key to moving between states:
enum {rx_state,pa_state, ptt_state} Current_State, Next_State;

Once these states are defined, all that is then needed is a big switch statement, and some extra logic to decode optional settings. A simple millisecond timer is used as the master clock to derive all other timings for state transitions, key debounce reads etc.

The most interesting aspect of the software design turned out to be the switch debouncing. I spent quite a lot of time on this, as I wanted to come up with something which is simple, would work well and be useful in other projects.

I ended up using a variation of a "vertical stack counter" for my switch debounce. It effectively uses 2 bytes to debounce upto 8 inputs, by adding them "vertically". So 2 8-bit bytes become 8 2-bit variables.

Some of the nifty features of this approach are:

  • Debounce up to 8 keys simultaenously.
  • Very small code footprint.
  • No timers are tied up for debouncing.
  • Debounced state is static.
  • Debounced keys may be read individually or in a group.
  • Sustained "key down" events may be read without affecting the debounced state.

The idea is to call DebounceInputs() every so often, which builds up a byte of DebouncedKeys. The debounced keys may be read at any time by calling GetInputs(key_mask), where key_mask is the key that you wish to read.

//	Debounce inputs
void DebounceInputs(void){
	static uint8_t Count0 = 0xFF, Count1 = 0xFF;	// 8 * 2bit counters
	uint8_t i;

	i = ~PINA^DebouncedKeyState;			// read keys (low active)
	Count0 = ~( Count0 & i );			// reset or count Count0
	Count1 = Count0 ^ (Count1 & i);			// reset or count Countt1
	i &= Count0 & Count1;				// count until roll over?
	DebouncedKeyState ^= i;				// then toggle debounced state
	DebouncedKeys |= DebouncedKeyState & i;		// 0->1: key press detect

//	Read Key inputs
unsigned char GetInputs(unsigned char key_mask){
  ATOMIC_BLOCK(ATOMIC_FORCEON){				// read and clear atomic !
    key_mask &= DebouncedKeys;				// read key(s)
    DebouncedKeys ^= key_mask;				// clear key(s)
  return key_mask;

A Sustained keypress may be read simply by looking at its current state and comparing it with its state in DebouncedKeys, to ensure it has stopped bouncing:

//	Read PTT input
void GetPTT(void){	
    if((portNr(PTTin) & DebouncedKeys) && (!portbitInputStatus(PTTin))){
        flag.PTT_asserted = 1;
	if((portNr(PTTin) & DebouncedKeys) && (portbitInputStatus(PTTin))){
        flag.PTT_asserted = 0;

Another fun project which has now been working well for over a year, without missing a beat and (most importantly) without anymore burnt FETs!


1296MHz Activities
26/06/16 Antenna Improvements.
Moon Tracker Ver 2
23/06/16 A new version.
1296MHz Activities
29/09/15 Build a small dish.
26/07/15 Low-noise Preamplifier Design.
1296MHz Activities
19/04/15 Power Amplifier Design.
1296MHz Activities
13/01/15 Design and build a tower for 3m parabolic dish.
30/09/14 LCD monitor for my Thunderbolt GPSDO.
02/08/14 A home-made Noise Figure Meter.
Moon Tracker Update
09/04/14 New rotator and better position feedback sensors added.
1296MHz Antenna
09/02/14 Begin construction of a 1296MHz feed horn for the 3m dish.
1296MHz Activities
28/01/14 After success at 144MHz, operation at 1296MHz is planned.
Moon Tracker Update
11/09/13 Added a Background Sky Temperature calculation into the Moon Tracker.
Moon Tracker Update
28/08/13 Just Added some software limits to rotation of motors.
Roger Beep installed
09/08/13 Added a Roger Beep to my radio.
Andy's Website
06/05/13 Start build of website.


Andy, VK3ANX
Yarra Valley, Australia