Go Down

Topic: Arduino + Wire = Morse Code AM Radio Beacon (reopen) (Read 3143 times) previous topic - next topic

ellisgl

Original thread: http://arduino.cc/forum/index.php/topic,8456.msg68164.html

Thought I would throw in my version:
Code: [Select]

/**
* Arduino + Wire = Morse Code AM Radio Beacon
* By EllisGL 2011-08-08
* Version 1.00 (Arduino version)
* Based on http://arduino.cc/forum/index.php/topic,8456.msg68164.html
*
* Change log:
*  V1.00: Initial
*
* Known Issues:
*  Harmonics
*/
// Beacon message
const char message[] = "hello from my arduino";

// Timings
const unsigned int dahLen = 1000; // 1000 ms - dah length
const unsigned int ditLen = 250;  // 250  ms - dit length - same timeing between dots and dashes of the same letter
const unsigned int maxBuf = 80;   // Max length for message buffer
const unsigned int lPause = 750;  // 750  ms - length between charaters
const unsigned int wPause = 1750; // 1750 ms - length for spaces
const unsigned int ledPin = 13;
const unsigned int outPin = 11;

// Character mapping
const char chars[36][5]        =
{
    {0, 1         }, // a
    {1, 0, 0, 0   }, // b
    {1, 0, 1, 0   }, // c
    {1, 0, 0      }, // d
    {0            }, // e
    {0, 0, 1, 0   }, // f
    {1, 1, 0      }, // g
    {0, 0, 0, 0   }, // h
    {0, 0         }, // i
    {0, 1, 1, 1   }, // j
    {1, 0, 1      }, // k
    {0, 1, 0, 0   }, // l
    {1, 1         }, // m
    {1, 0         }, // n
    {1, 1, 1      }, // o
    {0, 1, 1, 0   }, // p
    {1, 1, 0, 1   }, // q
    {0, 1, 0      }, // r
    {0, 0, 0      }, // s
    {1            }, // t
    {0, 0, 1      }, // u
    {0, 0, 0, 1   }, // v
    {0, 1, 1      }, // w
    {1, 0, 0, 1   }, // x
    {1, 0, 1, 1   }, // y
    {1, 1, 0, 0   }, // z
    {0, 1, 1, 1, 1}, // 1
    {0, 0, 1, 1, 1}, // 2
    {0, 0, 0, 1, 1}, // 3
    {0, 0, 0, 0, 1}, // 4
    {0, 0, 0, 0, 0}, // 5
    {1, 0, 0, 0, 0}, // 6
    {1, 1, 0, 0, 0}, // 7
    {1, 1, 1, 0, 0}, // 8
    {1, 1, 1, 1, 0}, // 9
    {1, 1, 1, 1, 1}, // 0
};

unsigned int msgLen, i, l, p, x;
char buffer, a, ch;

void dit(void);
void dah(void);
void pause(void);
void broadcast(int N_cycles);
void dontbroadcast(int N_cycles);

void setup()
{
    Serial.begin(9600);
    pinMode(outPin, OUTPUT);      // sets the digital pin as output

    msgLen = sizeof(message);
}

void loop()
{
    for(x = 0; x < msgLen; x++)
    {
        buffer = message[x];

        switch(buffer)
        {
            case 'a':
                l = 0;
                p = 2;
                a = 'a';
            break;

            case 'b':
                l = 1;
                p = 4;
                a = 'b';
            break;

            case 'c':
                l = 2;
                p = 4;
                a = 'c';
            break;

            case 'd':
                l = 3;
                p = 3;
                a = 'd';
            break;

            case 'e':
                l = 4;
                p = 1;
                a = 'e';
            break;

            case 'f':
                l = 5;
                p = 4;
                a = 'f';
            break;

            case 'g':
                l = 6;
                p = 3;
                a = 'g';
            break;

            case 'h':
                l = 7;
                p = 4;
                a = 'h';
            break;

            case 'i':
                l = 8;
                p = 2;
                a = 'i';
            break;

            case 'j':
                l = 9;
                p = 4;
                a = 'j';
            break;

            case 'k':
                l = 10;
                p = 3;
                a = 'k';
            break;

            case 'l':
                l = 11;
                p = 4;
                a = 'l';
            break;

            case 'm':
                l = 12;
                p = 2;
                a = 'm';
            break;

            case 'n':
                l = 13;
                p = 2;                   
                a = 'n';
            break;

            case 'o':
                l = 14;
                p = 3;
                a = 'o';
            break;

            case 'p':
                l = 15;
                p = 4;
                a = 'p';
            break;

            case 'q':
                l = 16;
                p = 4;
                a = 'q';
            break;

            case 'r':
                l = 17;
                p = 3;
                a = 'r';
            break;

            case 's':
                l = 18;
                p = 3;
                a = 's';
            break;

            case 't':
                l = 19;
                p = 1;
                a = 't';
            break;

            case 'u':
                l = 20;
                p = 3;
                a = 'u';
            break;

            case 'v':
                l = 21;
                p = 4;
                a = 'v';
            break;

            case 'w':
                l = 22;
                p = 3;
                a = 'w';
            break;

            case 'x':
                l = 23;
                p = 4;
                a = 'x';
            break;

            case 'y':
                l = 24;
                p = 4;
                a = 'y';
            break;

            case 'z':
                l = 25;
                p = 4;
                a = 'z';
            break;

            case '1':
                l = 26;
                p = 5;
                a = '1';
            break;

            case '2':
                l = 27;
                p = 5;
                a = '2';
            break;

            case '3':
                l = 28;
                p = 5;
                a = '3';
            break;

            case '4':
                l = 29;
                p = 5;
                a = '4';
            break;

            case '5':
                l = 30;
                p = 5;
                a = '5';
            break;

            case '6':
                l = 31;
                p = 5;
                a = '6';
            break;

            case '7':
                l = 32;
                p = 5;
                a = '7';
            break;

            case '8':
                l = 33;
                p = 5;
                a = '8';
            break;

            case '9':
                l = 34;
                p = 5;
                a = '9';
            break;

            case '0':
                l = 35;
                p = 5;
                a = '0';
            break;

            default:
               l = 36;
               p = 1;
               a = ' ';
        }

        Serial.print(a);
        Serial.print(" ");

        if(l == 36)
        {
            Serial.println("SPACE");
            delay(wPause);
        }           
        else
        {
            for(i = 0; i < p; i++)
            {

                if(chars[l][i] == 0)
                {
                  dit();
                }
                else
                {
                  dah();
                }
            }

            delay(lPause);
            Serial.println();
        }
    }

    Serial.println();
    delay(wPause); 
}

void dah(void)
{
    Serial.print("-");
    digitalWrite(ledPin, HIGH);
    analogWrite(outPin, 128);
    delay(dahLen);
    digitalWrite(ledPin, LOW);
    analogWrite(outPin, 0);
    delay(ditLen);
}

void dit(void)
{
    Serial.print(".");
    digitalWrite(ledPin, HIGH);
    analogWrite(outPin, 128);
    delay(ditLen);
    digitalWrite(ledPin, LOW);
    analogWrite(outPin, 0);
    delay(ditLen);
}


AWOL

#1
Aug 09, 2011, 08:53 am Last Edit: Aug 09, 2011, 08:57 am by AWOL Reason: 1
Code: [Select]
 msgLen = sizeof(message);
better to use "strlen", that way, you don't end up dealing with unnecessary terminators.

Your "switch/case" is over 200 lines long - it doesn't need to be there at all, and your code table occupies 540 bytes of precious RAM, when it needs at most about 110 (and would be better in PROGMEM).
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ellisgl

Code: [Select]

/**
* Arduino + Wire = Morse Code AM Radio Beacon
* By EllisGL 2011-08-08
* Version 1.01 (Arduino version)
* Based on http://arduino.cc/forum/index.php/topic,8456.msg68164.html
*
* Change log:
*  V1.00: Initial
*  V1.01: Refactored for smaller size
*
* Known Issues:
*  Harmonics
*/
// Beacon message
const char message[] = "az 012345689";

