Go Down

Topic: Morse library (Read 908 times) previous topic - next topic

saturation

Feb 25, 2008, 08:03 pm Last Edit: Feb 26, 2008, 05:52 am by saturation Reason: 1
Hello,
so here is semi-ready morse library.
please, criticise, judge and make suggestions and improvements.
Morse.h
Code: [Select]


/*
   Morse code transmitter, version 0.1
   Copyright (C) 2008 Miikka Liukkonen

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/



#ifndef Morsee_h
#define Morsee_h

#include "WConstants.h"
#include "binary.h"

typedef struct {
   byte code;    
   byte length;    
 } signal;


class Morsee {
 public:
   Morsee( int pin, int intervail );
   void transmitSign( signal sig );
   void transmitString( char str[], int strlen );
   
   signal letters[26],
          figures[20],
          spaceBetweenWords,
          spaceBetweenLetters,
          doubleHyphen,  
          quotationmarks,
          questionMark,
          commercialAt,    
          startingSignal,  
          endOfWork,  
          wait,        
          invitationToTransmit,            
          error,
          understood;  
         
 private:
    int  _pin;
    int  _dash;
    int  _dot;
};

#endif

saturation

#1
Feb 25, 2008, 08:04 pm Last Edit: Feb 26, 2008, 05:53 am by saturation Reason: 1
first part of Morse.cpp
Code: [Select]
/*
   Morse code transmitter, version 0.1
   Copyright (C) 2008 Miikka Liukkonen

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "Morsee.h"
#include "WConstants.h"
#include "binary.h"
Morsee::Morsee( int pin, int intervail )
{
   _pin  = pin;
   _dot  = intervail;
   _dash = intervail+intervail+intervail;
   pinMode( pin, OUTPUT );
   
   // LETTERS A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
 letters[0].code = B01000000; letters[0].length = 2;  
 letters[1].code = B10000000; letters[1].length = 4;  
 letters[2].code = B10100000; letters[2].length = 4;  
 letters[3].code = B10000000; letters[3].length = 3;  
 letters[4].code = B00000000; letters[4].length = 1;    //accented e letters[4].code = B00100000;   letters[4].lenght = 5;
 letters[5].code = B00100000; letters[5].length = 4;  
 letters[6].code = B11000000; letters[6].length = 3;  
 letters[7].code = B00000000; letters[7].length = 4;  
 letters[8].code = B00000000; letters[8].length = 2;  
 letters[9].code = B01110000; letters[9].length = 4;  
 letters[10].code = B10100000 letters[10].length = 3;  
 letters[11].code = B01000000; letters[11].length = 4;  
 letters[12].code = B11000000; letters[12].length = 2;  
 letters[13].code = B10000000; letters[13].length = 2;  
 letters[14].code = B11100000; letters[14].length = 3;  
 letters[15].code = B01100000; letters[15].length = 4;  
 letters[16].code = B11010000; letters[16].length = 4;  
 letters[17].code = B01000000; letters[17].length = 3;  
 letters[18].code = B00000000; letters[18].length = 3;  
 letters[19].code = B10000000; letters[19].length = 1;  
 letters[20].code = B00100000; letters[20].length = 3;  
 letters[21].code = B00010000; letters[21].length = 4;  
 letters[22].code = B01100000; letters[22].length = 3;  
 letters[23].code = B10010000; letters[23].length = 4;  
 letters[24].code = B10110000; letters[24].length = 4;  
 letters[25].code = B11000000; letters[25].length = 4;  
   
   // FIGURES ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 0 :
 figures[0].code = B01111000;  figures[0].length = 6;
 figures[1].code = B10110000;  figures[1].length = 5;
 figures[2].code = B10110100;  figures[2].length = 6;  
 figures[3].code = B10010000;  figures[3].length = 4;    
 figures[4].code = B01010000;  figures[4].length = 5;  
 figures[5].code = B11001100;  figures[5].length = 6;
 figures[6].code = B10000100;  figures[6].length = 6;        
 figures[7].code = B01010100;  figures[7].length = 6;  
 figures[8].code = B10010000;  figures[8].length = 5;    
 figures[9].code = B11111000;  figures[9].length = 5;
 figures[10].code = B01111000;  figures[10].length = 5;  
 figures[11].code = B00111000;  figures[11].length = 5;  
 figures[12].code = B00011000;  figures[12].length = 5;  
 figures[13].code = B00001000;  figures[13].length = 5;  
 figures[14].code = B00000000;  figures[14].length = 5;  
 figures[15].code = B10000000;  figures[15].length = 5;  
 figures[16].code = B11000000;  figures[16].length = 5;  
 figures[17].code = B11000000;  figures[17].length = 4;  
 figures[18].code = B11110000;  figures[18].length = 5;  
 figures[19].code = B11100000;  figures[19].length = 6;

   // MISCELLANEOUS SIGNS  
   understood.code = B00010000;              understood.length = 5;
   error.code = B00000000;                   error.length = 8;
   invitationToTransmit.code = B10100000;    invitationToTransmit.length = 3;
   wait.code = B01000000;                    wait.length = 5;
   endOfWork.code = B00010100;               endOfWork.length = 6;
   startingSignal.code = B10101000;          startingSignal.length = 5;
   commercialAt.code = B00000000;            commercialAt.length = 6;
   questionMark.code = B00110000;            questionMark.length = 6;
   quotationmarks.code = B01001000;          quotationmarks.length = 6;
   doubleHyphen.code = B10001000;            doubleHyphen.length = 5;
   spaceBetweenLetters.code = B00000000;     spaceBetweenLetters.length = 3;
   spaceBetweenWords.code = B00000000;       spaceBetweenWords.length = 7;
}

saturation

#2
Feb 25, 2008, 08:04 pm Last Edit: Feb 26, 2008, 05:54 am by saturation Reason: 1
and the last part..
Code: [Select]

void Morsee::transmitSign( signal s )
{
 byte mask = B10000000;
 do
 {
   digitalWrite(_pin, HIGH);
   
   if(s.code & mask) {
     delay(_dash);
   } else {
     delay(_dot);
   }
   
   digitalWrite(_pin, LOW);  
   delay(_dot);
   mask >>= 1;
 }
 while(--s.length > 0);
}
void Morsee::transmitString( char str[], int strlen )
{
 for( int i = 0; i <= strlen; i++ )
 {
   if( str[i] >=  67 && str[i] <= 132 )
   {
     transmitSign( letters[str[i]-67] );
   }
   else if( str[i] >=  141 && str[i] <= 172 )
   {
     transmitSign( letters[str[i]-141] );
   }
   else if( str[i] >= 39 && str[i] <= 58 )
   {
     transmitSign( figures[ str[i] - 39 ] );
   }
   else
   {
     switch( str[i] )
     {
       case '?' :
         transmitSign( questionMark );
         break;
       case '"' :
         transmitSign( quotationmarks );
         break;
       case '@' :
         transmitSign( commercialAt );
         break;
       case '=' :
         transmitSign( doubleHyphen );
         break;
       case ' ' :
         transmitSign( spaceBetweenWords );
         continue;
     }
   }
   transmitSign( spaceBetweenLetters );
 }
}



mem

#3
Feb 25, 2008, 08:24 pm Last Edit: Feb 25, 2008, 08:27 pm by mem Reason: 1
Looking good.

A few minor points:

you may want to fix the typo in the second member of yr signal type,  lenght -> length;

I guess you don't trust users to null terminate the string passed to transmitString  ;), otherwise you could dispense with strlen

brianbr

This is good work. I like what you have done, but I take one exception. The call to Morsee use a variable "intervail" which passes the dot time to the routine. Thus setting the words per minute rate. This number is rather obscure. I would propose that you do the math for the user. As long as you writing the library to make this easy for the user, do the whole job ... This is an output routine, we start up a serial routine by issuing a command like  "Serial.begin(9600)" so I would suggest you do the following;

(1) make "intervail" private , initialized to 0

(2) create begin() that gets called in a fashion like "myMorse.begin(wpm)" where wpm is a variable or an actual number of the Morse sending speed in words per minute. Then you do the math and set "intervail"

cheers ... BBR (n1bq)

PaulSchulz

Another typo in Morse.cpp

figures[7] - incorrect encoding for '8', should be:
 figures[17].code = B11100000; figures[17].length = 5;


AlphaBeta

#6
Aug 15, 2009, 12:18 pm Last Edit: Aug 15, 2009, 12:25 pm by AlphaBeta Reason: 1
Cool!

I have a suggestion:

Make the library accept two callbacks. Respectively signalOn, and signalOff functions.

If one wants to signal a morse code with other means than a pin high/low, this will be (one of) the way(s) to go.

Addition to the top of the header:
Code: [Select]

typedef void (*function)(void);


Two additional private member variables:
Code: [Select]

function userSignalOn;
function userSignalOff;


2nd constructor:
Code: [Select]
Morsee( function signalOn, function signalOff, int intervail );

Implementation: (be sure to set them to 0 in the other constructor)
Code: [Select]

Morsee::Morsee( function signalOn, function signalOff, int intervail ){
 userSignalOn = signalOn;
 userSignalOff = signalOff;
 //set other variables to 0
}

void Morsee::transmitSign( signal s )
{
 byte mask = B10000000;
 do
 {
   if (userSignalOn){
     userSignalOn();
   }else{
     digitalWrite(_pin, HIGH);
   }
   
   if(s.code & mask) {
     delay(_dash);
   } else {
     delay(_dot);
   }
   
   if (userSignalOff){
     userSignalOff();
   }else{
     digitalWrite(_pin, LOW);
   }
   delay(_dot);
   mask >>= 1;
 }
 while(--s.length > 0);
}



Now you could use morse coded signals for literally anything :)

[edit]I really like the idea of having a begin(wpm).[/edit]

Go Up