Arduino Fox

Arduino Fox

This project is largely based off VK5FSKS and WT4Y’s design, with a few modifications. I only intend for the Fox to be in use for a few hours at a time. Therefore, I pulled 7v DC power from the Baofeng UV-5R battery to power the Arduino Mega using a barrel connector. You could use a smaller Arudino for this project. I used the Mega as I had an extra laying around. 

I also modified the Arudino code a bit. I was unable to identify the ‘Aussie Folk Song’.  I changed the melody to A-Tisket A-Tasket, which is in the public domain. I didn’t care for the melody playing on every loop iteration. Therefore, I made a new switch case which can be called by DTMF tone.  

Supply list includes:

Fritzing Diagram :

Arduino Code

*NOTE* The DTMF Library and Pitches.H are required. Both are attached at the bottom of this post.

/*Be Sure to Edit variables for beaconstring[] and idstring[] in code replacing "CALLSIGN" with your actual callsign
char beaconstring[] = "CQ CALLSIGN/FOX";
char idstring[] = "DE CALLSIGN";
*/
//DTMF controlled Fox
//DTMF 1 = Start Fox
//DTMF 2 = A-Tisket A-Tasket
//DTMF 7 = Fox Tx '73' in Morse
//DTMF 5 = Fox Tx 'Have you found me yet' in Morse
//DTMF 0 = Fox DISABLED

// Arduino controlled Fox Hunting Xmtr and / or Beacon 
// Code cobbled together from various sources


//Connections 
//Baofeng Mic/Headset cable
//-------------------------
//3.5mm Sleve (orange) to Relay Common
//3.5mm Ring (Red) to Arduino Pin6 (PWM)
//2.5mm Sleve (Blue) to Relay N/C (Normally Closed)
//2.5mm Tip (Green) to Arduino A0

//Relay
//Normally open to Relay GND
//Signal Pin to Arduino Pin7
//VCC to Arduino 5V
//GND to Arduino GND

// Pin 6 is the square wave output for the Morse Code
// Pin 7 is Push to Talk pin (low = PTT)
// A0 is the Analog Input for DTMF detection

#include <DTMF.h>
#include "pitches.h"

int sensorPin = A0;  //The following block used by DTMF
float n = 128.0;
float sampling_rate = 8926.0;
DTMF dtmf = DTMF(n, sampling_rate);
float d_mags[8];
char thischar;

int xmit = 1;  // if xmit = 0, don't transmit
int pause = 220;  // pause between transmissions, 22 = 1 second (approx)

// notes in the melody:
int melody[] = {
  NOTE_G4, NOTE_G4, NOTE_E4, NOTE_A4, NOTE_G4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_G4, NOTE_E4, NOTE_A4, NOTE_G4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 2, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2
};

#define PTT  7
#define BUZZER_PIN 6  // send music and cw out this pin
#define BUZZER_FREQUENCY 700  // cw pitch
char beaconstring[] = "CQ CALLSIGN/FOX";
char idstring[] = "DE CALLSIGN";
int randNumber;

char chartemp[4] ;
char incomingByte = 0;
//int morseOutput = 4; //Pin for receiving Morse output - attach LED to this pin
int interval = 60;   //length of time for one dot - basic unit of measurement;  one interval occurs between each dot or dash; dash is equivalent to 3 dots; 7 dots between words

String alphabet = "abcdefghijklmnopqrstuvwxyz1234567890/ ";
String ALPHABET = alphabet;

String morseCode[] = { 
    ".-", // 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
    ".----", // 1
    "..---", // 2
    "...--", // 3
    "....-", // 4
    ".....", // 5
    "-....", // 6
    "--...", // 7
    "---..", // 8
    "----.", // 9
    "-----", // 0
    "-..-.", // forward slash
    " "   //space character
};

void setup() {
  
  pinMode(PTT, OUTPUT);
  digitalWrite(PTT, LOW);
  Serial.begin(9600);
//  pinMode(morseOutput, OUTPUT);
  
  ALPHABET.toUpperCase();
  randomSeed(analogRead(0));  // in case random delays between 
                              // transmissions are used
}

void loop() {

//  randNumber = random(110, 440);      // remove comments to use random delays
//  pause = randNumber;                 // example is 5 to 20 second pause

Serial.println("BeginPause");
for (int x = 0; x < pause; x ++)  // while waiting between transmissions, look for DTMF
{
  Serial.println(x);
  dtmf.sample(sensorPin);
  dtmf.detect(d_mags, 506);
  thischar = dtmf.button(d_mags, 1800.);
  
  if (thischar) {  // decide what to do if DTMF tone is received
    switch (thischar) {
      case 49:  // the number 1
        xmit = 1;  // set the flag to enable transmissions
        break;
      case 50: //number 2
         digitalWrite(PTT, HIGH);
         delay(2000);
        // play a little melody
  for (int thisNote = 0; thisNote < 12; thisNote++) {
    // to calculate the note duration, take one second
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(BUZZER_PIN, melody[thisNote], noteDuration);
    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(BUZZER_PIN);
  }
        digitalWrite(PTT, LOW);
        delay(2000);
        break;
        case 53:  //number 5
        digitalWrite(PTT, HIGH);
        delay(2000);
        sendLetter('h');
        sendLetter('a');
        sendLetter('v');
        sendLetter('e');
        sendLetter('y');
        sendLetter('o');
        sendLetter('u');
        sendLetter('f');
        sendLetter('o');
        sendLetter('u');
        sendLetter('n');
        sendLetter('d');
        sendLetter('m');
        sendLetter('e');
        digitalWrite(PTT, LOW);
        delay(2000);
        break;
      case 54:  //number 6
        digitalWrite(PTT, HIGH);
        delay(2000);
        for (int i = 0; i < sizeof(idstring); i++){
          sendLetter(idstring[i]);
        }
        digitalWrite(PTT, LOW);
        delay(2000);
        break;
      case 55:  //number 7
        digitalWrite(PTT, HIGH);
        delay(2000);
        sendLetter('7');
        sendLetter('3');
        digitalWrite(PTT, LOW);
        delay(2000);
        break;
      default:  // any other number, turn off transmissions
        xmit = 0;  // set the flag to disable transmissions
      break;
    }
  }
  delay(1);
}
Serial.println("PauseEnd");

if (xmit == 1)
  {
  digitalWrite(PTT, HIGH);
  delay(2000); // delay 2 seconds after PTT to account for race condition

  for (int i = 0; i < sizeof(beaconstring); i++){
    sendLetter(beaconstring[i]);
    }

  delay(500);
  digitalWrite(PTT, LOW);  // drop the PTT and wait a while

  }
}

// End of Loop()
// Functions follow

void sendLetter (char c) {
   int i;
   for (i = 0; i < alphabet.length(); i = i + 1) {
       if (alphabet[i] == c || ALPHABET[i] == c) {
           //Serial.print(c);
           sendMorseCode(morseCode[i]);
           return;
       }
   }
   if (c == '\n')
      Serial.println();
}

void sendMorseCode (String tokens) {
   int i;
   for (i = 0; i < tokens.length(); i = i + 1) {
       switch (tokens[i]) {
           case '-':
               sendDash();
               break;
           case '.':
               sendDot();
               break;
           case ' ':
               sendEndOfWord();
               break;
       }
   }
   morseOutputOff(2);
//   Serial.print(" ");
}

void sendEndOfWord() {
   morseOutputOff(4);
//   Serial.print("  ");
}

//basic functions - Morse code concepts  
void sendDot() {
   tone(BUZZER_PIN, BUZZER_FREQUENCY);
   morseOutputOn(1);
   noTone(BUZZER_PIN);
   morseOutputOff(1);
//   Serial.print(".");
}
void sendDash() {
   tone(BUZZER_PIN, BUZZER_FREQUENCY);
   morseOutputOn(3);
   noTone(BUZZER_PIN);
   morseOutputOff(1);
//   Serial.print("-");
}

//Low level functions - how the actions are accomplished
// n = number of intervals 
// interval is a fixed length of time determined at start, for example 200 milliseconds
void morseOutputOn (int n) {
//   example: morseOutputOn(1) means turn output on and keep it on for 1 interval 
//            morseOutputOn(3) means turn output on and keep it on for 3 intervals 
//   
//   digitalWrite(morseOutput, HIGH);
   delay(n * interval);
}

void morseOutputOff (int n) {
//   digitalWrite(morseOutput, LOW);
   delay(n * interval);
}

Tags: , ,

Leave a Reply

Your email address will not be published. Required fields are marked *