//-*-c++-*- // generate morse output // j. eric townsend // 15 Apr 2008 (did my taxes last week!) // // The ARRL double-cd is an excellent guide to learning the Morse // code, but I kinda forgot it due to not using it. I'm re-learning // morse code and wanted to see if I could learn it visually -- // looking at a blinking LED -- as well as audibly. // // it was pretty simple to crank out. My goal was to minimize code // size, so instead of a lookup table for letter->morse mappings I // just have a big switch statement with calls to functions that // generate dit/dash // const int wpm = 5; int ditLen = 0; // ms int dashLen = 0; int symLen = 0; int spaceLen = 0; int ledPin = 2; int statusLed = 13; char textDemo[] = "The quick brown fox jumped over the lazy dog."; void setup() { ditLen = 1200 / wpm; dashLen = ditLen * 3; symLen = ditLen; spaceLen = dashLen; pinMode(ledPin, OUTPUT); Serial.begin(9600); Serial.print("ditlen "); Serial.println(ditLen); } void loop() { blinkLed(statusLed, 1000); int len = strlen(textDemo); for (int i = 0; i < len; i++) { DoLetter(textDemo[i]); } } void DoLetter(char c) { switch(c) { case 'a': case 'A': DoDit(); DoSym(); DoDash(); DoSpace(); break; case 'b': case 'B': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'c': case 'C': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'd': case 'D': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'e': case 'E': DoDit(); DoSym(); DoSpace(); break; case 'f': case 'F': DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'g': case 'G': DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'h': case 'H': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'i': case 'I': DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'j': case 'J': DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'k': case 'K': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'l': case 'L': DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'm': case 'M': DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'n': case 'N': DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'o': case 'O': DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'p': case 'P': DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 'q': case 'Q': DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'r': case 'R': DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 's': case 'S': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case 't': case 'T': DoDash(); DoSym(); DoSpace(); break; case 'u': case 'U': DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'v': case 'V': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'w': case 'W': DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'x': case 'X': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'y': case 'Y': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case 'z': case 'Z': DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '1': DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '2': DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '3': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '4': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '5': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '6': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '7': DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '8': DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '9': DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '0': DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case ' ': DoSpace(); break; case '.': DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case ',': DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '?': DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '\'': DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '\!': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '/': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '\(': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '\)': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '&': DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case ':': DoDash(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case ';': DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '=': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '+': DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '-': DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '_': DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '\"': DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; case '\$': DoDit(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoSpace(); break; case '\@': DoDit(); DoSym(); DoDash(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoDash(); DoSym(); DoDit(); DoSym(); DoSpace(); break; default: Serial.print("unknown character >"); Serial.print(c); Serial.println("<"); } } void DoDit() { digitalWrite(ledPin, HIGH); delay(ditLen); digitalWrite(ledPin, LOW); } void DoDash() { digitalWrite(ledPin, HIGH); delay(dashLen); digitalWrite(ledPin, LOW); } void DoSpace() { delay(spaceLen); } void DoSym() { delay(symLen); } void blinkLed(int pin, int ms) { digitalWrite(pin,LOW); // turn it off it was on digitalWrite(pin,HIGH); delay(ms); digitalWrite(pin,LOW); delay(ms); }