Sunday, April 14, 2013

MSP430 Morse Code in Energia Part 2

So I wasn't entirely satisfied with my earlier work on this and decided to upgrade it somewhat. All valid letters and numbers are stored in an array now. There's also space and a couple of punctuation. Originally I made the array match up exactly with an ascii table, but there was some sort of a problem with that. Running the program would result in nothing being output, even if I forced it to return the first few locations in the array rather than up in the 50-70 range. It's either a bug in how Energia stores arrays that prevents a larger one or I wasn't doing something right. Once I reduced the array in size enough, it started working. I compensated by subtracting 31 from whatever letter I was trying to return.

Something that may help in understanding that is you can operate on Char values, which are single letters, as if they were numbers and it matches up directly to the ASCII table. Given that, you can put things in the same order in an array and simply match up the values to the letters. Furthermore, you can read a String variable similar to an array where each location returns a Char value of whatever is stored in that location.

In my array, undefined spaces are filled with 65000. This could just as easily been 0, but I did that as a debugging measure as it wouldn't be valid morse code but should be distinctive if it's landed on.

Now it's possible to enter a string in and have the program take care of what to do to send it out.

I'm still not 100% satisfied with this, but thought it would be nice to post my progress for now. I'd like to clean up some various variables that are unused. I'd also like to figure out how to specify how fast to send the code by Words Per Minute. I'd like to see if I could have it produce an audio tone on one of the pins instead of just flashing an LED. Preferably with the option of adjusting what frequency the tone is, 600hz is common. Eventually add the option to program the message, speed, and options like tone or LED by a serial connection to a computer, rather than needing to reprogram it with the Energia IDE every time.

/*
James Hall - N9XLC
Small program to push out my callsign via the red LED on a MSP430 board.
Developed 8/24/2012-8/25/2012
Modified 4/11/2013

Started off modifying, then totally replacing the code in the 'Blink' example project.
This could probably be wrapped up in a function to send out arbitrary sentences.
Only enough morse code is implemented to get my callsign out, but it would be trivial to add the rest.
Could be used to blink out current temp or maybe short status info in morse code in other projects.

 http://www.arduino.cc/en/Tutorial/BitMask
 http://wiring.org.co/reference/bitwiseAND.html
 http://wiring.org.co/reference/bitwisebitshiftleft.html
 */
 #define output 2 // pin 2 has the red led on a msp430 board, pin 14 is the green led.
 
unsigned int mask = 1;
int dot = 1;
int dash = 3; //dash is equal to 3 dots
int lspace = 1; //spacing in same letter is 1 dot
int llspace = 3; //spacing between two letters in same word is 3 dots
int wspace = 7; //spacing between two words is 7 dots.

int didot = 2;
int didash = 3;
int spacems = 120; //100ms is a little slower than 20wpm (60ms) so maybe 13-15wpm?
// 10 dot, 11 dash, 00 end
// 01 = space?
// unsigned int is 16 bits
unsigned int aCW[] = {
65000,1,65000,65000,65000,65000,65000,65000,65000,65000,
65000,65000,65000,65000,65000,65000,65000,1023,1022,1018,
1002,938,682,683,687,703,767,65000,65000,65000,
65000,65000,2810,3006,14,171,187,43,2,186,
47,170,10,254,59,174,15,11,63,190,
239,46,42,3,58,234,62,235,251,175,
};
unsigned int numCW[] = {
 1023,1022,1018,1002,938,682,683,687,703,767
};
unsigned int cwN = 11; //0000 0000 0000 1011 <-read right-to-left
unsigned int cw9 = 767; //0000 0010 1111 1111
unsigned int cwX = 235; //0000 0000 1110 1011
unsigned int cwL = 174; //0000 0000 1010 1110
unsigned int cwC = 187; //0000 0000 1011 1011
String MorseCode = "CQCQCQ DE N9XLC";

byte testbyte;
  
void setup() {                
  // initialize the digital pin as an output.
  // Pin 14 has an LED connected on most MSP430 boards:
  pinMode(output, OUTPUT);     
  pinMode(14, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
 // pinMode(5, INPUT);
}

void loop() {
  digitalWrite(14, LOW);
  digitalWrite(output, LOW);
  unsigned int cwout;
  unsigned int mask = 3;
  unsigned int x;
  
while(true) {
 for(x=0; x<MorseCode.length(); x++){
   //subtract by 31 because of reduced size array
   
   cwout = aCW[MorseCode[x]-31];
 
  //cwout = numCW[MorseCode.length()];
    while (cwout) {
     testbyte = cwout & mask;
     //testbyte = 00000010;
       if (testbyte == 1 ) {
          delay(wspace * spacems);
         } 
       if (testbyte == 2 ) {
          digitalWrite(output, HIGH);
          delay(dot * spacems);
          digitalWrite(output, LOW);
         } 
       if (testbyte == 3 ) {
        digitalWrite(output, HIGH);
        delay(dash * spacems);
        digitalWrite(output, LOW);
       }
       delay(spacems * dot); //inner letter spacing 
    
     cwout >>= 2; 
    }
 delay (spacems * dash); //outer letter spacing

}

delay (spacems * wspace); //word spacing
}
}

1 comment:

  1. I was trying to do something similar with the MSP430 but I didn't realize there was such a thing like energia. I started by looking at a bunch of tutorials online and found a few. Found one msp430 tutorial that helped me develop my own morse code. works pretty well but I have to improve the sound output a bit. Perhaps add a buffer or something similar.

    ReplyDelete