John's code modified for envelope shaping and different colours

Dependencies:   mbed

Fork of Morse-buddy-JohnF by Tony Abbey

Morse_Code.cpp

Committer:
tony1tf
Date:
2013-06-27
Revision:
3:cbd036b6942b
Parent:
2:260128ae5746

File content as of revision 3:cbd036b6942b:


//==============================================================
//  Morse Code  June 30, 2011  John H. Fisher - K5JHF
//==============================================================
// mods by Tony Abbey for envelope shaping and coloured LEDs - 27 June 2013

#include "mbed.h"

#include "main.h"

#include "Morse_Code.h"

const float sine_wave [ 32 ]    =   {
    
    sin (  1 * step ) / 2.5 ,
    sin (  2 * step ) / 2.5 ,
    sin (  3 * step ) / 2.5 ,
    sin (  4 * step ) / 2.5 ,
    sin (  5 * step ) / 2.5 ,
    sin (  6 * step ) / 2.5 ,
    sin (  7 * step ) / 2.5 ,
    sin (  8 * step ) / 2.5 ,
    sin (  9 * step ) / 2.5 ,
    sin ( 10 * step ) / 2.5 ,
    sin ( 11 * step ) / 2.5 ,
    sin ( 12 * step ) / 2.5 ,
    sin ( 13 * step ) / 2.5 ,
    sin ( 14 * step ) / 2.5 ,
    sin ( 15 * step ) / 2.5 ,
    sin ( 16 * step ) / 2.5 ,
    sin ( 17 * step ) / 2.5 ,
    sin ( 18 * step ) / 2.5 ,
    sin ( 19 * step ) / 2.5 ,
    sin ( 20 * step ) / 2.5 ,
    sin ( 21 * step ) / 2.5 ,
    sin ( 22 * step ) / 2.5 ,
    sin ( 23 * step ) / 2.5 ,
    sin ( 24 * step ) / 2.5 ,
    sin ( 25 * step ) / 2.5 ,
    sin ( 26 * step ) / 2.5 ,
    sin ( 27 * step ) / 2.5 ,
    sin ( 28 * step ) / 2.5 ,
    sin ( 29 * step ) / 2.5 ,
    sin ( 30 * step ) / 2.5 ,
    sin ( 31 * step ) / 2.5 ,
    sin (  0 * step ) / 2.5 

    };

//==============================================================

        Morse_Code::Morse_Code  (   float  WPM_Character,
                                    float  WPM_Speed,
                                    int    Tone_Frequency,  
                                    char   colour )  {
   
            _WPM_Character  =  WPM_Character;

            _WPM_Speed      =  WPM_Speed;
           
            _Tone_Frequency =  Tone_Frequency;
            
            _colour            =  colour;

            Calculate_Morse_Timing ( _WPM_Speed, _WPM_Character );
  
            Practice_On();
        
            }

//==============================================================

void    Morse_Code::Sound_On ( void )    {

    Morse_Flag._Sound    =    1;

    }

//==============================================================

void    Morse_Code::Sound_Off ( void )    {

    Morse_Flag._Sound    =    0;

    }

//==============================================================

void    Morse_Code::Sound_Toggle ( void )    {

    Morse_Flag._Sound    ^=    1;
    
    }

//==============================================================

void    Morse_Code::Practice_On ( void )    {

    Morse_Flag._Practice    =    1;

    }

//==============================================================

void    Morse_Code::Practice_Off ( void )    {

    Morse_Flag._Practice    =    0;

    }

//==============================================================

void    Morse_Code::Practice_Toggle ( void )    {

    Morse_Flag._Practice    ^=    1;
    
 //   Serial.print ( Morse_Flag._Practice );
    
    }

//==============================================================

int    Morse_Code::get_Practice ( void )    {

    return    Morse_Flag._Practice;
    
    }

//==============================================================

void    Morse_Code::set_Tone ( int    frequency )    {

    _Tone_Frequency    =    frequency;

    }

//==============================================================

int    Morse_Code::get_Tone ( )    {

    return    _Tone_Frequency;

    }

//==============================================================

void    Morse_Code::Tone_Adjust    ( int  delta,  int limit )    {

    Adjust ( &_Tone_Frequency, delta, limit );    
    
    }

//==============================================================

void    Morse_Code::set_WPM ( float  WPM_Speed )    {

    _WPM_Speed    =    WPM_Speed;

    }

//==============================================================

float    Morse_Code::get_WPM ( )    {

    return    _WPM_Speed;

    }

//==============================================================

void    Morse_Code::WPM_Adjust  (  float delta, float limit )    {
    
    Adjust ( &_WPM_Speed, delta, limit );    
    
    Calculate_Morse_Timing ( _WPM_Speed, _WPM_Character );
    
    }
    
//==============================================================

char    Morse_Code::Morse ( char ASCII )    {

    switch ( ASCII )  {
      
        case  'a':
        case  'A':
        
        return  0x05;  //    B'0000 0101'    ;A
 
        case  'b':
        case  'B':
        
        return  0x18;  //    B'0001 1000'    ;B

        case  'c':
        case  'C':
    
            return  0x1A;  //    B'0001 1010'    ;C

        case  'd':
        case  'D':
        
        return  0x0C;  //    B'0000 1100'    ;D

        case  'e':
        case  'E':
        
        return  0x02;  //    B'0000 0010'    ;E

        case  'f':
        case  'F':
        
        return  0x12;  //    B'0001 0010'    ;F

        case  'g':
        case  'G':
        
        return  0x0E;  //    B'0000 1110'    ;G

        case  'h':
        case  'H':
        
        return  0x10;  //    B'0001 0000'    ;H

        case  'i':
        case  'I':
        
        return  0x04;  //    B'0000 0100'    ;I

        case  'j':
        case  'J':
        
        return  0x17;  //    B'0001 0111'    ;J

        case  'k':
        case  'K':
        
        return  0x0D;  //    B'0000 1101'    ;K

        case  'l':
        case  'L':
        
        return  0x14;  //    B'0001 0100'    ;L

        case  'm':
        case  'M':
        
        return  0x07;  //    B'0000 0111'    ;M

        case  'n':
        case  'N':
        
        return  0x06;  //    B'0000 0110'    ;N

        case  'o':
        case  'O':
        
        return  0x0F;  //    B'0000 1111'    ;O

        case  'p':
        case  'P':
        
        return  0x16;  //    B'0001 0110'    ;P

        case  'q':
        case  'Q':
        
        return  0x1D;  //    B'0001 1101'    ;Q

        case  'r':
        case  'R':
        
        return  0x0A;  //    B'0000 1010'    ;R

        case  's':
        case  'S':
        
        return  0x08;  //    B'0000 1000'    ;S

        case  't':
        case  'T':
        
        return  0x03;  //    B'0000 0011'    ;T

        case  'u':
        case  'U':
        
        return  0x09;  //    B'0000 1001'    ;U

        case  'v':
        case  'V':
        
        return  0x11;  //    B'0001 0001'    ;V

        case  'w':
        case  'W':
        
        return  0x0B;  //    B'0000 1011'    ;W

        case  'x':
        case  'X':
        
        return  0x19;  //    B'0001 1001'    ;X

        case  'y':
        case  'Y':
        
        return  0x1B;  //   B'0001 1011'    ;Y

        case  'z':
        case  'Z':
        
        return  0x1C;  //    B'0001 1100'    ;Z

        case  '1':

        return  0x2F;  //    B'0010 1111'    ;1

        case  '2':

        return  0x27;  //    B'0010 0111'    ;2

        case  '3':

        return  0x23;  //    B'0010 0011'    ;3

        case  '4':

        return  0x21;  //    B'0010 0001'    ;4

        case  '5':

        return  0x20;  //    B'0010 0000'    ;5

        case  '6':

        return  0x30;  //    B'0011 0000'    ;6

        case  '7':

        return  0x38;  //    B'0011 1000'    ;7

        case  '8':

        return  0x3C;  //    B'0011 1100'    ;8

        case  '9':

        return  0x3E;  //    B'0011 1110'    ;9
 
        case  '0':

        return  0x3F;  //    B'0011 1111'    ;0

        case  '.':

        return  0x55;  //    B'0101 0101'    ;.

        case  ',':

        return  0x73;  //    B'0111 0011'    ;,

        case  ';':

        return  0x6A;  //   B'0110 1010'    ;;

        case  ':':

        return  0x78;  //    B'0111 1000'    ;:

        case  0x27:

        return  0x5E;  //    B'0101 1110'    ;'

        case  0x22:

        return  0x52;  //    B'0101 0010'    ;"

        case  '/':

        return  0x32;  //   B'0011 0010'    ;/

        case  '?':

        return  0x4C;  //    B'0100 1100'    ;?

        case  '-':

        return  0x61;  //    B'0110 0001'    ;-

        case  '_':

        return  0x4D;  //    B'0100 1101'    ;_

        case  '=':

        return  0x31;  //    B'0011 0001'    ;=

        case  '+':

        return  0x2A;  //    B'0010 1010'    ;+

        case  '!':

        return  0x22;  //    B'0010 0010'    ;!

        case  '@':

        return  0x5A;  //    B'0101 1010'    ;@

        case  '#':

        return  0x54;  //    B'0101 0100'    ;#

        case  '$':

        return  0x89;  //    B'1000 1001'    ;$

        case  '%':

        return  0x35;  //    B'0011 0101'    ;%

        case  '^':

        return  0x0D;  //    B'0000 1101'    ;^

        case  '&':

        return  0x28;  //    B'0010 1000'    ;&

        case  '*':

        return  0x45;  //    B'0100 0101'    ;*

        case  '(':

        return  0x36;  //    B'0011 0110'    ;(

        case  ')':

        return  0x6D;  //    B'0110 1101'    ;)

        case  0x09:

        return  0x54;  //    B'0101 0100'    ;TAB

        case  0x08:

        return  0x80;  //    B'1000 0000'    ;Backspace

        case  ' ':

        return  0x01;  //    B'1000 0000'    ;space

        default:
        
      return 0x01;

        }
    
    }

//===================================================================

    void    Morse_Code::Send_Morse ( char Morse )    {

        char    bit_counter    =    8;

        while ( !( Morse & 0x80 ) ) {

            Morse <<=    1;

            --bit_counter;

            }

        Morse_Flag.last_bit    =    0;

        while ( --bit_counter )    {

          if ( bit_counter == 1 ) Morse_Flag.last_bit = 1;

          if    ( ( Morse <<= 1 ) & 0x80 )  dah();

          else                              dit();

                  if ( !Morse_Flag.last_bit )       wait ( u );

                  else if ( Morse_Flag.last_char )  wait ( tw );
                
                  else                              wait ( tc );        

          }

    }

//===================================================================

char  Morse_Code::Random_Code ( void )  {

    char  ascii; 
 
    static char  count; 
  
    ascii  =  32 + rand () % 95;
  
    Send_Morse ( Morse ( ascii ) );
  
    if ( ( count++ ) % 5 == 0 ) Morse_Flag.last_char = 1;

    else                        Morse_Flag.last_char = 0;
 
    return ascii;
  
    }

//==============================================================
//  The ARRL Morse Transmission Timing Standard

void Morse_Code::Calculate_Morse_Timing ( float s, float c )  {  // In seconds for wait function
   
    if ( s >= 18.0 )  {
 
        c   =  s;
    
        u   =  1.2 / c;
    
        tc  =  3.0 * u;
 
        tw  =  7.0 * u; 
    
        }
  
    else  {
    
        u   = 1.2 / c;
    
        ta  =  ( 60.0 * c - 37.2 * s ) / ( s * c );
    
        tc  =  3.0 * ta / 19.0;  
  
        tw  =  7.0 * ta / 19.0;
  
        }
  
    }

//==============================================================

void  Morse_Code::dit  ( )  {
  
    if ( _colour == 1 ) blue =   on;
    if ( _colour == 2 ) red = on;
    if ( _colour == 3 ) green = on;
    if ( _colour == 4 ) { blue = on ; red = on ; green = on ; }

    Tone ( _Tone_Frequency, u, 1.0 );

    blue = off red = off green = off ;
  
   }
  
//==============================================================

void  Morse_Code::dah  ( )  {

    if ( _colour == 1 ) blue = on;
    if ( _colour == 2 ) red = on;
    if ( _colour == 3 ) green = on;
    if ( _colour == 4 ) { blue = on ; red = on ; green = on ; }

    Tone ( _Tone_Frequency, u, 3.0 );

       blue = off red = off green = off ;
  
    }
  
//=============================================================
 
void    Morse_Code::Tone ( int freq_factor, float duration, float multiplier )    {

    Timer   timer;

    char i = 0;
    float t;
    
    unsigned int delay;
    float amplitude = 0;

    timer.start();
    
    timer.reset();
    
    do  {
    
        for ( i = 0; i < 32; i++ )  {

            piezo  =   sine_wave [ i ] * amplitude + 0.4;
    
            for ( delay = 0; delay < freq_factor; delay++ );  

            } t = timer.read() ;
             if ( t < duration/5 ) amplitude = t * 5 / duration ;
             if ( t/multiplier > duration * 0.8 ) amplitude = ( ( duration - t/multiplier ) / duration  ) * 8 ;

        } while ( timer.read() < duration * multiplier );

    }

//=============================================================