Go Down

Topic: morse code flasher - lookup table question (Read 3 times) previous topic - next topic

MisterResistor

#10
Feb 11, 2013, 05:06 am Last Edit: Feb 11, 2013, 05:14 am by Learning Reason: 1
Your 'B' is actually a "D". B is dah dit dit dit.  A listening ratio of 1.0 for a dit to 1.5 for a dah, is more pleasing. Visually you might try 1.0 to 2.0.  Once you get to 23-25 words per minute, it all sounds like music. ;)

JavaMan

You can try this code I wrote last May, it's tested and works on my Uno rev3.

Code: [Select]

// flashes  morse code from text on serial port
// special characters to adjust wpm and frequency

char c;                  // read off serial port
int pin = 8;
float dot = 200.0;       // duration of dot for 5 wpm
void setup() {
  pinMode(8, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  while(Serial.available()) {
    c = Serial.read();
    switch(c) {
      case '!' : dot*=1.1; break;        // slower by 10%
      case '@' : dot*=.9; break;         // faster by 10%
      case '%' : report(); break;        // show status
      case ' ' : delay(7*dot); break;
      case 'a' : flash("01"); break;
      case 'b' : flash("1000"); break;
      case 'c' : flash("1010"); break;
      case 'd' : flash("100"); break;
      case 'e' : flash("0"); break;
      case 'f' : flash("0010"); break;
      case 'g' : flash("110"); break;
      case 'h' : flash("0000"); break;
      case 'i' : flash("00"); break;
      case 'j' : flash("0111"); break;
      case 'k' : flash("101"); break;
      case 'l' : flash("0100"); break;
      case 'm' : flash("11"); break;
      case 'n' : flash("10"); break;
      case 'o' : flash("111"); break;
      case 'p' : flash("0110"); break;
      case 'q' : flash("1101"); break;
      case 'r' : flash("010"); break;
      case 's' : flash("000"); break;
      case 't' : flash("1"); break;
      case 'u' : flash("001"); break;
      case 'v' : flash("0001"); break;
      case 'w' : flash("011"); break;
      case 'x' : flash("1001"); break;
      case 'y' : flash("1011"); break;
      case 'z' : flash("1100"); break;
      case 'A' : flash("01"); break;
      case 'B' : flash("1000"); break;
      case 'C' : flash("1010"); break;
      case 'D' : flash("100"); break;
      case 'E' : flash("0"); break;
      case 'F' : flash("0010"); break;
      case 'G' : flash("110"); break;
      case 'H' : flash("0000"); break;
      case 'I' : flash("00"); break;
      case 'J' : flash("0111"); break;
      case 'K' : flash("101"); break;
      case 'L' : flash("0100"); break;
      case 'M' : flash("11"); break;
      case 'N' : flash("10"); break;
      case 'O' : flash("111"); break;
      case 'P' : flash("0110"); break;
      case 'Q' : flash("1011"); break;
      case 'R' : flash("010"); break;
      case 'S' : flash("000"); break;
      case 'T' : flash("1"); break;
      case 'U' : flash("001"); break;
      case 'V' : flash("0001"); break;
      case 'W' : flash("011"); break;
      case 'X' : flash("1001"); break;
      case 'Y' : flash("1011"); break;
      case 'Z' : flash("1100"); break;
      case '0' : flash("11111"); break;
      case '1' : flash("01111"); break;
      case '2' : flash("00111"); break;
      case '3' : flash("00011"); break;
      case '4' : flash("00001"); break;
      case '5' : flash("00000"); break;
      case '6' : flash("10000"); break;
      case '7' : flash("11000"); break;
      case '8' : flash("11100"); break;
      case '9' : flash("11110"); break;
      case '.' : flash("010101"); break;
      case ',' : flash("110011"); break;
      default  : delay(7*dot); break;
    }
  }
}

void flash(char x[]) {
  for(int i=0; i<strlen(x); i++) {
    if(x[i]=='1') {
      digitalWrite(pin, HIGH);        // dash
      delay(3*dot);
      digitalWrite(pin, LOW);
    }
    else {
      digitalWrite(pin, HIGH);        // dot
      delay(dot);
      digitalWrite(pin, LOW);
    }
  delay(dot);               // end of flash
  }
  delay(3*dot);             // end of character
}

void report() {
  Serial.print(1000/dot);
  Serial.print(" wpm, ");
}
 


AlphaTango

Thanks guys!  I was hoping to avoid typing all the crazy-long lookup tables.  That was the reason for my "S=000" to make 'S" transmit "dot dot dot".  I like simple.  :)

Krupski


Krupski - yeah, this is more what I had in mind.  So, are you telling me that I can literally use the individual characters for the index??  I had no idea.  That makes things simpler.  Is that * a reference to pointer in this instance?  If so, you're shifting thru the symbols, correct?


Yes.

A simplified example: Imagine you only want to do Morse letters "A" through "E".

Take the character, subtract 'A' from it (makes A == 0, B == 1, etc...) then use it to index into the Morse array:

Code: [Select]
const char *morse[5] = {
    ".-", // A = 0
    "-...", // B = 1
    "-.-.", // C = 2
    "-..", // D = 3
    "." // E = 4
    // etc......
};

int m = 'C'; // canned letter C

m -= 'A'; // normalize to 0

for (int i = 0; i < strlen(morse[m]); i++) {
    if (morse[m][i] == "." {
        // generate a dot
    } else {
        // generate a dash
    }
}


Of course, you need to do the entire range, and save yourself grief by uppercasing the letters so you can handle lowercase input seamlessly.

Hope this helps.
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

AlphaTango

Thanks Krupski!  That's definitely what I had in mind, though I was going to use binary (0s for dits, 1s for dahs) for the pattern.

Can you explain why you're subtracting 'A' from each character?  I don't quite understand that.

Go Up