Pages: [1]   Go Down
Author Topic: Morse library  (Read 773 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
so here is semi-ready morse library.
please, criticise, judge and make suggestions and improvements.
Morse.h
Code:

/*
    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
« Last Edit: February 25, 2008, 11:52:16 pm by saturation » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

first part of Morse.cpp
Code:
/*
    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;
}
« Last Edit: February 25, 2008, 11:53:41 pm by saturation » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

and the last part..
Code:
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 );
  }
}


« Last Edit: February 25, 2008, 11:54:14 pm by saturation » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-wink, otherwise you could dispense with strlen
« Last Edit: February 25, 2008, 02:27:48 pm by mem » Logged

Underhill Center, Vermont, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Another typo in Morse.cpp

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

Logged

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 13
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
typedef void (*function)(void);

Two additional private member variables:
Code:
function userSignalOn;
function userSignalOff;

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

Implementation: (be sure to set them to 0 in the other constructor)
Code:
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 smiley

[edit]I really like the idea of having a begin(wpm).[/edit]
« Last Edit: August 15, 2009, 05:25:33 am by AlphaBeta » Logged

Pages: [1]   Go Up
Jump to: