Tom,
This form further down this forums postings.
/* =============================================================================
* File - morse.pde
* -----------------------------------------------------------------------------
* Code formatted assuming 80 characters screen width
*
* Naming Convention
* e_ enumeration
* g_ global
* k_ constant
*
* dt delta time
*/
/* =============================================================================
* -----------------------------------------------------------------------------
*/
#include "WProgram.h"
#include <ctype.h>
/* =============================================================================
* -----------------------------------------------------------------------------
*/
struct encoding_t
{
const char ascii;
const unsigned short encoding;
};
/* =============================================================================
* -----------------------------------------------------------------------------
*/
enum { e_EOS = 0, e_DOT, e_DASH, eMASK };
/* =============================================================================
* -----------------------------------------------------------------------------
*/
static const encoding_t morse_encodings[] =
{
// a string of 2-bit values encode the morse sequence, LSb -> MSb
// 00 end-of-sequence
// 01 '.'
// 10 '-'
// 11 unused
// --- Numeric
{ '0', 0x02AA } // "-----"
, { '1', 0x02A9 } // ".----"
, { '2', 0x02A5 } // "..---"
, { '3', 0x0295 } // "...--"
, { '4', 0x0255 } // "....-"
, { '5', 0x0155 } // "....."
, { '6', 0x0156 } // "-...."
, { '7', 0x015A } // "--..."
, { '8', 0x016A } // "---.."
, { '9', 0x01AA } // "----."
// --- Alphabetic
, { 'A', 0x0009 } // ".-"
, { 'B', 0x0056 } // "-..."
, { 'C', 0x0066 } // "-.-."
, { 'D', 0x0016 } // "-.."
, { 'E', 0x0001 } // "."
, { 'F', 0x0065 } // "..-."
, { 'G', 0x001A } // "--."
, { 'H', 0x0055 } // "...."
, { 'I', 0x0005 } // ".."
, { 'J', 0x00A9 } // ".---"
, { 'K', 0x0026 } // "-.-"
, { 'L', 0x0059 } // ".-.."
, { 'M', 0x000A } // "--"
, { 'N', 0x0006 } // "-."
, { 'O', 0x002A } // "---"
, { 'P', 0x0069 } // ".--."
, { 'Q', 0x009A } // "--.-"
, { 'R', 0x0019 } // ".-."
, { 'S', 0x0015 } // "..."
, { 'T', 0x0002 } // "-"
, { 'U', 0x0025 } // "..-"
, { 'V', 0x0095 } // "...-"
, { 'W', 0x0029 } // ".--"
, { 'X', 0x0096 } // "-..-"
, { 'W', 0x00A6 } // "-.--"
, { 'Z', 0x005A } // "--.."
// --- Punctuation
, { ',', 0x0A5A } // "--..--"
, { '.', 0x0999 } // ".-.-.-"
, { ':', 0x056A } // "---..."
, { '?', 0x05A5 } // "..--.."
, { '-', 0x0956 } // "-....-"
, { '/', 0x0196 } // "-..-."
, { '(', 0x09A6 } // "-.--.-"
, { ')', 0x09A6 } // "-.--.-"
// --- ARDUINO Windows IDE has problems with escaped ascii literals!
#if 0
, { '\'', 0x06A9 } // ".----."
, { '\"', 0x0699 } // ".-.--."
#endif
};
const int pin = 13;
/* =============================================================================
* -----------------------------------------------------------------------------
*/
int g_dtDot;
int g_dtDash;
int g_dtChar;
int g_dtWord;
/* =============================================================================
* -----------------------------------------------------------------------------
*/
static void dot()
{
digitalWrite(pin, HIGH);
delay(g_dtDot);
digitalWrite(pin, LOW);
}
/* =============================================================================
* -----------------------------------------------------------------------------
*/
static void dash()
{
digitalWrite(pin, HIGH);
delay(g_dtDash);
digitalWrite(pin, LOW);
}
/* =============================================================================
* -----------------------------------------------------------------------------
*/
static void blinkSequence(unsigned short encoding)
{
do
{
switch ( encoding bitand eMASK )
{
case e_DOT: dot(); break;
case e_DASH:dash(); break;
default: break;
}
encoding >>= 2;
if ( encoding ) { delay(g_dtDot); }
} while ( e_EOS != (encoding bitand eMASK) );
}
/* =============================================================================
* -----------------------------------------------------------------------------
*/
static void blinkCharactor(char ch)
{
const int cEntries = sizeof(morse_encodings) / sizeof(morse_encodings[0]);
for ( int i = 0; i < cEntries; i++)
{
if ( ch == morse_encodings[i].ascii )
{
blinkSequence(morse_encodings[i].encoding);
return;
}
}
}
/* =============================================================================
* -----------------------------------------------------------------------------
*/
void setTimings(int dt)
{
g_dtDot = dt;
g_dtDash = 3 * dt;
g_dtChar = 3 * dt;
g_dtWord = 7 * dt;
}
/* =============================================================================
* -----------------------------------------------------------------------------
* Any speed greater than 10-15 words per minute will be hard to read on an LED
*/
void setSpeedWordsPerMinute(int wpm)
{
#define WPM_MAX (150)
const unsigned long k_MPM = (60 * 1000); // millisec's per minute
const unsigned long k_DOT = 1;
const unsigned long k_DASH = 3;
const unsigned long k_INTRA_SEQ = 1;
const unsigned long k_INTRA_CHAR = 1;
const char standard[] = { "PARIS" };
// --- check and enforce words per minute boundries
if ( wpm < 1 ) { wpm = 1; }
if ( wpm > WPM_MAX ) { wpm = WPM_MAX; }
// --- count 'dot' length of 'standard' word
const char* ptr = standard;
unsigned long dpw = 0; // 'dot's per word
char ch;
while ( ch = *ptr++ )
{
const int cEntries = sizeof(morse_encodings) / sizeof(morse_encodings[0]);
for ( int i = 0; i < cEntries; i++)
{
if ( ch == morse_encodings[i].ascii )
{
unsigned short encoding = morse_encodings[i].encoding;
do
{
switch ( encoding bitand eMASK )
{
case e_DOT: dpw += k_DOT; break;
case e_DASH: dpw += k_DASH; break;
default: break;
}
encoding >>= 2;
if ( encoding ) { dpw += k_INTRA_SEQ; }
} while ( e_EOS != (encoding bitand eMASK) );
}
}
if ( *ptr ) { dpw += k_INTRA_CHAR; }
}
setTimings(k_MPM / (wpm * dpw));
}
/* =============================================================================
* -----------------------------------------------------------------------------
*/
void loop()
{
const char message[] = { "ARDUINO ROCKS" };
const char* ptr = message;
char ch;
while ( ch = *ptr++ )
{
blinkCharactor(((isalpha(ch)) ? toupper(ch) : ch));
delay(((' ' == *ptr) ? g_dtWord : g_dtChar));
}
// 3 SECONDS
const int dtMessageDelay = (3 * 1000);
delay(dtMessageDelay);
}
/* =============================================================================
* -----------------------------------------------------------------------------
*/
void setup()
{
pinMode(ledPin, OUTPUT);
setSpeedWordsPerMinute(25);
}