Home |
Search |
Today's Posts |
#11
![]() |
|||
|
|||
![]()
On Tue, 30 Dec 2003 20:10:53 +0800, "Richard Hosking"
wrote: Wolfgang Thanks for your reply Richard, I will dig into my paper piles - I do have a very small and tiny Basic source with a flow chart, published years ago. I wanted to write this, but time went by and in the meantime ready built software is available in the net. Stay tuned - I will post it. 73s and DX for 2004 Wolfgang OE1MWW |
#12
![]() |
|||
|
|||
![]()
Disclaimer: I've never decoded morse in my life, so most of what I write is
educated guessing. For my master's thesis I built a receiver that demodulated 400 baud MSK. The RF chain delivered a signal centered around 2kHz to a 68HC11 which sampled at 6400Hz and demodulated the data entirely in software -- and it only had 2k bytes of code space. Granted, it was all in assembly, and it used 94% of the available processor time to do it, but it did work. In spite of having some really ugly compromises in the signal processing (the sampling rate was really too low, and the only "multiply" was to add, not add, or subtract from an accumulator) the receiver had performance within a dB of the theoretical optimum. I think with something modern like an AVR or a PIC a 16-baud OOK signal should be possible (fun, too). OK, so you still have the problem with the math. Consider using not one, but two comparators to square up your signal, so a "non-signal" rarely gets above the threshold. You're back to needing AGC (at least to set the comparator), but you can close the loop in your software by looking at the comparator outputs for the right signatures (too much output = too low threshold, too little output = too high threshold), and set the threshold from the uP. With a good signal to noise ratio this should have a nice broad center to it that'll be easy to find. With a good narrow CW filter your signal to noise ratio will get better... Once your threshold is set you can integrate the "buzz" from the comparators to see if you're receiving a carrier. You should probably integrate for some period of time (the length of the fastest code you want to receive would be good, it'd give you a sorta-kinda-matched filter) and take the presense of signal 1/2 of the time to indicate the transmitter is "on". I like the idea of using the dibits to form a PLL, but for receiving bad code at an unknown rate you'd probably be better off making a little histogram of the on and off times of the code. You should be able to see two peaks in the histogram for "on" corresponding to dot and dash, and three for "off" corresponding to intra-letter, inter-letter and inter-word spacing. At this point you can start looking for dashes, dots, and spaces (maybe going back over your data to catch the beginning of the message, if you have enough RAM) and decoding words. You could also estimate the speed of the code that you're receiving and feed it back to your KSMF (that's kinda-sorta-matched filter, of course) for better noise figure. Once you have your stream of dashes, dots, inter-charater and inter-word spaces you can separate the charaters, look them up in a table and just reject anything that doesn't seem to fit. I suspect that your performance would be pretty good at this point, and if not the theoretical ne-plus-ultra of decoders it would be better at receiving the lousy senders than Wofgang's. "Richard Hosking" wrote in message u... Wolfgang Thanks for your reply I am not very sophisticated mathematically and I have not studied communication theory. Your article is most helpful. However it looks as |
#13
![]() |
|||
|
|||
![]()
Disclaimer: I've never decoded morse in my life, so most of what I write is
educated guessing. For my master's thesis I built a receiver that demodulated 400 baud MSK. The RF chain delivered a signal centered around 2kHz to a 68HC11 which sampled at 6400Hz and demodulated the data entirely in software -- and it only had 2k bytes of code space. Granted, it was all in assembly, and it used 94% of the available processor time to do it, but it did work. In spite of having some really ugly compromises in the signal processing (the sampling rate was really too low, and the only "multiply" was to add, not add, or subtract from an accumulator) the receiver had performance within a dB of the theoretical optimum. I think with something modern like an AVR or a PIC a 16-baud OOK signal should be possible (fun, too). OK, so you still have the problem with the math. Consider using not one, but two comparators to square up your signal, so a "non-signal" rarely gets above the threshold. You're back to needing AGC (at least to set the comparator), but you can close the loop in your software by looking at the comparator outputs for the right signatures (too much output = too low threshold, too little output = too high threshold), and set the threshold from the uP. With a good signal to noise ratio this should have a nice broad center to it that'll be easy to find. With a good narrow CW filter your signal to noise ratio will get better... Once your threshold is set you can integrate the "buzz" from the comparators to see if you're receiving a carrier. You should probably integrate for some period of time (the length of the fastest code you want to receive would be good, it'd give you a sorta-kinda-matched filter) and take the presense of signal 1/2 of the time to indicate the transmitter is "on". I like the idea of using the dibits to form a PLL, but for receiving bad code at an unknown rate you'd probably be better off making a little histogram of the on and off times of the code. You should be able to see two peaks in the histogram for "on" corresponding to dot and dash, and three for "off" corresponding to intra-letter, inter-letter and inter-word spacing. At this point you can start looking for dashes, dots, and spaces (maybe going back over your data to catch the beginning of the message, if you have enough RAM) and decoding words. You could also estimate the speed of the code that you're receiving and feed it back to your KSMF (that's kinda-sorta-matched filter, of course) for better noise figure. Once you have your stream of dashes, dots, inter-charater and inter-word spaces you can separate the charaters, look them up in a table and just reject anything that doesn't seem to fit. I suspect that your performance would be pretty good at this point, and if not the theoretical ne-plus-ultra of decoders it would be better at receiving the lousy senders than Wofgang's. "Richard Hosking" wrote in message u... Wolfgang Thanks for your reply I am not very sophisticated mathematically and I have not studied communication theory. Your article is most helpful. However it looks as |
#14
![]() |
|||
|
|||
![]()
"Richard Hosking" wrote in message
u... I am not very sophisticated mathematically and I have not studied communication theory. Your article is most helpful. However it looks as though it might be somewhat hard to implement in a small/slow codespace such as a microcontroller. (It may well be impossible to do this job in such a device.) In the August '98 QST, IK3OIL published an article on a CW decoder based on a PIC16F84, which may well be, by today's standards, the most limited microcontroller in use by hobbyists. (Well, I suppose you could tie one hand behind your back by adding a Basic compiler on top of it or something like that!) That particular device, while far from perfect, works a lot better than the various PC based programs that I've tried. Last I looked, he still had most of the information on his web site. I know others have done work to improve on his program, but I don't know of any of that work that has been published. One nasty feature is that a long series of dahs can greatly confuse his algorithm and it can take a while to recover from that. Were you to implement his algorithm in a '628 or something like that, or even to simply replace the rather lengthy code he has around displaying the speed with a little more work on the algorithm, I'm sure it could be improved. He did use an external decoder to recognize the CW signal, a 567 or something of that ilk. Some folks have worked on that end, too. It seems like there should be a better approach, but I haven't seen anything dramatically better. ... |
#15
![]() |
|||
|
|||
![]()
"Richard Hosking" wrote in message
u... I am not very sophisticated mathematically and I have not studied communication theory. Your article is most helpful. However it looks as though it might be somewhat hard to implement in a small/slow codespace such as a microcontroller. (It may well be impossible to do this job in such a device.) In the August '98 QST, IK3OIL published an article on a CW decoder based on a PIC16F84, which may well be, by today's standards, the most limited microcontroller in use by hobbyists. (Well, I suppose you could tie one hand behind your back by adding a Basic compiler on top of it or something like that!) That particular device, while far from perfect, works a lot better than the various PC based programs that I've tried. Last I looked, he still had most of the information on his web site. I know others have done work to improve on his program, but I don't know of any of that work that has been published. One nasty feature is that a long series of dahs can greatly confuse his algorithm and it can take a while to recover from that. Were you to implement his algorithm in a '628 or something like that, or even to simply replace the rather lengthy code he has around displaying the speed with a little more work on the algorithm, I'm sure it could be improved. He did use an external decoder to recognize the CW signal, a 567 or something of that ilk. Some folks have worked on that end, too. It seems like there should be a better approach, but I haven't seen anything dramatically better. ... |
#16
![]() |
|||
|
|||
![]()
Thanks to all for your replies
With regard to Tim's idea of the dual comparators, I presume these would in "series". For the integration idea to work, the comparators would obviously have to have their gain set carefully, otherwise random noise would integrate to 1/2 time and be interpreted as signal. The circuit I was thinking of would set the DC comparison point at halfway (say 2.5V for a 5V logic level) with the DC level of the signal also at 2.5V. I presume in your system the uP controls the comparison voltage and sets it with a DAC and the signal DC level is 0V. Is this correct? In my idea I was going to use the timing of signal transitions in a hard limited signal. If there were several transitions with the same timing, I would presume a "tone" was present and signal was being received. Randomly timed transitions would indicate noise.The uP could follow the tone as an adaptive filter to track carrier freq. Once carrier is received the uP then captures dot, dash and space timing with the histogram as you describe. If a moving average filter of these is kept, then the uP could track sender speed variations. Anyone have ideas as to the theoretical performance of such an idea or any potential problems? Thanks again Richard Tim Wescott wrote in message ... Disclaimer: I've never decoded morse in my life, so most of what I write is educated guessing. For my master's thesis I built a receiver that demodulated 400 baud MSK. The RF chain delivered a signal centered around 2kHz to a 68HC11 which sampled at 6400Hz and demodulated the data entirely in software -- and it only had 2k bytes of code space. Granted, it was all in assembly, and it used 94% of the available processor time to do it, but it did work. In spite of having some really ugly compromises in the signal processing (the sampling rate was really too low, and the only "multiply" was to add, not add, or subtract from an accumulator) the receiver had performance within a dB of the theoretical optimum. I think with something modern like an AVR or a PIC a 16-baud OOK signal should be possible (fun, too). OK, so you still have the problem with the math. Consider using not one, but two comparators to square up your signal, so a "non-signal" rarely gets above the threshold. You're back to needing AGC (at least to set the comparator), but you can close the loop in your software by looking at the comparator outputs for the right signatures (too much output = too low threshold, too little output = too high threshold), and set the threshold from the uP. With a good signal to noise ratio this should have a nice broad center to it that'll be easy to find. With a good narrow CW filter your signal to noise ratio will get better... Once your threshold is set you can integrate the "buzz" from the comparators to see if you're receiving a carrier. You should probably integrate for some period of time (the length of the fastest code you want to receive would be good, it'd give you a sorta-kinda-matched filter) and take the presense of signal 1/2 of the time to indicate the transmitter is "on". I like the idea of using the dibits to form a PLL, but for receiving bad code at an unknown rate you'd probably be better off making a little histogram of the on and off times of the code. You should be able to see two peaks in the histogram for "on" corresponding to dot and dash, and three for "off" corresponding to intra-letter, inter-letter and inter-word spacing. At this point you can start looking for dashes, dots, and spaces (maybe going back over your data to catch the beginning of the message, if you have enough RAM) and decoding words. You could also estimate the speed of the code that you're receiving and feed it back to your KSMF (that's kinda-sorta-matched filter, of course) for better noise figure. Once you have your stream of dashes, dots, inter-charater and inter-word spaces you can separate the charaters, look them up in a table and just reject anything that doesn't seem to fit. I suspect that your performance would be pretty good at this point, and if not the theoretical ne-plus-ultra of decoders it would be better at receiving the lousy senders than Wofgang's. "Richard Hosking" wrote in message u... Wolfgang Thanks for your reply I am not very sophisticated mathematically and I have not studied communication theory. Your article is most helpful. However it looks as |
#17
![]() |
|||
|
|||
![]()
Thanks to all for your replies
With regard to Tim's idea of the dual comparators, I presume these would in "series". For the integration idea to work, the comparators would obviously have to have their gain set carefully, otherwise random noise would integrate to 1/2 time and be interpreted as signal. The circuit I was thinking of would set the DC comparison point at halfway (say 2.5V for a 5V logic level) with the DC level of the signal also at 2.5V. I presume in your system the uP controls the comparison voltage and sets it with a DAC and the signal DC level is 0V. Is this correct? In my idea I was going to use the timing of signal transitions in a hard limited signal. If there were several transitions with the same timing, I would presume a "tone" was present and signal was being received. Randomly timed transitions would indicate noise.The uP could follow the tone as an adaptive filter to track carrier freq. Once carrier is received the uP then captures dot, dash and space timing with the histogram as you describe. If a moving average filter of these is kept, then the uP could track sender speed variations. Anyone have ideas as to the theoretical performance of such an idea or any potential problems? Thanks again Richard Tim Wescott wrote in message ... Disclaimer: I've never decoded morse in my life, so most of what I write is educated guessing. For my master's thesis I built a receiver that demodulated 400 baud MSK. The RF chain delivered a signal centered around 2kHz to a 68HC11 which sampled at 6400Hz and demodulated the data entirely in software -- and it only had 2k bytes of code space. Granted, it was all in assembly, and it used 94% of the available processor time to do it, but it did work. In spite of having some really ugly compromises in the signal processing (the sampling rate was really too low, and the only "multiply" was to add, not add, or subtract from an accumulator) the receiver had performance within a dB of the theoretical optimum. I think with something modern like an AVR or a PIC a 16-baud OOK signal should be possible (fun, too). OK, so you still have the problem with the math. Consider using not one, but two comparators to square up your signal, so a "non-signal" rarely gets above the threshold. You're back to needing AGC (at least to set the comparator), but you can close the loop in your software by looking at the comparator outputs for the right signatures (too much output = too low threshold, too little output = too high threshold), and set the threshold from the uP. With a good signal to noise ratio this should have a nice broad center to it that'll be easy to find. With a good narrow CW filter your signal to noise ratio will get better... Once your threshold is set you can integrate the "buzz" from the comparators to see if you're receiving a carrier. You should probably integrate for some period of time (the length of the fastest code you want to receive would be good, it'd give you a sorta-kinda-matched filter) and take the presense of signal 1/2 of the time to indicate the transmitter is "on". I like the idea of using the dibits to form a PLL, but for receiving bad code at an unknown rate you'd probably be better off making a little histogram of the on and off times of the code. You should be able to see two peaks in the histogram for "on" corresponding to dot and dash, and three for "off" corresponding to intra-letter, inter-letter and inter-word spacing. At this point you can start looking for dashes, dots, and spaces (maybe going back over your data to catch the beginning of the message, if you have enough RAM) and decoding words. You could also estimate the speed of the code that you're receiving and feed it back to your KSMF (that's kinda-sorta-matched filter, of course) for better noise figure. Once you have your stream of dashes, dots, inter-charater and inter-word spaces you can separate the charaters, look them up in a table and just reject anything that doesn't seem to fit. I suspect that your performance would be pretty good at this point, and if not the theoretical ne-plus-ultra of decoders it would be better at receiving the lousy senders than Wofgang's. "Richard Hosking" wrote in message u... Wolfgang Thanks for your reply I am not very sophisticated mathematically and I have not studied communication theory. Your article is most helpful. However it looks as |
#18
![]() |
|||
|
|||
![]()
Remark: The interface via a LPT port is possible by PortIO or other
free add ons to access direct the LPT port in Windows. Visual Basic or Powerbasic could be used. The PEEK statement has to be replaced by the equivalent access methode from the language to the port. Please double check, could be there are some errors due to OCR conversion. 73s Wolfgang World of the Brass Pounders: Receive the Morse Code the easy way by ROBERT L KURTZ 4 SANTA BELLA RD ROLLING HILLS CA 90274 scanned from an very old paper copy by OE1MWW WOLFGANG MEISTER WENHARTGASSE 27/5 WIEN A-1210 AUSTRIA email: oe1mww(at)qsl.net (replace the (at) with an @) Original article starts he A great feature of a personal-computing hobby is that it can be used to work with other hobbies. A case In point is this little program to decode and print out Morse code. I original-ly wrote this in machine lan-guage for my KIM system, where it took up less than one page, and finally decided to try it in BASIC. Even though the program looks simple, it has some unusual surprises, such as self-adaptive adjustment for changes in code speed. In addi-tion, the influence of changes in dash or dot length is weighted so that they must occur five or six times in succession be-fore the computer decides that there has been a bona fide speed change. As a result, an occasional "bad" character will not mess up your copy; the printout is extremely stable and the copy is relatively foolproof. The program also detects the end of the word and prints out a space, if required. The program's memory needs are minor—just a little over 1K of RAM is required. The program is written in Microsoft BASIC on the KIM computer, but should operate with any relatively fast BASIC. From a hardware standpoint, if your CRT or printer will go to 300 baud, this program will provide excellent copy of Morse code, up to 15 or 20 words per minute. If your terminal operates up to 1200 baud, it will follow the Morse transmissions to well over 30 words per minute. Loading the Program Input the program exactly as written, even though some of the instructions may seem re-dundant. It is written this way to save operating time—a very important consideration when you are dealing with fast-acting dots and dashes. Lines 10,20, 60, 110 and 150 instruct a PEEK to location 5888 (decimal). In the KIM com-puter, this is a peripheral input address at 1700 (hex). This loca-tion reads a total of eight input ports as an eight-bit word. The AND 1 on lines 10,20,60, 110 and 150 assures that the computer is only reading the port to which the incoming Morse is connected obviously, this must be changed to fit your particular system. In addition, the program assumes that when a dot or a dash occurs, a logic 0 appears on the input port. This is in agreement with a "key down" shorting the input port to ground, and also in agreement with the hardware interface cir-cuit described later. If your hookup provides a logic 1 during a dot and a dash, then lines 11, 30, 70,120 and 160 must be changed so that all IF A = 1 statements should read IF A = 0, and vice versa. Program Description Fig. 1 is a simplified flow diagram of the program. The initialization routine (lines 1 through 6) sets the lookup table that will permit the printout of the proper character. The pro-gram then waits for a key down to occur (lines 10 and 11). The first part of the operating pro-gram (lines 20 through 80) mea-sures the length of time that the key is down and compares this with the stored value for the length of a dash. If the key is raised in less than one-half of the stored dash time, the computer writes a dot into the dot register (line 30) and goes to the second part of the operating program. If the key remains down longer than one-half of the dash time, a dash is stored in the dash register (line 50), and the value of the dash time is up-dated with a one-to-four weight-ing (line 80). This is accom-plished by multiplying the old value of the dash time by four, adding the new value, and then dividing by five. As a result, the stored value of the dash time cannot change drastically from character to character, and the copy is not susceptible to er-rors from erratic sending habits. The second part of the pro-gram (lines 100 through 190) measures the length of time the key is up. if it's up less than one-half of the dash length, the program assumes that the character is not complete and no printout is provided (see lines 100 through 130). If the key is up longer, the program jumps to line 300, the print-character subroutine. If the key is up longer than twice the dash length, the program assumes that a word is complete and a "space" is printed (lines 170 and 180). Lookup Table The heart of the program is the algorithm that counts the dots and dashes and develops a number used to look up the ac-tual character to be printed, in other words, each combination of dots and dashes in Morse code has a discrete number that commands a given character to be printed. This algorithm has three conditions as listed in Table 1. Steps 1 and 2 keep repeating until the character is complete. When the program detects a key-up period longer than one-half of a dash length, it is assumed that the character is complete and step 3 is accomplished (lines 300 to 430). The manner in which the lookup number for the letter D is formed is shown in Example 1. Interlace Hardware Fig. 2 shows a typical circuit for connecting your radio re-ceiver to the computer. The NPN transistor is an R/C coupled audio amplifier con-nected to a type 567 phase-lock loop circuit. The free-running frequency of the phase-lock loop is set by the values of the capacitor and resistor con-nected to pins 5 and 6 of the 567, and is approximately 2000 Hz. The capacitors on pins 1 and 2 of the PLL adjust the bandwidth to about 100 Hz, and the LED serves as a tuning in-dicator—that is, It will start blinking when the signal Is in the center of this narrow band-pass. This circuit is compatible with the program, as written, In that the output signal goes to a logic 0 when a dot or a dash occurs. The circuit shown is not my original idea, but has appeared in numerous publications; you may have your own favorite circuit that you would like to use. As long as you maintain the same output logic (a 0 for a dot or dash), there will be no problem. Incidentally, the circuit has another unique application. Since it is only activated by audio signals over a fairly nar-row band, it can also be used to key an audio oscillator set to any frequency desired. When Morse CW comes in amidst a jumble of other signals, the phase-lock loop picks out the signal you want and keys the audio oscillator... and that is all you hear. A full-scale outline of the circuit board is shown in Fig. 3. Adjusting the Program One of the advantages of writing this program in BASIC is the ease with which the com putatlon constants can be changed. For Instance, you may wish to experiment with different algorithms to detect whether a key-down signal is a a dot or a dash... to take care of "swlng-fisters." This can be accomplished easily by chang-ing the factor in line 40 from (.5*0) to (.2S*C or .75*C). By the same token, the constants In lines 111 and 151 can be changed to provide more lee-way for the formation of char-acters and spaces. 1. If the input signal is a dash: A. Double the values in the dot and dash registers. B. Add 1 to the dash register (see line 50). 2. If the input signal is a dot: A. Double the values in the dot and dash registers. B. Add 1 to the dot register (see line 30). 3. if the character is complete: A. Double the value in the dash register. B. Add the dash and dot registers to obtain the lookup number. C. Clear the dot and dash registers. Table 1. EXAMPLE: D = -.. initial conditions: Dot register = 0, Dash register = 0. First period: Input a dash. 2 times dash register =2x0 = 0. 2 times dot register =2x0 = 0. Add 1 to dash register =1+0 = 1. Summary: dash register = 1, dot register = 0. Second period: Input a dot. 2 times dash register =2x1 = 2. 2 times dot register =2x0 = 0. Add 1 to dot register =1+0 = 1. Summary: dash register = 2, dot register = 1. Third period: Input a dot. 2 times dash register =2x2 = 4. 2 times dot register =2x1 = 2. Add 1 to dot register =1+2 = 3. Summary: dash register = 4, dot register = 3. End of Character—-determine lookup number for D. 2 times dash register =2x4 = 8. Add dot register and dash register =8 + 3 = 11. Answer: D = 11. Example 1. BASIC Code: 1 REM MORSE CODE READER - WRITTEN BY R. KURTZ - W6PR0 2 RESTORE 3 PRINT CHR$(26) : REM CAN DELETE - PUTS CURSOR AT TOP OF PAGE 5 DIM A$(100) 6 FOR N=l TO 100 : READ A$(N) : NEXT N 10 A=PEEK(5888) AND 1 11 IF A=l THEN 10 15 B=0 20 A=PEEK(5888) AND 1:B=B+10 30 IF A=l THEN C*((5*C)+(2*B))/6 ![]() ![]() ![]() 40 IF B(.5*C) THEN 20 50 DO=2*DO ![]() ![]() 60 A=PEEK(5888) AND 1:B=B+10 70 IF A=0 THEN GOTO 60 80 C=((4*C)+B)/5 100 B=0 110 A-PEEK(5888) AND 1 111 B=B+10 120 IF A=0 THEN GOTO 15 130 IF B(.5*C) THEN GOTO 110 140 GOSUB 300 150 A=PEEK(5888) AND 1 151 B=B+10 160 IF A=0 THEN GOTO 15 170 IF B(2*C) THEN GOTO 150 180 PRINT " "; 190 GOTO 10 300 DA=DA*2 310 D=DA+DO 330 IF D100 THEN D=100 340 PRINT A$(D); 350 DA=0 ![]() 360 RETURN 400 DATA E,T,I,A,N,M,S,U,R,W,D,K,G,O,H,V,F,-,L,-,P,J,B,X,C 410 DATA Y,Z,Q,-,-,5,4,-,3,-,-,-,2,-,-,-,-,-,-,-,1,6,-,/,- 420 DATA -,-,-,-,7,-,-,-,8,-,9,0,-,-,-,-,-,-,-,-,-,-,-,-,? 430 DATA -,-,-,-,-,-,-,-,.,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,- The circuit for the interface is scanned and can be requested via email from oe1mww(at)qsl.net |
#19
![]() |
|||
|
|||
![]()
Remark: The interface via a LPT port is possible by PortIO or other
free add ons to access direct the LPT port in Windows. Visual Basic or Powerbasic could be used. The PEEK statement has to be replaced by the equivalent access methode from the language to the port. Please double check, could be there are some errors due to OCR conversion. 73s Wolfgang World of the Brass Pounders: Receive the Morse Code the easy way by ROBERT L KURTZ 4 SANTA BELLA RD ROLLING HILLS CA 90274 scanned from an very old paper copy by OE1MWW WOLFGANG MEISTER WENHARTGASSE 27/5 WIEN A-1210 AUSTRIA email: oe1mww(at)qsl.net (replace the (at) with an @) Original article starts he A great feature of a personal-computing hobby is that it can be used to work with other hobbies. A case In point is this little program to decode and print out Morse code. I original-ly wrote this in machine lan-guage for my KIM system, where it took up less than one page, and finally decided to try it in BASIC. Even though the program looks simple, it has some unusual surprises, such as self-adaptive adjustment for changes in code speed. In addi-tion, the influence of changes in dash or dot length is weighted so that they must occur five or six times in succession be-fore the computer decides that there has been a bona fide speed change. As a result, an occasional "bad" character will not mess up your copy; the printout is extremely stable and the copy is relatively foolproof. The program also detects the end of the word and prints out a space, if required. The program's memory needs are minor—just a little over 1K of RAM is required. The program is written in Microsoft BASIC on the KIM computer, but should operate with any relatively fast BASIC. From a hardware standpoint, if your CRT or printer will go to 300 baud, this program will provide excellent copy of Morse code, up to 15 or 20 words per minute. If your terminal operates up to 1200 baud, it will follow the Morse transmissions to well over 30 words per minute. Loading the Program Input the program exactly as written, even though some of the instructions may seem re-dundant. It is written this way to save operating time—a very important consideration when you are dealing with fast-acting dots and dashes. Lines 10,20, 60, 110 and 150 instruct a PEEK to location 5888 (decimal). In the KIM com-puter, this is a peripheral input address at 1700 (hex). This loca-tion reads a total of eight input ports as an eight-bit word. The AND 1 on lines 10,20,60, 110 and 150 assures that the computer is only reading the port to which the incoming Morse is connected obviously, this must be changed to fit your particular system. In addition, the program assumes that when a dot or a dash occurs, a logic 0 appears on the input port. This is in agreement with a "key down" shorting the input port to ground, and also in agreement with the hardware interface cir-cuit described later. If your hookup provides a logic 1 during a dot and a dash, then lines 11, 30, 70,120 and 160 must be changed so that all IF A = 1 statements should read IF A = 0, and vice versa. Program Description Fig. 1 is a simplified flow diagram of the program. The initialization routine (lines 1 through 6) sets the lookup table that will permit the printout of the proper character. The pro-gram then waits for a key down to occur (lines 10 and 11). The first part of the operating pro-gram (lines 20 through 80) mea-sures the length of time that the key is down and compares this with the stored value for the length of a dash. If the key is raised in less than one-half of the stored dash time, the computer writes a dot into the dot register (line 30) and goes to the second part of the operating program. If the key remains down longer than one-half of the dash time, a dash is stored in the dash register (line 50), and the value of the dash time is up-dated with a one-to-four weight-ing (line 80). This is accom-plished by multiplying the old value of the dash time by four, adding the new value, and then dividing by five. As a result, the stored value of the dash time cannot change drastically from character to character, and the copy is not susceptible to er-rors from erratic sending habits. The second part of the pro-gram (lines 100 through 190) measures the length of time the key is up. if it's up less than one-half of the dash length, the program assumes that the character is not complete and no printout is provided (see lines 100 through 130). If the key is up longer, the program jumps to line 300, the print-character subroutine. If the key is up longer than twice the dash length, the program assumes that a word is complete and a "space" is printed (lines 170 and 180). Lookup Table The heart of the program is the algorithm that counts the dots and dashes and develops a number used to look up the ac-tual character to be printed, in other words, each combination of dots and dashes in Morse code has a discrete number that commands a given character to be printed. This algorithm has three conditions as listed in Table 1. Steps 1 and 2 keep repeating until the character is complete. When the program detects a key-up period longer than one-half of a dash length, it is assumed that the character is complete and step 3 is accomplished (lines 300 to 430). The manner in which the lookup number for the letter D is formed is shown in Example 1. Interlace Hardware Fig. 2 shows a typical circuit for connecting your radio re-ceiver to the computer. The NPN transistor is an R/C coupled audio amplifier con-nected to a type 567 phase-lock loop circuit. The free-running frequency of the phase-lock loop is set by the values of the capacitor and resistor con-nected to pins 5 and 6 of the 567, and is approximately 2000 Hz. The capacitors on pins 1 and 2 of the PLL adjust the bandwidth to about 100 Hz, and the LED serves as a tuning in-dicator—that is, It will start blinking when the signal Is in the center of this narrow band-pass. This circuit is compatible with the program, as written, In that the output signal goes to a logic 0 when a dot or a dash occurs. The circuit shown is not my original idea, but has appeared in numerous publications; you may have your own favorite circuit that you would like to use. As long as you maintain the same output logic (a 0 for a dot or dash), there will be no problem. Incidentally, the circuit has another unique application. Since it is only activated by audio signals over a fairly nar-row band, it can also be used to key an audio oscillator set to any frequency desired. When Morse CW comes in amidst a jumble of other signals, the phase-lock loop picks out the signal you want and keys the audio oscillator... and that is all you hear. A full-scale outline of the circuit board is shown in Fig. 3. Adjusting the Program One of the advantages of writing this program in BASIC is the ease with which the com putatlon constants can be changed. For Instance, you may wish to experiment with different algorithms to detect whether a key-down signal is a a dot or a dash... to take care of "swlng-fisters." This can be accomplished easily by chang-ing the factor in line 40 from (.5*0) to (.2S*C or .75*C). By the same token, the constants In lines 111 and 151 can be changed to provide more lee-way for the formation of char-acters and spaces. 1. If the input signal is a dash: A. Double the values in the dot and dash registers. B. Add 1 to the dash register (see line 50). 2. If the input signal is a dot: A. Double the values in the dot and dash registers. B. Add 1 to the dot register (see line 30). 3. if the character is complete: A. Double the value in the dash register. B. Add the dash and dot registers to obtain the lookup number. C. Clear the dot and dash registers. Table 1. EXAMPLE: D = -.. initial conditions: Dot register = 0, Dash register = 0. First period: Input a dash. 2 times dash register =2x0 = 0. 2 times dot register =2x0 = 0. Add 1 to dash register =1+0 = 1. Summary: dash register = 1, dot register = 0. Second period: Input a dot. 2 times dash register =2x1 = 2. 2 times dot register =2x0 = 0. Add 1 to dot register =1+0 = 1. Summary: dash register = 2, dot register = 1. Third period: Input a dot. 2 times dash register =2x2 = 4. 2 times dot register =2x1 = 2. Add 1 to dot register =1+2 = 3. Summary: dash register = 4, dot register = 3. End of Character—-determine lookup number for D. 2 times dash register =2x4 = 8. Add dot register and dash register =8 + 3 = 11. Answer: D = 11. Example 1. BASIC Code: 1 REM MORSE CODE READER - WRITTEN BY R. KURTZ - W6PR0 2 RESTORE 3 PRINT CHR$(26) : REM CAN DELETE - PUTS CURSOR AT TOP OF PAGE 5 DIM A$(100) 6 FOR N=l TO 100 : READ A$(N) : NEXT N 10 A=PEEK(5888) AND 1 11 IF A=l THEN 10 15 B=0 20 A=PEEK(5888) AND 1:B=B+10 30 IF A=l THEN C*((5*C)+(2*B))/6 ![]() ![]() ![]() 40 IF B(.5*C) THEN 20 50 DO=2*DO ![]() ![]() 60 A=PEEK(5888) AND 1:B=B+10 70 IF A=0 THEN GOTO 60 80 C=((4*C)+B)/5 100 B=0 110 A-PEEK(5888) AND 1 111 B=B+10 120 IF A=0 THEN GOTO 15 130 IF B(.5*C) THEN GOTO 110 140 GOSUB 300 150 A=PEEK(5888) AND 1 151 B=B+10 160 IF A=0 THEN GOTO 15 170 IF B(2*C) THEN GOTO 150 180 PRINT " "; 190 GOTO 10 300 DA=DA*2 310 D=DA+DO 330 IF D100 THEN D=100 340 PRINT A$(D); 350 DA=0 ![]() 360 RETURN 400 DATA E,T,I,A,N,M,S,U,R,W,D,K,G,O,H,V,F,-,L,-,P,J,B,X,C 410 DATA Y,Z,Q,-,-,5,4,-,3,-,-,-,2,-,-,-,-,-,-,-,1,6,-,/,- 420 DATA -,-,-,-,7,-,-,-,8,-,9,0,-,-,-,-,-,-,-,-,-,-,-,-,? 430 DATA -,-,-,-,-,-,-,-,.,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,- The circuit for the interface is scanned and can be requested via email from oe1mww(at)qsl.net |
#20
![]() |
|||
|
|||
![]()
On Fri, 02 Jan 2004 14:44:02 GMT, Wolfgang K. Meister
wrote: line 350 should be 350 DA=0 ![]() |
Reply |
Thread Tools | Search this Thread |
Display Modes | |
|
|
![]() |
||||
Thread | Forum | |||
FS: Wavecom w41pc rtty decoder package! | Digital | |||
FS: Wavecom w41pc rtty decoder package! | Digital | |||
FS: Wavecom w41pc rtty decoder package! | Equipment | |||
FS: Wavecom w41pc rtty decoder package! | Equipment |