vismaymuthukad
Published © GPL3+

Arduino Telegraph

It is a model of a working telegraph. Uses and converts morse code

IntermediateFull instructions provided1,309
Arduino Telegraph

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
LED (generic)
LED (generic)
×2
Resistor 1k ohm
Resistor 1k ohm
×2
Active Buzzer
×2
Limit Switch, 5 A
Limit Switch, 5 A
or you can also use a push button
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Custom parts and enclosures

Necessary File

Add this file to the source folder and rename it "Fifo.h"..

Schematics

Diagram

Diagram

I added a Push Button in the diagram. You can also use a limit switch..

Code

Code

C/C++
//  Needs Fifo.h (Queue functions) copied into the sketch folder
#include "Fifo.h"
Fifo<char> symbolQueue( 160 )  ;

const uint8_t led = 2;
const uint8_t ledPin = 3; 
const uint8_t buz = 4;
const uint8_t buzPin = 5;
const int inputPin = 6;

String code = "";

// To increase speed, change '50' to a smaller number..
// To decrease speed, change '50' to a larger number..
const unsigned long  MsecDot   = 50;
const unsigned long  MsecDash  = MsecDot * 3;
const unsigned long  MsecSym   = MsecDot;
const unsigned long  MsecLtr   = MsecDot * 3;
const unsigned long  MsecWord  = MsecDot * 7;

String letters[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                    ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
                    "-----"  , ".----"  , "..---"  , "...--"  , "....-" , "....." , "-...."  , "--..." , "---.." , "----." , "E"  };// Morse letters (26) followed by numbers(10)
                  
void convertor(){

  int i = 0;
  if (code == ".-.-.-")
  {
    Serial.print(".");
  }
  else
  {
    while (letters[i] != "E")
    {
      if (letters[i] == code)
      {
        if ( i >= 0 && i <= 25 ) Serial.print(char('A' + i));
        else if ( i >= 26 && i <= 35 ) Serial.print(char('0' + i - 26 ));
        break;
      }
      i++;
    }
    if (letters[i] == "E")
    {
      Serial.println("");
    }
  }
  code = "";
}

bool  getKey() {
  // get debounced key press
  static bool currentKeyState = HIGH ;
  static bool newKeyState = HIGH ;
  static uint32_t newKeyStateAtMs = millis()  ;

  bool dr =  digitalRead(inputPin) ;
  if ( dr != newKeyState ) {
    newKeyState = dr ;
    newKeyStateAtMs = millis() ;
  }
  if ( currentKeyState != newKeyState && millis() - newKeyStateAtMs > 25 ) {
    // debounce: accept only a mature change ( > X ms )
    currentKeyState = newKeyState ;
  }
  return currentKeyState ;
}

void decoder() {
  
  static bool lastKey = HIGH ;
  static uint32_t lastTranstionAtMs = millis() ;
  static bool inLetter = false ;
  static bool inWord = false ;

  uint32_t ms = millis() ;

  digitalWrite( ledPin, !getKey() ) ;
  digitalWrite( buzPin, !getKey() ) ;
  
  if ( getKey() != lastKey ) {
    // transition
    if ( lastKey == LOW ) {
      // we were in a symbol - determine if it was a '.' or a '-'
      code += ( ms - lastTranstionAtMs < MsecDot * 2 ? '.' : '-' ) ;
    }  else {
      // we were in a space
      inLetter = true ;
      inWord = true ;
    }
    lastTranstionAtMs = ms ;
    lastKey = getKey() ;
  }

  if ( getKey() == HIGH ) {
    // we are in a space
    if ( inLetter && ms - lastTranstionAtMs > MsecLtr ) {
      // flush out letter
      convertor() ;
      inLetter = false ;
    }
    if ( inWord && ms - lastTranstionAtMs > MsecWord ) {
      // flush out word
      Serial.print(" " ) ;
      inWord = false ;
    }
  }
}    
   
void charToMorse( char mChar ) {
  // converts input character to a set of morse symbols which are pushed onto a 
  // queue together with an end of character marker '|'
          
  uint8_t offset ;   // offset into table letters[] based on ascii code of char
  bool inTable = false ;

  if ( mChar >= 'a' && mChar <= 'z' ) {
    offset = mChar - 97 ;
    inTable = true ;
  }
  else if ( mChar >= 'A' && mChar <= 'Z' ) {
    offset = mChar - 64 ;
    inTable = true ;
  }
  else if ( mChar >= '0' && mChar <= '9' ) {
    offset = (mChar - 48) + 26 ;
    inTable = true ;
  }
  else {}

  if ( inTable ) {  
   // Serial.print( letters[ offset ] ) ;
    for ( uint8_t i = 0 ; i < letters[ offset ].length() ; i++ ) symbolQueue.push( letters[ offset ].charAt( i )   ) ;
    symbolQueue.push( '|' ) ;
  }
  else if ( mChar == ' ' ) {
    // Serial.print( '|' ) ;
    symbolQueue.push( '|' ) ;
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buz, OUTPUT);  
  pinMode(buzPin, OUTPUT);
  pinMode(inputPin, INPUT_PULLUP);
  Serial.println("Start");
  symbolQueue.flush() ;
}

void loop() {
  enum state_t { inDot, inDash, inSpace, inWaiting } ;
  static state_t state = inWaiting ;
  static uint32_t inStateAtMs = millis() ;
  
  // get input from user, analyse, convert to morse symbols and queue
  if (Serial.available()) {
    char inChar = Serial.read() ;
    charToMorse( inChar ) ;
  }

  // finite state machine - unload queue and sound buzzer as required

  switch ( state ) {

    case inWaiting : {
        if ( ! symbolQueue.isempty() ) {
          char inCh = symbolQueue.pop() ;
          // debug
          Serial.print( inCh ) ; 
           
          inStateAtMs = millis() ;
          if ( inCh == '.' ) {
            digitalWrite(led, HIGH);
            digitalWrite(buz, HIGH);
            state = inDot ;
          }
          else if ( inCh == '-' ) {
            digitalWrite(led, HIGH);
            digitalWrite(buz, HIGH);
            state = inDash ;
          }
          else if ( inCh == '|' ) {
            state = inSpace ;
          }
        }
        break ;
      }

    case inDot : {
        if ( millis() - inStateAtMs > MsecDot ) {
          inStateAtMs = millis() ;
          digitalWrite(led, LOW);
          digitalWrite(buz, LOW);
          state = inSpace ;
        }
        break ;
      }

    case inDash : {
        if ( millis() - inStateAtMs > MsecDash  ) {
          inStateAtMs = millis() ;
          digitalWrite(led, LOW);
          digitalWrite(buz, LOW);
          state = inSpace ;
        }
        break ;
      }

    case inSpace : {
        if ( millis() - inStateAtMs > MsecLtr  ) {
          inStateAtMs = millis() ;
          digitalWrite(led, LOW);
          digitalWrite(buz, LOW);
          state = inWaiting ;
        }
        break ;
      }
  }
  
  decoder() ;
}

Credits

vismaymuthukad

vismaymuthukad

0 projects • 0 followers

Comments