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