| ??? 10/08/06 14:11 Modified: 10/08/06 14:30 Read: times Msg Score: +1 +1 Good Answer/Helpful |
#126011 - Morse Code Decoding Hints Responding to: ???'s previous message |
Hello Arif,
I did this a long time ago. Here are the basic steps:
1. Make a table in RAM that keeps track of the duration of each
ON time and each OFF time. The ON times will correspond to
the dots and the dashes, and the OFF times will correspond to
the silent periods between the dots and the dashes.
ON or OFF Time
----------------
ON 51
OFF 47
ON 142
OFF 151
ON 50
OFF 48
ON 162
OFF 51
ON 48
OFF 143
ON 51
OFF 45
ON 49
OFF 153
ON 45
OFF 52
ON 46
OFF 51
ON 151
OFF 55
ON 59
OFF 160
The entries in the table will always alternate ON OFF ON OFF
ON OFF ...
A dash is supposed to be three times as long as a dot. The
space between dots and dashes is supposed to be the same as a
dot. The space between letters is supposed to be the same as
a dash. So in the example above, the dot time is about 50,
and the dash time is about 150.
The table should be long enough to hold several seconds worth
of information. At each transition of the input signal, throw
away the oldest entry in the table and add a new one. That
way, the table always contains the ON and OFF times for the
most recent few seconds of input.
2. Every time you make a new addition to the table, examine the
table to determine the average dot time and the average dash
time. Once you know these numbers, you can set a threshold
halfway between them. Any ON time smaller than the threshold
is a dot, and any ON time longer than the threshold is a dash.
If the speed of the incoming data changes slowly, the
threshold will also change slowly and everything will work
fine. However, if the speed of the incoming data changes
quickly, then the decoder will lose synchronization until the
table fills up with entries at the new speed. At that point
it will start to work again.
3. Every time you see an OFF time that is longer than the
threshold, you know you have found a space beteween two
letters. At that point, you can look at the ON times in the
table following the previous letter to decode the letter than
you just received. If the OFF time is much longer than
the treshold, then you have found a space between words and
you should output a blank character as well.
That's the basic idea. Now, Step #2 is the tricky one. If you
can do Step #2, then the rest is easy. How do you determine the
average dot time and the average dash time? Here is one idea:
1. Copy the times from the table to a separate list and sort them
in order from smallest to largest.
2. Starting at the beginning, scan through the sorted list and
look for the magic spot where the next value is greater than
twice the average of all the previous values.
3. The average of all the times before the magic spot is the
average dot time. The average of all the times after the
magic spot is the average dash time.
As near as I can remember, that's the method I used when I did
this a long time ago.
The code that follows shows another approach. I developed it to
divide blood cell images into two groups (big ones and little
ones) by area, but it should work equally well to divide Morse
code signals into two groups (dots and dashes) by time.
-- Russ
/* ////////////////////////////////////////////////////////////////////////////
tfinder.cpp
///////////////////////////////////////////////////////////////////////////////
DESCRIPTION: This module contains Russ's threshold finder.
REVISIONS: 8 Feb 01 - RAC - Genesis
//////////////////////////////////////////////////////////////////////////// */
#include "stdafx.h"
#include "tfinder.h"
/* ////////////////////////////////////////////////////////////////////////////
FindThreshold()
///////////////////////////////////////////////////////////////////////////////
DESCRIPTION: This function automatically calculates a threshold value for
discriminating two populations that are assumed to lie within a
set of data. For example, if the given batch of data contains
leukocyte areas, this function will find the area threshold
for discriminating lymphocytes (which are small) from other
(larger) cells.
METHOD: Here's how this function works, explained in terms of the cell
area example:
A. Pick an arbitrary threshold T somewhere between the
smallest and biggest cells observed.
B. Place the cells with areas greater than T in population B
and those with areas less than or equal to T in population
S.
C. Calculate the mean size of the cells in population B.
D. Repeat for population S.
E. Calculate the sum of the absolute values of the differences
between the sizes of the cells in population B and
population B's mean cell size. Call this number Deviation
B.
F. Repeat for population S. Call the result Deviation S.
G. Calculate a Total Deviation = Deviation B + Deviation S.
H. Repeat steps A through G for all possible threshold values.
I. Choose the threshold value which produces the smallest
Total Deviation as the one that best separates the two
populations.
NOTE: Pay particular attention to the "greater than" and "less than
or equal to" provisions of Step B.
REVISIONS: 8 Feb 01 - RAC - Genesis, with hints from some Excel spread-
sheets used to develop the idea.
//////////////////////////////////////////////////////////////////////////// */
int FindThreshold(int *pData, int count) {
int minValue; /* Minimum data value */
int maxValue; /* Maximum data value */
int i; /* A generic integer */
int currentThreshold;
int minThreshold;
int currentTotalDeviation;
int minTotalDeviation;
int bigMean; /* Mean of big population */
int smallMean; /* Mean of small population */
int bigCount; /* Size of big population */
int smallCount; /* Size of small population */
/* Make an initial pass through the data to find the minimum and maximum
values. */
maxValue = INT_MIN; /* Set min and max to */
minValue = INT_MAX; /* incredible values */
for (i=0; i<count; i++) { /* For each data item */
if (pData[i] < minValue) { /* Remember it if it's the */
minValue = pData[i]; /* new minimum value */
}
if (pData[i] > maxValue) { /* Remember it if it's the */
maxValue = pData[i]; /* new maximum value */
}
} /* End 'for each data item' */
/* For each possible threshold value, calculate the Total Deviation. At the
same time, be sure to keep track of which threshold value resulted in the
smallest Total Deviation. */
minTotalDeviation = INT_MAX; /* Inz to incredible value */
for (currentThreshold = minValue; /* For all possible */
currentThreshold < maxValue; /* threshold values */
currentThreshold++) {
/* Rattle through the data to find the sizes and means of the two
populations. */
bigMean = smallMean = 0; /* No items summed yet */
bigCount = smallCount = 0; /* No items counted yet */
for (i=0; i<count; i++) { /* For each data item */
if (pData[i] > currentThreshold) { /* Place in the appropriate */
bigMean += pData[i]; /* population, depending on */
bigCount++; /* whether or not it is */
} /* above the threshold */
else {
smallMean += pData[i];
smallCount++;
}
} /* End 'for each data item' */
bigMean = (bigMean + (bigCount / 2)) / /* Calculate the actual mean */
bigCount; /* values here */
smallMean = (smallMean + (smallCount /
2)) / smallCount;
/* Now pass through the data once more to find the Total Deviation for the
current threshold. */
currentTotalDeviation = 0; /* No deviations yet */
for (i=0; i<count; i++) { /* For each data item */
if (pData[i] > currentThreshold) { /* Sum the difference twixt */
currentTotalDeviation += /* the data value and the */
abs(pData[i] - bigMean); /* mean of its population. */
}
else {
currentTotalDeviation +=
abs(pData[i] - smallMean);
}
} /* End 'for each data item' */
if (currentTotalDeviation < /* Track the smallest Total */
minTotalDeviation) { /* Deviation observed along */
minTotalDeviation = /* with the threshold value */
currentTotalDeviation; /* that produced it. */
minThreshold = currentThreshold;
}
} /* End 'for all thresholds' */
return minThreshold; /* The answer */
} /* End FindThreshold() */
|
| Topic | Author | Date |
| Morse Code Decoding Algorithm | 01/01/70 00:00 | |
| ooh thats a hard one | 01/01/70 00:00 | |
| having said that | 01/01/70 00:00 | |
| Autobaud it to death | 01/01/70 00:00 | |
| Morse Code Decoding Hints | 01/01/70 00:00 | |
| Thanks | 01/01/70 00:00 | |
| You're Welcome | 01/01/70 00:00 | |
| QRZ QRZ QRZ | 01/01/70 00:00 | |
We had a product... | 01/01/70 00:00 |



