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

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

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

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

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 362
Posts: 17307
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Lefty
Logged

USA, IN
Offline Offline
Newbie
*
Karma: 0
Posts: 26
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

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

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

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
Logged

NZ
Offline Offline
Sr. Member
****
Karma: 0
Posts: 390
Turtle in a hard shell
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley

Code:
/*
* 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);
}
Logged

Pages: [1]   Go Up
Jump to: