Project tutorial
Auto-Keyer for Radio "Fox Hunting"

Auto-Keyer for Radio "Fox Hunting" © GPL3+

Attach an amateur radio to this and the radio will regularly identify itself so others can use their direction finding skills and locate it.

  • 2,491 views
  • 2 comments
  • 5 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)
4966285
Solder Wire, Lead Free
Amateur Radio

About this project

Ham radio enthusiasts often try to keep their radio direction finding skills sharp by practicing to find a radio hidden somewhere distant (called a "fox"). These skills are useful for finding equipment and people with a radio transmitter and need to be found.

This project takes an Arduino and uses it to key up the radio to transmit and then sends the station ID (the call sign of ham radio operator) using Morse code. A long tone is then sent. While transmitting, the radio signal's location can be pinpointed.

The Arduino keys up the radio, sends the station ID and then a long tone

I had my very first "fox hunt" using radio direction finding at the 2011 ARRL Teacher's Institute and loved it (even though our team accidentally found the wrong "fox"). It seemed like it would make a great activity for the middle school students I teach in my science classes. Unfortunately, building one seemed either too complicated or cost more than I was willing to spend.

Recently, however, I realized that with an inexpensive 2 meter radio and a programmable microprocessor (like the Arduino), I could make my own "fox" for very little cost, and have a fun summer learning project.

For this project, I used a Baofeng UV-3R radio since it's inexpensive (and I'm not using it any more), and an Arduino Uno. I'm assuming using a different radio with a different jack would require similar steps to test the jack and microphone, but the circuit and Arduino sketch would be the same except for the radio call sign of the operator.

Note: The schematic is less complicated than it looks. The.01 microfarad capacitors were added to prevent the circuit from picking up RFI (radio frequency interference) when transmitting. Without them, the Arduino did unusual and inconsistent things (often restarting) when the radio transmitted so close to the circuit. The other capacitor is to smooth out the Arduino's square wave and make it a sine wave so it sounds better.

Code

Fox Hunting Radio KeyerArduino
The Arduino that keys up the radio to transmit and sends the Morse code to identify itself.
/*By Nelson Farrier
  Key up radio and send tone
  Keys up Baofeng UV-3R radio by turning on and off the relay, then ID's and and sends a 5 second tone.
 */
      
// Pin 12 is connected to a relay.
// Pin 13 is connected to a tone circuit.

//   modified from: Mike Myers (http://mikemyers.me)  @netnutmike
//   Let's Make It Episode 6 (http://tech-zen.tv/index.php/shows/let-s-make-it/episodes/59-sensor-fun-with-arduino-1-massive-failure-but-4-successes-let-s-make-it-episode-6)
//   define the morse code for the alphabet and numbers

char* letters[] = {
  ".-",     // A
  "-...",   // B
  "-.-.",   // C
  "-..",    // D
  ".",      // E
  "..-.",   // F
  "--.",    // G
  "....",   // H
  "..",     // I
  ".---",   // J
  "-.-",    // K
  ".-..",   // L
  "--",     // M
  "-.",     // N
  "---",    // O
  ".--.",   // P
  "--.-",   // Q
  ".-.",    // R
  "...",    // S
  "-",      // T
  "..-",    // U
  "...-",   // V
  ".--",    // W
  "-..-",   // X
  "-.--",   // Y
  "--.."    // Z
};

char* numbers[] = {
  "-----",   // 0
  ".----",   // 1
  "..---",   // 2
  "...--",   // 3
  "....-",   // 4
  ".....",   // 5
  "-....",   // 6
  "--...",   // 7
  "---..",   // 8
  "----."    // 9   --- end of 1st segment of borrowed code from Mike Myers
};

int relay = 12;
int TonePin = 13; 
int frequency = 1000; // frequency of tone

int dotDelay = 70;      // duration of the dot in morse code, this is also the time between the dots and dashes
int charDelay = 500;    // duration of the wait between letters for Farsnworth method
int wordDelay = 1100;   // duration of the wait between words for Farsnworth method
int cycleDelay = 15000;  // HALF the duration because the largest value is 16383

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(12, OUTPUT);     
  pinMode(13, OUTPUT);     
  delay(2000);  // initial delay after powering on
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(relay, HIGH);   // turn the relay on (HIGH is the voltage level)
  delay(1000);                 // wait for a second
  
  SendText("NF7Z FOX");  

  delay(1000);                 // wait for a second

  tone(TonePin, frequency);    // send 7 sec tone
  delay(7000);
  noTone(TonePin);
  
  delay(10000);                 // 10 seconds transmit w/o tone

  digitalWrite(relay, LOW);    // turn the relay off by making the voltage LOW

  delay(cycleDelay);           // wait for cycle time (because the largest value is 16383)
  delay(cycleDelay);           // wait for cycle time
}

//=================================================================
//
// modified from: Mike Myers (http://mikemyers.me)  @netnutmike
// Function: morseCodeSequence
//
// Input: Character Array of Dots and Dashes to be sent
//
// Description:
//      This function takes as input an array or "." and "-" and
//      calls dotOrDash for each item in the array.
//
//      At the end of the sequence, there is a delay of 3 times 
//      the dot duration.
//=================================================================

void morseCodeSequence(char* sequence)
{
   int i = 0;

   // Loop for each element in the array
   while (sequence[i] != NULL)  
   {
      dotOrDash(sequence[i]);     // Send out the dot or dash
       i++;                        // Increment to the next element in the array
   }
   delay(charDelay);            // gap between letters
}
//=================================================================
//
// Function: SendText
//
// Input: Character Array of text in English
//
// Description:
//      This function takes text as input and sends Morse code for each letter.
//      There then is a pause after each letter.
//
//=================================================================

void SendText(char* MorseCodeLetters)
{
   int i = 0;
   char ch;

   // Loop for each element in the array
   while (MorseCodeLetters[i] != NULL)  
   {
    ch = MorseCodeLetters[i];
    // Is it lowercase letter?
    if (ch >= 'a' && ch <= 'z')
    {
      morseCodeSequence(letters[ch - 'a']);
    }
    else if (ch >= 'A' && ch <= 'Z')    // Uppercase Letter
    {
      morseCodeSequence(letters[ch - 'A']);
    }
    else if (ch >= '0' && ch <= '9')    // Number
    {
      morseCodeSequence(numbers[ch - '0']);
    }
    else if (ch == ' ')                // Space (wait for 4 times dotDelay
    {
     delay(wordDelay);      // gap between words  
    }
    else {
    }
    i++;         // Increment to the next element in the array
   }
   delay(charDelay);            // gap between letters
}

//=================================================================
//
// Function: dorOrDash
//
// modified from: Mike Myers (http://mikemyers.me)  @netnutmike
// Input: Character that should be either a dot or a dash
//
// Description:
//      This function first turns on the output then looks to see 
//      if the character is a "." and if so delays the dotDelay.
//      
//      If the character is not a "." then the routine assumes it
//      is a "-" and keep the output high for 3 times the length of
//      dotDelay.  This could be improved by making sure the 
//      character is a "-" but for most cases it would not matter.
//
//      After the delay time the pin is taken low turning off the 
//      tone.
//
//      Then it delays for one dotDelay time so the dots and dashes
//      do not run together.
//=================================================================

void dotOrDash(char dotOrDash)
{
  tone(TonePin, frequency);
  if (dotOrDash == '.')
  {
    delay(dotDelay);           
  }
  else // must be a -
  {
    delay(dotDelay * 3);           
  }
  noTone(TonePin);
  delay(dotDelay); // gap between flashes
}

Schematics

Schematic for Fox Hunt Keyer
Schematic for the fox hunt radio's keyer
Schematic i8y3r3k3x3

Comments

Author

Nfarrier
nfarrier
  • 3 projects
  • 1 follower

Additional contributors

Published on

June 30, 2019

Members who respect this project

Puzzleofmesmall dubmpckgbiDefaultDefaultDefault

and 3 others

See similar projects
you might like

Similar projects you might like

Fox Advisor

Project tutorial by Celia Garrido Hidalgo

  • 3,675 views
  • 2 comments
  • 13 respects

Android App-Based Home Automation System Using IOT

Project tutorial by Team Autoshack

  • 37,508 views
  • 20 comments
  • 111 respects

Arduino Project: Burglar Zone Input Tester

Project tutorial by Cezarjar

  • 1,544 views
  • 2 comments
  • 9 respects

"Mini-Vintage" Internet Radio

Project tutorial by Guilherme Schallenbach

  • 32,115 views
  • 24 comments
  • 146 respects

Arduino Clone Breeding T-Rig

Project tutorial by Madao

  • 5,404 views
  • 0 comments
  • 32 respects

Personal Home Assistant

Project tutorial by 3 developers

  • 4,003 views
  • 0 comments
  • 26 respects
Add projectSign up / Login