Skip to content

philippe86220/morseKey

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

115 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

👉 Version française disponible ici : README_FR.MD

Morse Key Decoder

ATmega328P – Morse Key – 20x4 I2C LCD – FLASH Memory Decoding

This project implements a hardware and software Morse decoder based on an ATmega328P microcontroller, allowing:

  • input of dots and dashes using an external Morse key,
  • precise measurement of press and silence durations,
  • conversion of the Morse sequence into a binary representation,
  • lookup of the corresponding character in a constant array of structures stored in FLASH memory (PROGMEM),
  • real-time display of the decoded text on a 20x4 I2C LCD,
  • dynamic adjustment of the Morse sending speed.

The project is intentionally designed to be low-level, compact, and educational, with no dynamic memory allocation, no interrupts, and a controlled use of AVR memory resources.


Table of Contents


1. General Overview

The principle relies exclusively on time measurements:

  1. A short press on the Morse key corresponds to a dot.
  2. A long press corresponds to a dash.
  3. Dots and dashes are stored in binary form:
    • 1 = dot
    • 0 = dash
  4. A sufficiently long pause triggers the decoding of a character.
  5. An even longer pause triggers the display of a space.

The project uses:

  • no interrupts,
  • no hardware timers,
  • no dynamic memory allocation.

All logic is based on millis().


2. Hardware

2.1 Power Supply

  • 5 V power supply
  • Input via DC jack
  • Series diode 1N4007 for reverse polarity protection

2.2 Microcontroller

  • ATmega328P-PU
  • 16 MHz crystal
  • Capacitors:
    • 2 × 22 pF (oscillator)
    • 2 × 100 nF (VCC / AVCC decoupling)
  • RESET resistor: 10 kΩ to VCC

2.3 20x4 I2C LCD

  • I2C interface (PCF8574)
  • Address used: 0x27
  • Power supply: 5 V

Connections:

  • SDA → PC4 (Arduino A4)
  • SCL → PC5 (Arduino A5)
LiquidCrystal_I2C lcd(0x27, 20, 4);

2.4 Morse Key (J9)

MorseKey The Morse key is connected via a PJ-307C jack
Documentation: https://www.lcsc.com/product-detail/C16684.html

Usage is strictly equivalent to a push button:

  • Tip → PD2 (Arduino D2)
  • Sleeve → GND

Pin PD2 is configured as INPUT_PULLUP.

Behavior:

  • idle → HIGH
  • pressed → LOW

2.5 Speed Adjustment Buttons

  • PLUS button → D6 (PD6)
  • MINUS button → D7 (PD7)

Wiring:

  • button between pin and GND
  • internal pull-up enabled

2.6 Buzzer

  • Output D3 (PD3)
  • Direct drive
  • Active only while the Morse key is pressed

2.7 Pin Assignment Summary

Function Arduino ATmega328P
Morse Key D2 PD2
Buzzer D3 PD3
LCD SDA A4 PC4
LCD SCL A5 PC5
PLUS Button D6 PD6
MINUS Button D7 PD7

3. Schematic and PCB

  • Schematic: Schematic
  • Final PCB: Final PCB

4. Software Operating Principle

The code is structured in two main parts:

  • Real-time acquisition (inside loop())
  • Deferred decoding (after detecting a silence)

Dots and dashes are accumulated until a significant pause is detected.


5. Morse Timing Management

The base time unit is the dot duration:

uint32_t seuilPointTrait = 150;

Applied rules:

  • dot = 1 unit
  • dash = 3 units
  • inter-letter gap = 3 units
  • inter-word gap = 9 units

The threshold can be adjusted using the PLUS/MINUS buttons.


6. Morse Acquisition

Symbols are stored in:

static uint8_t codeMorseRecu[6];
static uint8_t y = 0;

1 = dot
0 = dash

Each key release validates one symbol.


7. Morse Code Storage in FLASH Memory

The Morse code is stored in a constant array of C++ structures, placed in program memory (FLASH) using PROGMEM.
It is a static array accessed sequentially, perfectly suited to AVR constraints.

struct struct_code {
  uint16_t caractere : 7;
  uint16_t longueur  : 3;
  uint16_t code      : 6;
};

Each structure occupies 16 bits, optimizing memory usage.


8. Decoding: Binary Conversion and PROGMEM Reading

The sequence {1,0,0,1} is converted into a binary integer using successive shifts:

resultat = (resultat << 1) | tableau[i];

Character lookup relies on:

  • the binary value,
  • and the length, which is essential to avoid ambiguities
    (e.g. I = 11 and D = 011 both yield decimal 3).

Structures are copied one by one from FLASH to RAM using memcpy_P().


9. LCD Display

  • Line 0: tempo threshold display
  • Lines 1 to 3: decoded text

The voirCaractere() function handles:

  • cursor advancement,
  • line wrapping,
  • clean screen reset.

10. simpleBouton Library

The project relies on the simpleBouton library for:

  • software debouncing,
  • reliable edge detection,
  • press and silence duration measurement.

Key functions:

  • vientDEtreRelache()
  • dureeEnfonce()
  • estRelacheDepuisPlusDe(ms)
  • estStableDepuisPlusDe(ms)

The code uses three simpleBouton inputs:

  • simpleBouton bouton(2); : main input (Morse key)
  • simpleBouton boutonPlus(6);
  • simpleBouton boutonMoins(7);

The simpleBouton library configures pins as INPUT_PULLUP.

Wiring consequence:

  • The Morse key must connect the pin to GND when pressed.

This library enables a clear and robust Morse logic.


11. Acknowledgements


Dependency: simpleBouton Library

This project uses the simpleBouton library, developed by Bricoleau.

The library is included in this repository without any modification, solely to facilitate compilation, understanding, and faithful reproduction of the project.

It is fundamental to the software architecture, as it forms the core of the Morse key temporal management mechanism.

In particular, it provides:

  • reliable detection of transitions (press / release),
  • measurement of press and silence durations,
  • management of stable button states,

all without using hardware interrupts or hardware timers, relying exclusively on millis() and a software state machine.

The entire Morse logic of the project is built on these primitives, for example:

bouton.vientDEtreRelache();
bouton.estRelacheDepuisPlusDe(...);
bouton.estStableDepuisPlusDe(...);
bouton.dureeEnfonce();

All rights related to this library remain the property of its author.


Repository Organization

  • The code/ directory contains the main Arduino sketch (.ino) as well as detailed documentation explaining its internal operation.
  • The simpleBouton/ directory contains the third-party simpleBouton library (included without modification), used for reliable button handling and press duration measurement.

To compile the project in the Arduino IDE, the simpleBouton library must be placed in the libraries/ directory of the Arduino environment, or integrated locally according to the user’s workflow.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages