morse_codec

Module decoder

Source
Expand description

Live decoder for morse code that converts morse code to characters. Supports real-time decoding of incoming signals and decoding prepared morse signals. This module supports Farnsworth timing mode and can be used for morse code practice.

Receives morse signals and decodes them character by character to create a char array (charray) message with constant max length. Empty characters will be filled with the const FILLER and decoding errors will be filled with DECODING_ERROR_CHAR. Trade-offs to support no_std include:

  • No vectors or any other type of dynamic heap memory used, all data is plain old stack arrays.

  • We decode the signals character by character instead of creating a large buffer for all signals and decoding it at the end. As a result, if an initial reference short duration is not provided, there’s a problem with words starting with ‘T’ decoding as different characters. This is a problem because we can’t determine the length of spaces (low signals) after the high signal being long with only one signal as reference. Creating a large buffer would fix this, because we could audit the entire signal buffer to iron out wrong decodings, but the large size of the buffer would not fit into small RAM capacities of certain 8 bit MCUs like AVR ATmega328P with SRAM size of 2KB and even smaller sizes for simpler chips. So we clear the buffer every time we add a character.

    One way to fix the wrong decoding problems of ‘T’ character is to provide an initial reference short signal length to the decoder. A good intermediate value is 100 milliseconds.

use morse_codec::decoder::Decoder;

const MSG_MAX: usize = 64;
let mut decoder = Decoder::<MSG_MAX>::new()
    .with_reference_short_ms(90)
    .build();

// We receive high signal from button. 100 ms is a short dit signal because reference_short_ms is 90
// ms, default tolerance range factor is 0.5. 90 ms falls into 100 x 0.5 = 50 ms to 100 + 50 = 150 ms.
// So it's a short or dit signal.
decoder.signal_event(100, true);
// We receive a low signal from the button. 80 ms low signal is a signal space dit.
// It falls between 50 and 150.
decoder.signal_event(80, false);
// 328 ms high long signal is a dah. 328 x 0.5 = 164, 328 + 164 = 492.
// Reference short signal 90 x 3 (long signal multiplier) = 270. 270 falls into the range.
decoder.signal_event(328, true);
// 412 ms low long signal will end the character.
decoder.signal_event(412, false);
// At this point the character will be decoded and added to the message.

// Resulting character will be 'A' or '.-' in morse code.
let message = decoder.message.as_str();
assert_eq!(message, "A");

Structs§

  • This is the builder, or public interface of the decoder using builder pattern. It builds a MorseDecoder which is the concrete implementation and returns it with build(). For details on how to use the decoder, refer to MorseDecoder documentation.
  • This is the concrete implementation of the decoder.

Enums§

  • Decoding precision is either Lazy, Accurate or Farnsworth(speed_reduction_factor: f32).