/*

* MORSE KEYBOARD v0.9

*

* By Saumil Shah @therealsaumil

*

* Switch S1 will drive the red LED. When pressed the LED shall

* illuminate and when released the LED will turn off.

*

* Detect transitions - from OFF to ON and ON to OFF

* Note down the time at each transition, in milliseconds

* Record the time duration of each pulse in milliseconds

* Identify DITs and DAHs based on pulse duration

* Identify letter gaps

* Represent Morse Symbols as numbers

* Each DIT represented by 1

* Each DAH represented by 3

* So H = 1111

* I = 11

* D = 311

* I = 11

* O = 333

* T = 3

* Decode A Morse Code into an English Alphabet

* Incorporate de-bounce

*/

#include "DigiKeyboard.h"

#define SWITCH_OFF HIGH

#define SWITCH_ON LOW

// constants for pin numbers

const int switch1 = 0 ;

const int redLED = 1 ;

char alphabet [ 26 ] = {

'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'

} ;

int code [ 26 ] = {

13 , 3111 , 3131 , 311 , 1 ,

1131 , 331 , 1111 , 11 , 1333 ,

313 , 1311 , 33 , 31 , 333 ,

1331 , 3313 , 131 , 111 , 3 ,

113 , 1113 , 133 , 3113 , 3133 ,

3311

} ;

int unit ;

int dit_length , dah_length ;

int letter_gap , word_gap ;

int numeric_morse_letter ;

const int debounce = 2 ; // 2 milliseconds for debouncing

boolean stateS1 , previous_state , symbol_observed ;

unsigned long time_key_pressed , time_key_released ;

void setup ( ) {

unit = 120 ; // 10 WPM

dit_length = unit ;

dah_length = 3 * unit ;

letter_gap = 3 * unit ;

word_gap = 7 * unit ;

// initialize the LED pin as an output:

pinMode ( redLED , OUTPUT ) ;

// initialize the pushbuttons as input:

pinMode ( switch1 , INPUT_PULLUP ) ;

previous_state = SWITCH_OFF ;

symbol_observed = false ;

numeric_morse_letter = 0 ;

// send a NULL keystroke

DigiKeyboard. sendKeyStroke ( 0 ) ;

}

void loop ( ) {

stateS1 = digitalRead ( switch1 ) ;

if ( stateS1 == SWITCH_ON ) {

key_pressed ( ) ;

digitalWrite ( redLED , HIGH ) ;

}

else {

key_released ( ) ;

digitalWrite ( redLED , LOW ) ;

}

previous_state = stateS1 ;

}

void key_pressed ( ) {

if ( stateS1 != previous_state ) {

// TRANSITION - we just went from OFF to ON

time_key_pressed = millis ( ) ;

}

}

void key_released ( ) {

int position ;

if ( stateS1 != previous_state ) {

// TRANSITION - we just went from ON to OFF

time_key_released = millis ( ) ;

dit_or_dah ( time_key_released - time_key_pressed ) ;

symbol_observed = true ;

}

else {

if ( symbol_observed == true ) {

if ( millis ( ) - time_key_released > letter_gap ) {

position = search_code ( numeric_morse_letter ) ;

if ( position != 26 ) {

DigiKeyboard. println ( alphabet [ position ] ) ;

}

else {

DigiKeyboard. println ( '?' ) ;

}

numeric_morse_letter = 0 ;

symbol_observed = false ;

}

}

}

}

void dit_or_dah ( unsigned long t ) {

char symbol = '?' ;

// if the width is less than debounce delay, then do nothing

if ( t <= debounce ) {

return ;

}

if ( t <= dit_length * 2 ) {

symbol = '.' ;

numeric_morse_letter = numeric_morse_letter * 10 ;

numeric_morse_letter = numeric_morse_letter + 1 ;

}

if ( t > dah_length * 0.75 ) {

symbol = '-' ;

numeric_morse_letter = numeric_morse_letter * 10 ;

numeric_morse_letter = numeric_morse_letter + 3 ;

}

DigiKeyboard. print ( symbol ) ;

}

// Function to look up a numeric morse code pattern

// and return its index position

int search_code ( int n ) {

int index = 0 ;

while ( index < 26 ) {

if ( n == code [ index ] ) {

break ;

}

index = index + 1 ;

}

return ( index ) ;