Monday 25 November 2013

Send morse code with an Arduino

Here is a very simple morse code sender, with at the moment hard wired text words to send. I hope to develop this to accept keyboard input and send it...

The circuit is very simple, a Piezo transducer is connected to pin 2, a LED to pin 7 and a push button to pin 8. Pushing the button sends the text "CQ CD DE M6KWH".

2013 11 25 15 25 31

// Morse sender

// pins
#define PIEZOPIN 2
#define BUTTONPIN 8
#define LEDPIN 7

// text array codes
#define DOT 0
#define DASH 1
#define SPACE 2
#define WORD 3

// text words
int CQ[] = {1,0,1,0,2,1,1,0,1,3};
int DE[] = {1,0,0,2,0,3};
int M6KWH[] = {1,1,2,0,1,1,1,1,2,1,0,1,2,1,1,0,2,0,0,0,0,3};

// sound frequency 1000Hz
// cycle time = 1000000/frequency(Hz) usec
#define CYCLE 1000

// dash = 3 dots, space = 3 dots, word = 7 dots
#define DOTTIME 150

void setup() {

  pinMode(BUTTONPIN, INPUT);
  pinMode(PIEZOPIN, OUTPUT);
  pinMode(LEDPIN, OUTPUT);
}

void loop() {

// wait for button pressed 
  while(digitalRead(BUTTONPIN) != LOW);

// send message words
  sender(CQ);
  sender(CQ);
  sender(DE);
  sender(M6KWH);

// finger still on button?
  while(digitalRead(BUTTONPIN) != HIGH);
  delay(100); // avoid button bounce
}

// send a word
void sender(int dida[]) {

  int x = 0; // array index

// send characters up to end of word
  while(dida[x] != WORD) {
   switch (dida[x]) {
    case DOT:
       sound(DOTTIME);
       delay(DOTTIME); // add after dot
       break;
    case DASH:
        sound(3 * DOTTIME);
        delay(DOTTIME); // add after dash
        break;
    case SPACE:
         delay(2 * DOTTIME);  // add for space
         break;
    }
    x++;
  }
  delay(6 * DOTTIME); // add   for word
}

// make sound at FREQ for time (msec)
void sound(long time) {

  long start;

// make the sound for time msec
  start = millis(); // read current time
  digitalWrite(LEDPIN, HIGH); // turn on LED

// loop until time has passed making sound
  while(millis() < start + time) {
    digitalWrite(PIEZOPIN, HIGH);
    delayMicroseconds(CYCLE/2);
    digitalWrite(PIEZOPIN, LOW);
    delayMicroseconds(CYCLE/2);
  }
  digitalWrite(LEDPIN, LOW); // turn off LED
}

No comments: