OOSMOS Morse Code Keyer Example
1 Introduction
2 Keyer on Arduino
2.1 Keyer on Arduino - Wiring Diagram
2.2 Keyer on Arduino - Code
3 Keyer on PIC32
4 Keyer on ChipKit
5 Keyer on Galileo
6 Keyer on MSP430
1 Introduction
2 Keyer on Arduino
2.1 Keyer on Arduino - Wiring Di...
2.2 Keyer on Arduino - Code
3 Keyer on PIC32
4 Keyer on ChipKit
5 Keyer on Galileo
6 Keyer on MSP430

1 Introduction

This example is an implementation of a Morse code keyer, useful to Ham Radio CW operators using Iambic paddles (see Figure 1) to send Morse code.
CW (Morse code) is formed with DIT and DAH sounds (or, if you prefer, dots and dashes). A Dit is a short tone and a Dah is a long tone. An iambic key has two paddles. One paddle generates the Dah sound and the other the Dit sound. (In the U.S., the Dah paddle is usually the right-hand paddle.) With the assistance of a microcontroller and software like in this example, an operator, using a combination of taps and holds of these paddles, can form Morse code characters.
For example, the letter B (DahDitDitDit in Morse code) is formed by tapping the Dah paddle immediately followed by a press-and-hold of the Dit paddle. Dits are repeatedly generated by the software until the operator releases the Dit paddle. Thus, with only two paddle depressions, we can generate a perfectly formed B.
Figure 1. Iambic Paddles
Here is a video of an operator using iambic keyer paddles.
This keyer example uses the generalized keyer class in the Classes directory and is documented here.

2 Keyer on Arduino

Using our portable keyer object, we will now write the small bit of code specific to the Arduino. This example uses the Arduino Uno, but all Arduinos (that we know of) will run this example.

2.1 Keyer on Arduino - Wiring Diagram

Figure 2 is a Fritzing wiring diagram of the components. We have 3.5mm jack to accommodate a stereo plug for the keyer. The Dit paddle goes to pin 6 and the Dah paddle to pin 7. The buzzer is hooked to pin 13, which, on the Uno, is the pin that is hooked to the built-in, on-board LED, so when the speaker sounds, the LED also lights up.
The Arduino has built-in pull up resistors capability but we don't use it. Because not all boards have this capability, we use external resistors so that we can make a single breadboard that works across all devices.
Figure 2. Arduino Wiring Diagram

2.2 Keyer on Arduino - Code

This is the main program for an Arduino target where we implement the Arduino-standard setup and loop functions. In setup, we create three pin objects; two for the digital inputs for the Dit and Dah paddles as well as one for the "speaker" output. (This does not really drive a speaker, rather a piezoelectric buzzer.)
Once the pin objects are created, we pass them to the keyer constructor. Because the keyer object creates a State Machine object that automatically registers the object with OOSMOS, we can then call oosmos_RunStateMachines in the loop function and the keyer state machine will be run repeatedly.
1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[GPLv2]
 
#include "oosmos.h"
#include "pin.h"
#include "keyer.h"
#include "prt.h"
 
unsigned long prtArduinoBaudRate = 115200;
 
extern void setup()
{
pin * pDitPin = pinNew(6, pinIn, pinActiveLow);
pin * pDahPin = pinNew(7, pinIn, pinActiveLow);
pin * pSpeakerPin = pinNew(13, pinOut, pinActiveHigh);
 
const int WPM = 17;
 
keyerNew(pDahPin, pDitPin, pSpeakerPin, WPM);
}
 
extern void loop()
{
oosmos_RunStateMachines();
}
Keyer on Arduino - KeyerExample.ino

3 Keyer on PIC32

Using the portable keyer object, we can write the small bit of code specific to the PIC32 Starter Kit. The PIC32 architecture has a different way of addressing pins than does, say, an Arduino, but the pin class abstraction hides these details such that the same keyer object can be portable to all microcontrollers.
Note that the PIC32 needs to have some specialized #pragma directives to properly setup the chip. We also have to tell the run-time environment that the clock speed is 80 MHz (see line 32 of main.c).
We use the PIC32 Starter Kit board for this demo along with the I/O Expansion Board headers J10 to gain access the processor's pins. (See figure 3.)
Figure 3. PIC32 Starter Kit with I/O Expansion Board
The documentation related to which pins
Figure 4. I/O Expansion Board, Header J10
Figure 5. PIC32 Wiring Diagram
The PIC32 does not have a setup and loop structure like the Arduino-family does. Instead, we simply implement the main function and call oosmos_RunStateMachines in a loop once all the pin and keyer objects have been created.
There are a variety of PIC32 Starter Kits. When you open up any of our PIC32 projects with MPLAB X, you may need to change the processor type to get a clean compile.
1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[GPLv2]
 
#include "oosmos.h"
#include "pin.h"
#include "keyer.h"
 
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
 
extern int main(void)
{
oosmos_ClockSpeedInMHz(80);
 
pin * pDahPin = pinNew(IOPORT_C, BIT_1, pinIn, pinActiveLow);
pin * pDitPin = pinNew(IOPORT_C, BIT_2, pinIn, pinActiveLow);
pin * pSpeakerPin = pinNew(IOPORT_C, BIT_3, pinOut, pinActiveHigh);
 
const int WPM = 15;
 
keyerNew(pDahPin, pDitPin, pSpeakerPin, WPM);
 
while (true) {
oosmos_RunStateMachines();
}
}
Keyer on PIC32 - main.c

4 Keyer on ChipKit

Using the portable keyer object, we can write the small bit of code specific to the ChipKit. Because the ChipKit is Arduino pin compatible, we can use the same pin descriptions as the Arduino example.
Figure 6. ChipKit Wiring Diagram
1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[GPLv2]
 
#include "oosmos.h"
#include "pin.h"
#include "keyer.h"
#include "prt.h"
 
unsigned long prtArduinoBaudRate = 115200;
 
extern void setup()
{
pin * pDitPin = pinNew(6, pinIn, pinActiveLow);
pin * pDahPin = pinNew(7, pinIn, pinActiveLow);
pin * pSpeakerPin = pinNew(13, pinOut, pinActiveHigh);
 
const int WPM = 17;
 
keyerNew(pDahPin, pDitPin, pSpeakerPin, WPM);
}
 
extern void loop()
{
oosmos_RunStateMachines();
}
Keyer on ChipKit - KeyerExample.ino

5 Keyer on Galileo

Using the portable keyer object, we can write the small bit of code specific to the Galileo. Because the Galileo is Arduino pin compatible, we can use the same pin descriptions as the Arduino example.
Figure 7. Galileo Wiring Diagram
1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[GPLv2]
 
#include "oosmos.h"
#include "pin.h"
#include "keyer.h"
#include "prt.h"
 
unsigned long prtArduinoBaudRate = 115200;
 
extern void setup()
{
pin * pDitPin = pinNew(6, pinIn, pinActiveLow);
pin * pDahPin = pinNew(7, pinIn, pinActiveLow);
pin * pSpeakerPin = pinNew(13, pinOut, pinActiveHigh);
 
const int WPM = 17;
 
keyerNew(pDahPin, pDitPin, pSpeakerPin, WPM);
}
 
extern void loop()
{
oosmos_RunStateMachines();
}
Keyer on Galileo - KeyerExample.ino

6 Keyer on MSP430

Using the portable keyer object, we can write the small bit of code specific to an MSP430F5529 LaunchPad board.
Fritzing does not have a part for the MSP430F5529 LaunchPad board, so we created a reasonable representation of the board's headers in order to show the connections.
MSP430 Wiring Diagram
The pin designations for the MSP430F5529 LaunchPad board are not the same as Arduino Uno pins. (See lines 29-31.)
1
22
23
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[GPLv2]
 
#includes...
 
extern void setup()
{
pin * pDitPin = pinNew(P1_2, pinIn, pinActiveLow);
pin * pDahPin = pinNew(P1_3, pinIn, pinActiveLow);
pin * pSpeakerPin = pinNew(P1_4, pinOut, pinActiveHigh);
 
const int WPM = 15;
 
keyerNew(pDahPin, pDitPin, pSpeakerPin, WPM);
}
 
extern void loop()
{
oosmos_RunStateMachines();
}
Snippet 1. Keyer on MSP430 - KeyerExample.ino
Copyright © 2014-2016  OOSMOS, LLC