// Timings
const unsigned int dahLen = 1000; // 1000 ms - dah length
const unsigned int ditLen = 250;  // 250  ms - dit length - same timeing between dots and dashes of the same letter
const unsigned int lPause = 750;  // 750  ms - length between charaters
const unsigned int wPause = 1750; // 1750 ms - length for spaces
const unsigned int ledPin = 13;
const unsigned int outPin = 11;

// Character mapping
const char chars[36][6]        =
{
    {'.', '-'               }, // 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
    {'-', '-', '-', '-', '-'}, // 0
    {'.', '-', '-', '-', '-'}, // 1
    {'.', '.', '-', '-', '-'}, // 2
    {'.', '.', '.', '-', '-'}, // 3
    {'.', '.', '.', '.', '-'}, // 4
    {'.', '.', '.', '.', '.'}, // 5
    {'-', '.', '.', '.', '.'}, // 6
    {'-', '-', '.', '.', '.'}, // 7
    {'-', '-', '-', '.', '.'}, // 8
    {'-', '-', '-', '-', '.'} // 9
};

unsigned int msgLen, ch, i, l, p, x;
char buffer;

void dit(void);
void dah(void);
void pause(void);
void broadcast(int N_cycles);
void dontbroadcast(int N_cycles);

void setup()
{
    Serial.begin(9600);
    pinMode(outPin, OUTPUT);      // sets the digital pin as output

    msgLen = strlen(message);
}

void loop()
{
    for(x = 0; x < msgLen; x++)
    {
        buffer = message[x];
        ch     = 0;
        ch     = (ch * 10) + message[x];


        if(ch >=97 && ch <=122)
        {
            l = ch - 97;
        }
        else if(ch >= 48 && ch <= 57)
        {
            l = ch - 22;
        }
        else
        {
            l = 36;
        }
       
        Serial.print(buffer);

        if(l == 36)
        {
            Serial.println("SPACE");
            delay(wPause);
        }           
        else
        {
            p = strlen(chars[l]);

            for(i = 0; i < p; i++)
            {

                if(chars[l][i] == '.')
                {
                  dit();
                }
                else if(chars[l][i] == '-')
                {
                  dah();
                }
            }

            delay(lPause);
            Serial.println();
        }
    }

    Serial.println();
    delay(wPause); 
}

void dah(void)
{
    Serial.print("-");
    digitalWrite(ledPin, HIGH);
    analogWrite(outPin, 128);
    delay(dahLen);
    digitalWrite(ledPin, LOW);
    analogWrite(outPin, 0);
    delay(ditLen);
}

void dit(void)
{
    Serial.print(".");
    digitalWrite(ledPin, HIGH);
    analogWrite(outPin, 128);
    delay(ditLen);
    digitalWrite(ledPin, LOW);
    analogWrite(outPin, 0);
    delay(ditLen);
}


AWOL

#3
Aug 09, 2011, 10:50 am Last Edit: Aug 09, 2011, 10:53 am by AWOL Reason: 1
Code: [Select]
if(ch >=97 && ch <=122)
Better:
Code: [Select]
if(ch >='a' && ch <= 'z')

Code: [Select]
buffer = message[x];
        ch     = 0;
        ch     = (ch * 10) + message[x];

?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ellisgl

#4
Aug 09, 2011, 11:15 am Last Edit: Aug 09, 2011, 11:17 am by ellisgl Reason: 1
instead of having to convert (int)ch to a char - use the buffer (which i renamed buff) so I don't have to look have to look up the value from the array.
Code: [Select]

/**
* Arduino + Wire = Morse Code AM Radio Beacon
* By EllisGL 2011-08-09
* Version 1.02 (Arduino version)
* Based on http://arduino.cc/forum/index.php/topic,8456.msg68164.html
*
* Change log:
*  V1.00: Initial
*  V1.01: Refactored for smaller size
*  V1.02: More refactoring
*
* Known Issues:
*  Harmonics
*/
// Beacon message
const char message[] = "hello from my arduino 1022";

// Timings
const unsigned int dahLen = 1000; // 1000 ms - dah length
const unsigned int ditLen = 250;  // 250  ms - dit length - same timeing between dots and dashes of the same letter
const unsigned int lPause = 750;  // 750  ms - length between charaters
const unsigned int wPause = 1750; // 1750 ms - length for spaces
const unsigned int ledPin = 13;
const unsigned int outPin = 11;

// Character mapping
const char chars[36][6]        =
{
   {'.', '-'               }, // 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
   {'-', '-', '-', '-', '-'}, // 0
   {'.', '-', '-', '-', '-'}, // 1
   {'.', '.', '-', '-', '-'}, // 2
   {'.', '.', '.', '-', '-'}, // 3
   {'.', '.', '.', '.', '-'}, // 4
   {'.', '.', '.', '.', '.'}, // 5
   {'-', '.', '.', '.', '.'}, // 6
   {'-', '-', '.', '.', '.'}, // 7
   {'-', '-', '-', '.', '.'}, // 8
   {'-', '-', '-', '-', '.'} // 9
};

unsigned int msgLen, ch, i, l, p, x;
char buff;

void dit(void);
void dah(void);
void pause(void);
void broadcast(int N_cycles);
void dontbroadcast(int N_cycles);

void setup()
{
   Serial.begin(9600);
   pinMode(outPin, OUTPUT);      // sets the digital pin as output

   msgLen = strlen(message);
}

void loop()
{
   for(x = 0; x < msgLen; x++)
   {
       buff = message[x];
       ch   = 0;
       ch   = (ch * 10) + buff;

       if(buff >= 'a' && buff <= 'z')
       {
           l = ch - 97;
       }
       else if(buff >= '0' && buff <= '9')
       {
           l = ch - 22;
       }
       else
       {
           l = 36;
       }
       
       Serial.print(buff);

       if(l == 36)
       {
           Serial.println("SPACE");
           delay(wPause);
       }          
       else
       {
           p = strlen(chars[l]);

           for(i = 0; i < p; i++)
           {

               if(chars[l][i] == '.')
               {
                 dit();
               }
               else if(chars[l][i] == '-')
               {
                 dah();
               }
           }

           delay(lPause);
           Serial.println();
       }
   }

   Serial.println();
   delay(wPause);  
}

void dah(void)
{
   Serial.print("-");
   digitalWrite(ledPin, HIGH);
   analogWrite(outPin, 128);
   delay(dahLen);
   digitalWrite(ledPin, LOW);
   analogWrite(outPin, 0);
   delay(ditLen);
}

void dit(void)
{
   Serial.print(".");
   digitalWrite(ledPin, HIGH);
   analogWrite(outPin, 128);
   delay(ditLen);
   digitalWrite(ledPin, LOW);
   analogWrite(outPin, 0);
   delay(ditLen);
}


robtillaart


As morse codes are max 5 bits long you can pack use one byte per character.

struct morse
{
  unsigned int length : 3;
  unsigned int value : 5;
}

for the value one can pack a . as 0 and a - as 1

    {'.', '-'               }, // a
    {'-', '.', '.', '.'     }, // b

becomes 

   a -> length 2, value 01XXX    X is don't care (lets make X's 0

so the bit pattern : 
a -> B010 01000
b -> B100 10000
etc

for length only 1,2,3,4,5 are used, which leaves open the values 0, 6 and 7 which can be used e.g. for special modes.


Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

AWOL

Code: [Select]
buff = message[x];
        ch   = 0;
        ch   = (ch * 10) + buff;

?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ellisgl

@AWOL:
buff = message
  • ; <-- put into a variable to stop "expensive" array look ups in theory
    ch   = (ch * 10) + buff; <-- converts the character to a decimal value.

    @robtillaart:
    I'm still a n00b to C, so structs are kind of bewildering to me. As for what I did with the 6 width, this was to fix the issue of numbers - guessed I needed a terminator element in my array. (or pseudo)

AWOL

Quote
ch   = (ch * 10) + buff; <-- converts the character to a decimal value.

And the initial value of "ch" is...?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ellisgl


AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ellisgl

so If trying to compare message
  • to a integer all the time, wouldn't the char to int conversion less efficient than to do it once and compare that?

AWOL

Adding zero to anything does not change its type.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

ellisgl

Ah - so i should to store message
  • in  ch - or just hit up message
  • all the time?

AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up