Go Down

Topic: Morse decoder and password checker (Read 2056 times) previous topic - next topic

Josh Myer

I wrote a program that decodes morse code from a button on digital2, and sets a pin high when you've keyed in a password.  This is meant to let me in the front gate of my apartment building without needing physical keys.

I'd like to share the code, but i'm not sure where to put it.  Where does that sort of thing go?

(This is my first arduino project, and: wow!  What a slick little platform!  In 6 hours, I went from never having used it before to having a finished product.)

Josh Myer

I've seen a few people posting code, so here's mine.  I'd use the "format for forum" but it's throwing an exception.  I blame the structure of my code, which is very much programming by accident.

It's messy, but it (mostly) works.  I'm posting the current state as an inspiration for others.

/*
* Morse Code Decoder and door opener
*
* Josh Myer <josh@joshisanerd.com>
*
* 20090103 rev 0 -- ugly and unfortunate, but mostly functional (my first arduino code)
*
* Hook a debounced switch up to digital pin 2, like you would for the Button demo.
*
* This code reads morse code from digital02, turning it into ASCII characters.
* If you key in "SOS" (... --- ...), it will turn on the LED on digital13.
*
* The intended application is to let me key in a password at my apartment's
* front gate and have it automatically let me into the building, instead of
* fumbling around for keys.
*
* There's still lots of stuff to do and clean up, but I wanted to share the idea
* and the current implementation to help spur people on.
*/

#include <avr/pgmspace.h>
#include <string.h>

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for a pushbutton)
int val = 0;                    // variable for reading the pin status

#define THRESHOLD 3
#define DELAY_TIME 10 // ms

int n_since_zero = 0;
int n_in_zero = 0;

#define NCHARS 26+10+3

char morse_chars[NCHARS]  = {
 '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',
 '.',
 ',',
 '?',

};

char* morse_strings[NCHARS] = {
 ".-",
 "-...",
 "-.-.",
 "-..",
 ".",
 "..-.",
 "--.",
 "....",
 "..",
 ".---",
 "-.-",
 ".-..",
 "--",
 "-.",
 "---",
 ".--.",
 "--.-",
 ".-.",
 "...",
 "-",
 "..-",
 "...-",
 ".--",
 "-..-",
 "-.--",
 "--..",
 "-----",
 ".----",
 "..---",
 "...--",
 "....-",
 ".....",
 "-....",
 "--...",
 "---..",
 "----.",
 ".-.-.-",
 "--..--",
 "..--..",
};



#define PAUSE 0
#define DIT 1
#define DAH 2
#define DDLEN 5

char passwd[] = "SOS";

char chars_rx[10];
int char_cursor= 0;

int ditsdahs[DDLEN];
int dd_cursor = 0;

void setup() {
 pinMode(ledPin, OUTPUT);      // declare LED as output
 pinMode(inputPin, INPUT);     // declare pushbutton as input

 for (int i = 0; i < DDLEN; i++) {
   ditsdahs = 0;
 }
 dd_cursor = 0;


 for (int i = 0; i < 10; i++) {
   chars_rx = 0;
 }
 char_cursor = 0;


 Serial.begin(9600);
}

void dd_print() {
 Serial.print("  > DD BUF: ");
 for(int i = 0; i < DDLEN; i++) {
   Serial.print(ditsdahs);
   Serial.print(", ");
 }
 Serial.println();
}

boolean dd_eq(char*buf) {
 if(ditsdahs[0] == PAUSE) return false;

 int i;

 for(i = 0; ditsdahs != PAUSE && i < DDLEN; i++) {
   if (ditsdahs == DIT && buf == '-') {
     return false;
   }
   if (ditsdahs == DAH && buf == '.') {
     return false;
   }
 }

 /*
 Serial.print("Got to the end of ");
  Serial.print(buf);
  Serial.print("; checking strlen=");
  Serial.print(strlen(buf));
  Serial.print(" == i=");
  Serial.println(i);
  */
 if (i != strlen(buf)) return false;

 return true;
}

void dd_decode() {
 for(int i = 0; i < NCHARS; i++) {
   /*
   Serial.print("dd_decode: check i=");
    Serial.print(i);
    Serial.print(" , string=\"");
    Serial.print(morse_strings);
    Serial.print("\", c=");
    Serial.print(morse_chars);
    Serial.println();
    */
   if (dd_eq(morse_strings)) {

     char c = morse_chars;

     char_emit(c);


     break;
   }
 }

 for (int i = 0; i < DDLEN; i++) {
   ditsdahs = 0;
 }
 dd_cursor = 0;
}

void check_passwd() {

 Serial.print("Check password: ");
 Serial.print(chars_rx);
 Serial.println();

 if (0 != strstr(chars_rx, passwd)) {
   digitalWrite(ledPin, HIGH);
 }

 /*
 for (int i = 0; i < 10; i++) {
  chars_rx = 0;
  }
  char_cursor = 0;
  */
}

void char_emit(char c) {
 Serial.print("Got a char: c=");

 Serial.println(c);


 chars_rx[char_cursor] = c;
 char_cursor++;

 if (char_cursor >= strlen(passwd)) {
   check_passwd();
 }
}

void dd_emit(int v) {
 ditsdahs[dd_cursor] = v;
 dd_cursor++;

 dd_print();

 if (v == PAUSE)
   dd_decode();
}

void dit()   {
 dd_emit(DIT);
 Serial.println("DIT");
}
void dah()   {
 dd_emit(DAH);
 Serial.println("DAH");
}
void pause() {
 dd_emit(PAUSE);
 Serial.println("PAUSE");
}

void loop(){
 val = digitalRead(inputPin);  // read input value

 if (val == LOW) {
   if (n_since_zero > 5) {
     /*  Serial.print("CROSS LOW AFTER ");
      Serial.println(n_since_zero);
      */
     if (n_since_zero > 16) {
       dah();
     }
     else {
       dit();
     }


   }

   n_since_zero = 0;
   n_in_zero++;
 }
 else {
   n_since_zero++;
 }

 if (n_in_zero == 20) {
   pause();
 }

 if (n_since_zero > THRESHOLD) {
   if (n_in_zero > 0) {
     // Serial.print("CROSS HIGH AFTER ");
     //Serial.print(" > ");
     // Serial.println(n_in_zero);

     //      Serial.println("**************************");
   }

   n_in_zero = 0;
   // digitalWrite(ledPin, HIGH);
 }
 else {
   // digitalWrite(ledPin, LOW);
 }

 delay(DELAY_TIME);
}

retrolefty

Wow, what a unique application. Thanks for sharing it. Be sure to keep us posted on progress.

Lefty

Peter

Really good idea, Josh.

About sharing your code, you might want to consider one of the many free code hosting alternatives, like github, google code or the more traditional sourceforge.

kb1isp

Also there's a '#' on the text editor (at least in google chrome running XP). You might want to look into it.

TechDante

thank you so much for this was trying to figure out how to do this as i want to use this a build a morse code computer keyboard (tapping out morse code will input text on pc) as a way to help learn morse code though use and practive

WanaGo

Nice work
I just wrapped your code up in the forum friendly code displayer (the little # button above when you post)
Just so its easier to read.

Top job :)

Code: [Select]
/*
* Morse Code Decoder and door opener
*
* Josh Myer <josh@joshisanerd.com>
*
* 20090103 rev 0 -- ugly and unfortunate, but mostly functional (my first arduino code)
*
* Hook a debounced switch up to digital pin 2, like you would for the Button demo.
*
* This code reads morse code from digital02, turning it into ASCII characters.
* If you key in "SOS" (... --- ...), it will turn on the LED on digital13.
*
* The intended application is to let me key in a password at my apartment's
* front gate and have it automatically let me into the building, instead of
* fumbling around for keys.
*
* There's still lots of stuff to do and clean up, but I wanted to share the idea
* and the current implementation to help spur people on.
*/

#include <avr/pgmspace.h>
#include <string.h>

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for a pushbutton)
int val = 0;                    // variable for reading the pin status

#define THRESHOLD 3
#define DELAY_TIME 10 // ms

int n_since_zero = 0;
int n_in_zero = 0;

#define NCHARS 26+10+3

char morse_chars[NCHARS]  = {
'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',
'.',
',',
'?',

};

char* morse_strings[NCHARS] = {
".-",
"-...",
"-.-.",
"-..",
".",
"..-.",
"--.",
"....",
"..",
".---",
"-.-",
".-..",
"--",
"-.",
"---",
".--.",
"--.-",
".-.",
"...",
"-",
"..-",
"...-",
".--",
"-..-",
"-.--",
"--..",
"-----",
".----",
"..---",
"...--",
"....-",
".....",
"-....",
"--...",
"---..",
"----.",
".-.-.-",
"--..--",
"..--..",
};



#define PAUSE 0
#define DIT 1
#define DAH 2
#define DDLEN 5

char passwd[] = "SOS";

char chars_rx[10];
int char_cursor= 0;

int ditsdahs[DDLEN];
int dd_cursor = 0;

void setup() {
pinMode(ledPin, OUTPUT);      // declare LED as output
pinMode(inputPin, INPUT);     // declare pushbutton as input

for (int i = 0; i < DDLEN; i++) {
  ditsdahs[i] = 0;
}
dd_cursor = 0;


for (int i = 0; i < 10; i++) {
  chars_rx[i] = 0;
}
char_cursor = 0;


Serial.begin(9600);
}

void dd_print() {
Serial.print("  > DD BUF: ");
for(int i = 0; i < DDLEN; i++) {
  Serial.print(ditsdahs[i]);
  Serial.print(", ");
}
Serial.println();
}

boolean dd_eq(char*buf) {
if(ditsdahs[0] == PAUSE) return false;

int i;

for(i = 0; ditsdahs[i] != PAUSE && i < DDLEN; i++) {
  if (ditsdahs[i] == DIT && buf[i] == '-') {
    return false;
  }
  if (ditsdahs[i] == DAH && buf[i] == '.') {
    return false;
  }
}

/*
Serial.print("Got to the end of ");
 Serial.print(buf);
 Serial.print("; checking strlen=");
 Serial.print(strlen(buf));
 Serial.print(" == i=");
 Serial.println(i);
 */
if (i != strlen(buf)) return false;

return true;
}

void dd_decode() {
for(int i = 0; i < NCHARS; i++) {
  /*
  Serial.print("dd_decode: check i=");
   Serial.print(i);
   Serial.print(" , string=\"");
   Serial.print(morse_strings[i]);
   Serial.print("\", c=");
   Serial.print(morse_chars[i]);
   Serial.println();
   */
  if (dd_eq(morse_strings[i])) {

    char c = morse_chars[i];

    char_emit(c);


    break;
  }
}

for (int i = 0; i < DDLEN; i++) {
  ditsdahs[i] = 0;
}
dd_cursor = 0;
}

void check_passwd() {

Serial.print("Check password: ");
Serial.print(chars_rx);
Serial.println();

if (0 != strstr(chars_rx, passwd)) {
  digitalWrite(ledPin, HIGH);
}

/*
for (int i = 0; i < 10; i++) {
 chars_rx[i] = 0;
 }
 char_cursor = 0;
 */
}

void char_emit(char c) {
Serial.print("Got a char: c=");

Serial.println(c);


chars_rx[char_cursor] = c;
char_cursor++;

if (char_cursor >= strlen(passwd)) {
  check_passwd();
}
}

void dd_emit(int v) {
ditsdahs[dd_cursor] = v;
dd_cursor++;

dd_print();

if (v == PAUSE)
  dd_decode();
}

void dit()   {
dd_emit(DIT);
Serial.println("DIT");
}
void dah()   {
dd_emit(DAH);
Serial.println("DAH");
}
void pause() {
dd_emit(PAUSE);
Serial.println("PAUSE");
}

void loop(){
val = digitalRead(inputPin);  // read input value

if (val == LOW) {
  if (n_since_zero > 5) {
    /*  Serial.print("CROSS LOW AFTER ");
     Serial.println(n_since_zero);
     */
    if (n_since_zero > 16) {
      dah();
    }
    else {
      dit();
    }


  }

  n_since_zero = 0;
  n_in_zero++;
}
else {
  n_since_zero++;
}

if (n_in_zero == 20) {
  pause();
}

if (n_since_zero > THRESHOLD) {
  if (n_in_zero > 0) {
    // Serial.print("CROSS HIGH AFTER ");
    //Serial.print(" > ");
    // Serial.println(n_in_zero);

    //      Serial.println("**************************");
  }

  n_in_zero = 0;
  // digitalWrite(ledPin, HIGH);
}
else {
  // digitalWrite(ledPin, LOW);
}

delay(DELAY_TIME);
}

Go Up