Searching \ for '[PIC] Morse Code Firmware -- not big enough' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Morse Code Firmware -- not big enough'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Morse Code Firmware -- not big enough'
2007\04\09@163608 by Barry Gershenfeld

face picon face
As your morse code programs are getting smaller and smaller, they are in
danger of disappearing!  This code trades efficiency for novelty.  I saw
this idea at a ham club talk (in the '70's) and have been doing it this way
ever since.  Since you guys use assembler more than anything else, I'll
post it that way.  I do the same thing in other languages.

; Morse code, tree structured.
; Example fragment assumes the basic elements have been previously defined:

E:
    call    dit
    goto    interchar

N:
    call    dah
    goto    E

G:
    call    dah
    goto    N

P:
    call    dit
    goto    G

T:
    call    dah
    goto    interchar

A:
    call    dit
    goto    T

#pragma etc
; the 'etc' directive writes the rest of the program for you!

; Barry

2007\04\09@164506 by M. Adam Davis

face picon face
That's great!  I have a thing for binary trees though, so naturally it
would appeal to me.  I just wouldn't have thought of doing it from the
bottom up like that.

-Adam

On 4/9/07, Barry Gershenfeld <spam_OUTbarry_gTakeThisOuTspamzmicro.com> wrote:
{Quote hidden}

> -

2007\04\09@170222 by David VanHorn

picon face
> ; Morse code, tree structured.
> ; Example fragment assumes the basic elements have been previously defined:
>
> E:
>     call    dit
>     goto    interchar

Hmm.. You'd like my first solution for decoding UPC/EAN barcodes.
Four elements, the sum of which is always "7"
4111, 2311, etc.

In my case, the morse gen has to run with everything else, no task is
allowed to sit and spin, but I could see generating the timing
intervals this way, I guess.
Still, one byte per char and a LUT is hard to beat.

In my case, the morse routine has to see if a char should be running,
if the tone or silence is done, and if so, if there is a next element
to start up before exiting.

2007\04\09@184018 by Harold Hallikainen

face
flavicon
face
I remember seeing a Morse table that was something like this. Everything
is based on either an E or T. Do you have source code for the "etc."
pragma? I could really use it!



Harold


{Quote hidden}

> -

2007\04\09@193823 by Tamas Rudnai

face picon face
Hi Berry,

That's a good idea! And of course we could optimize further like this:

; Morse code, tree structured.
; Example fragment assumes the basic elements have been previously defined:

P:
   call    dit
G:
   call    dah
N:
   call    dah
E:
   call    dit
   goto    interchar

A:
   call    dit
T:
   call    dah
   goto    interchar


#pragma shrink
; the 'shrink' directive will shrink your code even further

Tamas




On 4/9/07, Barry Gershenfeld <.....barry_gKILLspamspam@spam@zmicro.com> wrote:
{Quote hidden}

> -

2007\04\10@091536 by M. Adam Davis

face picon face
Oh great, just like the dighole site, I'm going to spend an hour or
two fiddling with this to see how small I can make it.

_Thanks!_  ;-(


:)

-Adam

On 4/9/07, Tamas Rudnai <tamas.rudnaispamKILLspamgmail.com> wrote:
{Quote hidden}

2007\04\10@141948 by Walter Banks

picon face
This could have interesting encoding. Drive it as  FSM. It can be coded as
one byte per encoded character(with shorter decoding than the last Morse code
generator). MSBit as a dit/dah encoding leaving 7 bits for addressing next
character with a few left over for "interchar" and  other utility functions.

dit/dah   |     Next state
  7               6 - - 0

#define dit 0
#define dah 0x80

E:   dit+&interchar
N:   dah+&E
G:   dah+&N
P:   dit+&G
T:   dah+&interchar
A:   dah+&T


Organize as an upper case ascii representation this could be a very tight morse serial driver.


w..
--
Walter Banks
Byte Craft Limited
1 519 888 6911
http://www.bytecraft.com
EraseMEwalterspam_OUTspamTakeThisOuTbytecraft.com





Barry Gershenfeld wrote:

{Quote hidden}

> -

2007\04\10@144059 by Robert Rolf

picon face
It's still a look up table so you still have to have one entry per
character and code to look up the character (they're not linear
mapped of the ASCII value).
e.g. some sort of case structure before the table.

The advantage to Tamas's tree approach is that the code IS
the table. But you still have to do the NON SEQUENTIAL
character lookup.

Seems to me that a linear lookup table with the morse pattern is going
to give the lowest memory footprint when ALL of the needed
code pieces are viewed together.
e.g. lookup character, decode, output

Are any morse characters more than 8 elements?

Robert

Walter Banks wrote:

{Quote hidden}

2007\04\10@152902 by Peter P.

picon face
Barry Gershenfeld <barry_g <at> zmicro.com> writes:

{Quote hidden}

Or, rewritten a little bit:

P: call dit
G: call dah
N: call dah
E: call dit
  goto interchar

O: call dah
M: call dah
T: call dah
  goto interchar

A: call dit
  goto T

; etc

But it is more interesting to analyze this for morse decoding. A binary tree
approach can be used, pointing into a retlw table, with halving distances for
each succesive symbol, e.g.:

(Note: decoding of 'V' shown as example in comments)

;; dit half of table, to symbol count of 4
     retlw 'H'
     retlw 'S'   ;                      step(3); dit: A -= Y; Y=Y/2
     retlw 'V'   ;                      step(4); daw: (end)

     retlw 'I'   ;                      step(2); dit: A -= Y; Y=Y/2

     retlw 'F'
     retlw 'U'
     retlw m0011 ; dit dit dah dah

Ddit  retlw 'E'   ; ex: Y=4;A=Ddit; 'V': step(1); dit: A -= Y; Y=Y/2

     retlw 'L'
     retlw 'R'
     retlw m0101

     retlw 'A'

     retlw m0110
     retlw 'W'
     retlw 'J'

;; daw half

     retlw 'B'
     retlw 'D'
     retlw 'X'

     retlw 'N'

     retlw 'Y'
     retlw 'K'
     retlw 'C'

Ddaw  retlw 'T'

     retlw 'Z'
     retlw 'G'
     retlw 'Q'
   
     retlw 'M'

     retlw m1110
     retlw 'O'
     retlw m1111
     
; to decode morse, call a subroutine that times symbols and outputs a bit vector
; like 0001bbbb where bbbb are morse symbols, 1 for dah and 0 for dit. The 1
; is a start symbol. If the start symbol is in bit 5 and 6,7 are 0 then it's a
; number, so treat it differently. Else use this table (bit vector is in Morse):
; (else use a different table with prosigns etc)
Sdecode_morse4:
 movlw 4
 movwf Y ; step size

 movlw Ddit      ; 1st symbol
 btfsc Morse,3   ; zero: start at Ddit
 movlw Ddaw      ; one:  start at Ddaw

decode_morse4:
 rlf   Morse,f   ; next bit in bit 3

 btfss Morse,3   ; dit: go up
 subwf Y,w       ; do it
 btfsc Morse,3   ; daw: go down
 addwf Y,w       ; do it

 rrf   Y,f       ; Y /= 2
 incf  Y,f       ; +1
 decfsz Fcount,f ; -1, check Z
 goto   decode_morse4

 ;; check page/bank bits here
 movwf  PC       ; return with character code in W

A suitable table can be found on wikipedia (scroll down to the dichotomic search
table):

 http://en.wikipedia.org/wiki/Morse_code

Peter P.


2007\04\10@162529 by Walter Banks

picon face
Robert ,

I wasn't clear, my code can be in a table to be accesses with
sequential lookup there is no order dependencies in the entry
points for the FSM. My email was focused on the encoding
and failed to make the one byte per character, order independent
clear. Start state is an indexed array access into a 64 byte
table indexed by the ascii character. This would be the same
encode order that Dennis Crawley use a couple weeks ago.

There are 7 unused Morse characters that can be used for
other states

Barry's approach has the code in a the table with each entry
a two instruction code size overhead per character encoded
57 * 2 instructions depending on implementation possibly 64
* 2 instructions. Tamas's trades speed for table size but loses
the advantage of table order. My Hybrid approach cuts the
table code to 57 or 64 bytes plus enough overhead to
interpret the MSbit (dit/dah) and jump to the next character or
intercharacter.

The result is shorter than the thread a couple weeks ago
and shorter (but more cycles) than Barry's approach.

In the best traditions of the PIC list it can be done with none
or less:)

w..
--
Walter Banks
Byte Craft Limited
1 519 888 6911
http://www.bytecraft.com
walterspamspam_OUTbytecraft.com


Robert Rolf wrote:

{Quote hidden}

> -

2007\04\10@171600 by Peter P.

picon face
So what about the receiver decoder I posted ? Has anybody done this before in
this way ?

thanks,
Peter P.


2007\04\10@172837 by Peter P.

picon face
Ok, my decoder code has a bug, it ignores the length of the received vector. It
should 'search for the start bit' before decoding, E.g. 0001abcd, 00001abc,
000001ab, 0000001a with a..d bits encoding dit or dah. Then this snippet of code
should be added to the decoder:

 rrf   Morse,f
search_start:
 rlf   Morse,f
 btfss Morse,4
 goto  search_start

and the tested bit would be Morse,3 with stop condition Morse,7 == 1

Peter P.



2007\04\11@064601 by Peter P.

picon face
I have considered the alternatives and I have come to the conclusion that the best way to implement an encoder and decoder (both) is by using a straight table. I attach debugged testing code that implements both in 78 words for alnum plus dot and comma. Adding prosigns, umlauts etc is trivial with the table system. Runtime is under 700 usec for a decode. This should be enough time to decode a morse stream even at 180 Wpm using 50% of the standard llspace, with a clock of only 4 MHz. On send, the time variance due to non-constant runtime encoding is only 22 usec and the longest time taken to send something is under 100 usec. This should be enough for 150+ Wpm sending. The calculations may be slightly off. Comments are welcome.

Wrt. the previous discussion, I think that the binary tree approach is expensive if encoding and decoding must be used. For encoding only it may be advantageous. For fast decoding a direct table approach (map code->retlw character) could work but it would waste a lot of space (minimum 64 bytes of table with many unused positions - about half would be empty).

Code follows:

;;
;; Morse encoding and decoding subroutines
;;
;; V0.0
;; @spam@plpeter2006KILLspamspamyahoo.com 2007
;;
;; Sender:   debugged ok
;; Receiver: debugged ok
;;
;; Subroutines:
;;
;; Smorse_send sends character in W using Sditdah and Sllspace
;; Sreceive_morse decodes vector in Fmorse and returns char in W
;;
;; To simulate this code set breakpoints at all lines marked BRK
;;
;; Total code words (less main and debugging code):
;;
;; Smorse_table   : 4 + table size ( = 41 for alnum + '.' + ',' )
;; Sreceive_morse : 16 Words
;; Ssend_morse    : 21 Words
;;
;; runtime for sending is short and has low variance by code
;; runtime for receiving is longer and more dependent on code
;;
;; runtimes are approximate and do not include subroutine (Sditdah) overhead
;;
;; total is 78 words of active subroutines (less test code and main) for
;; sending and receiving
;;

;; setup etc
   list p=p16f84, r=hex
   include <p16f84.inc>

   cblock 0x10

   Fmorse_temp
   Fcounter
   Fmorse

   Fchar    ; used by main
   Ftest   ; used by main and Sditdah

   endc

;; entry point
   org 0
Reset:
   goto Start

   org 4
Interrupt:
   return

ERROR_MISSING_CODE set 0xf0

;; MAIN
Start:

;; debug sender
   movlw '0'
   call Ssend_morse

   movf Ftest,w
   xorlw b'00111111'
   btfss STATUS,Z    ; BRK
   nop               ; BRK if the nop executes the simulation failed

   movlw '9'
   call  Ssend_morse

   movf  Ftest,w
   xorlw b'00111110'
   btfss STATUS,Z    ; BRK
   nop               ; BRK

   movlw 'A'
   call  Ssend_morse

   movf  Ftest,w
   xorlw b'00000101'
   btfss STATUS,Z    ; BRK
   nop               ; BRK

;; debug receiver
       movlw b'00101111' ; '1'
   movwf Fmorse
   call  Sdecode_morse

   xorlw '1'
   btfss STATUS,Z    ; BRK
   nop               ; BRK

   movlw b'00111110' ; '9'
   movwf Fmorse
   call  Sdecode_morse

   xorlw '9'
   btfss STATUS,Z    ; BRK
   nop               ; BRK

       movlw b'00000101' ; 'A'
   movwf Fmorse
   call  Sdecode_morse

   xorlw 'A'
   btfss STATUS,Z    ; BRK
   nop               ; BRK

       movlw b'00011100' ; 'Z'
   movwf Fmorse
   call  Sdecode_morse

   xorlw 'Z'
   btfss STATUS,Z    ; BRK
   nop               ; BRK
   goto Start

;; stubs

;; send dit for C=0, dah for C=1, then symbol-symbol space
Sditdah:
   btfsc STATUS,C
   nop                ; simulator steps here if C==1
   
   ; for simulation only
   rlf Ftest,f

   retlw 0

;; send space between letters
Sllspace:
   retlw 0

;; Table, used for sending and receiving, 10 digits + 26 chars +
;; punctuation + prosigns
;; index math: 0-9:straight A-Z:-10+'A' etc
;; 3 + table size words + 1 (41 words for alnum +','+'.' only)
;; calls: none; destroys: W
Smorse_table:
 movlw morse_table
 addwf Fmorse_temp,w
 ;; set page and bank bits here
 movwf PCL

morse_table
 ;; encoding 'zzz1abc' where z are zero bits 1 is a start bit and abc are      
 ;; symbols
 ;; length = 10 + 26 + x
 ;; it is good for speed and compression if punctuation is remapped to
 ;; character codes above 'Z', or below '0', and consecutive codes
 retlw b'00111111' ; '0'
 retlw b'00101111' ; '1'
 retlw b'00100111'
 retlw b'00100011'
 retlw b'00100001'
 retlw b'00100000' ; '5'
 retlw b'00110000'
 retlw b'00111000'
 retlw b'00111100'
 retlw b'00111110' ; '9'

 retlw b'00000101' ; 'A'
 retlw b'00011000' ; 'B'
 retlw b'00011010' ; 'C'
 retlw b'00001100' ; 'D'
 retlw b'00000010' ; 'E'
 retlw b'00010100' ; 'F'
 retlw b'00001100' ; 'G'
 retlw b'00010000' ; 'H'
 retlw b'00000100' ; 'I'
 retlw b'00010111' ; 'J'
 retlw b'00001101' ; 'K'
 retlw b'00010100' ; 'L'
 retlw b'00000111' ; 'M'
 retlw b'00000110' ; 'N'
 retlw b'00001000' ; 'O'
 retlw b'00010110' ; 'P'
 retlw b'00011101' ; 'Q'
 retlw b'00001010' ; 'R'
 retlw b'00001000' ; 'S'
 retlw b'00000011' ; 'T'
 retlw b'00001001' ; 'U'
 retlw b'00010001' ; 'V'
 retlw b'00001011' ; 'W'
 retlw b'00011001' ; 'X'
 retlw b'00011011' ; 'Y'
 retlw b'00011100' ; 'Z'

 retlw b'01110011' ; '.' use DOT_CHAR   = code 36
 retlw b'01010101' ; ',' use COMMA_CHAR = code 37
 ; more like this ...

 retlw 0           ; table end marker!!!

;; Subroutine to send morse, input character in W
;; assume input characters are in the ranges permitted by the code table
;; destroys Fmorse_temp, Fcounter
;; 21 words + table, calls Smorse_table, Sditdah, Sllspace
;; shortest run: about 76T, longest 94T
Ssend_morse:
 addlw 0x100-'9'-1   ; W >= 9?
 btfsc STATUS,C      ; no
 addlw 0x100+'0'-'A'+d'10' ; yes
 addlw '9'+1-'0'

 movwf Fmorse_temp ; table index uses this
 call  Smorse_table
 movwf Fmorse_temp ; encoded bits

 movlw 8
 movwf Fcounter

 ; find start '1'
send_morse0:
 decf  Fcounter,f  
 rlf   Fmorse_temp,f

 btfss STATUS,C
 goto  send_morse0

;; this section only for testing: init test register
 movlw 0x01
 movwf Ftest
;; end test section

send_morse1:
 rlf   Fmorse_temp,f
 call  Sditdah     ; send dit for C=0, dah for C=1, then symbol space

 decfsz Fcounter,f
 goto  send_morse1

 call  Sllspace

 return

;; Subroutine to decode morse, output character in W, input in Fmorse
;; destroys Fmorse_temp and Fcounter
;; 16 words + table, calls Smorse_table
;; shortest run: about 40T '0'
;; longest run: about 650T 'Z'
Sdecode_morse:
 clrf  Fmorse_temp   ; index into table

decode_morse0:
 call  Smorse_table

 andlw 0xff
 btfsc STATUS,Z
 retlw ERROR_MISSING_CODE

 xorwf Fmorse,w
 btfsc STATUS,Z
 goto  decode_morse1 ; found it

 incf  Fmorse_temp,f ; next
 goto  decode_morse0

decode_morse1:
 movlw d'10'
 subwf Fmorse_temp,w
 btfsc STATUS,C
 addlw 'A'-'0'-d'10'
 addlw '0'+d'10'

 return

 end

Peter P.


     
---------------------------------
Don't be flakey. Get Yahoo! Mail for Mobile and
always stay connected to friends.

2007\04\11@083156 by Tamas Rudnai

face picon face
Hi Peter,

Letters are wrong: G; O and F

Regards,
Tamas


On 4/11/07, Peter P. <KILLspamplpeter2006KILLspamspamyahoo.com> wrote:
{Quote hidden}

> -

2007\04\11@093041 by Dennis Crawley

picon face
On Wednesday, April 11, 2007 9:31 AM [GMT-3=CET],
Tamas Rudnai  wrote:

> Hi Peter,
>
> Letters are wrong: G; O and F
>
> Regards,
> Tamas



 retlw b'00010010' ; 'F'
 retlw b'00001110' ; 'G'
 retlw b'00001111' ; 'O'

D.



2007\04\11@101403 by Tamas Rudnai

face picon face
Hi Walter,

Is that something similar what you meant?

equ dit 0
equ dah 1

equ A   0
equ B   1
equ C   2
equ D   3
equ E   4
...

; letter is in W
send_letter
   call    letter
   movwf   char ; store char (well, the following one...)

   bsf     PORTB,0 ; start beeping
   call    dit     ; wait for 1 at least dit long

   rrf     char,f
   btfsc   STATUS,C
   call    dah     ; wait for 2 more dits

   ; stop beeping and wait for dit long
   bcf     PORTB,0
   call    dit

   movf    char,w  ; get the char from temp variable
   btfss   STATUS,Z
   goto    send_letter ; INSTR 12 ;-)

   ; here the code goes furtherif char was 0...
   ; we saved a return as WREG is 0 and
   ; we don't care what gets returned...
letter
   addwf PCL,f
   retlw T+dit ; A
   retlw S+dah ; B
   retlw R+dah ; C
   retlw I+dah ; D
   retlw   dit ; E
...

PS: for decoding if no reversed table used (example on "D"):

1. wait for dit or dah, look it up in table (dit arrived, "E" found)
2. wait for next one, look up E+dit/dah (dit arrived, "I" found)
3. wait for next one, look up I+dit/dah (dah arrived, "D" found)
4. wait for next one, long wait detected, finished, result: "D"

(Very time consuming, I know)

Tamas



On 4/11/07, Walter Banks <spamBeGonewalterspamBeGonespambytecraft.com> wrote:
{Quote hidden}

2007\04\11@111129 by Walter Banks

picon face
Tamas,

I would implement this something like your example.  I would likely
us the letter access with code similar to what Dennis used.
letter[(char-34)& 0x3f] so it could use ascii order
in a 64 byte char array. In his implementation he
set the 7 unused chars to 0. E and T need to be detected
they are always the last character to be accesses. lots of
possibilities how that can be accomplished.

Decoding is a different problem I am not sure I would use the
same data base for Morse to ascii conversion.

w..



Tamas Rudnai wrote:

{Quote hidden}

>

2007\04\11@122132 by Peter P.

picon face
Dennis Crawley <dennis.crawley <at> usa.net> writes:

> On Wednesday, April 11, 2007 9:31 AM [GMT-3=CET],
> Tamas Rudnai  wrote:
>
> > Hi Peter,
> >
> > Letters are wrong: G; O and F
> >
> > Regards,
> > Tamas
>
>   retlw b'00010010' ; 'F'
>   retlw b'00001110' ; 'G'
>   retlw b'00001111' ; 'O'

Yes, thanks. I copied a table carelessly while concentrating on other aspects. I
will likely add a sounder and later a discriminator (receiver) and republish the
code.

Peter P.


2007\04\11@144313 by Dennis Crawley

picon face
On Wednesday, April 11, 2007 1:11 PM [GMT-3=CET],
Peter P.  wrote:

[snip]
> Yes, thanks. I copied a table carelessly while concentrating on other
> aspects. I will likely add a sounder and later a discriminator (receiver)
and
> republish the code.
>
> Peter P.

Discriminator.
... An adjustable band pass digital-filter? DFT? FFT?. Sounds like a lot of
work. The user dictates the cut off frequencies so the "reader" can
discriminates one cw transmission form another?

Dennis.



2007\04\11@153049 by Brooke Clarke

flavicon
face
Hi Peter:

For a graphical implementation of the dichotomic search see the MORSE CODE
DECODER COIN at: http://coins.hallwindmeter.com/index.php#decoder

Have Fun,

Brooke Clarke
--
w/Java http://www.PRC68.com
w/o Java www.pacificsites.com/~brooke/PRC68COM.shtml
http://www.precisionclock.com

2007\04\11@153925 by Peter P.

picon face
Dennis Crawley <dennis.crawley <at> usa.net> writes:

> On Wednesday, April 11, 2007 1:11 PM [GMT-3=CET],
> Peter P.  wrote:
>
> [snip]
> > Yes, thanks. I copied a table carelessly while concentrating on other
> > aspects. I will likely add a sounder and later a discriminator (receiver)
> and
> > republish the code.
> >
> > Peter P.
>
> Discriminator.
> ... An adjustable band pass digital-filter? DFT? FFT?. Sounds like a lot of
> work. The user dictates the cut off frequencies so the "reader" can
> discriminates one cw transmission form another?

Most likely a time domain discriminator (phdspeak for autobauding morse
decoder). But later frequency sensitive things may be added. Although the DSP
performance of the pics I use for this project is not in that league at all
something nice could be imagined and tested (f.ex. a switched capacitor filter
driven by two phase clock produced by the pic).

The sounder already works but the code is un-clean. I'm still well under 200
words. I think that I can fit a complete sender and receiver in the smallest
available pics (12{c,f}508} with an external eeprom for some fun projects.

Peter P.


2007\04\11@154306 by Barry Gershenfeld

face picon face

>Barry's approach has the code in a the table with each entry
>a two instruction code size overhead per character encoded
>57 * 2 instructions depending on implementation possibly 64
>* 2 instructions.

Barry's *subject line* said he wasn't going for smaller code :-)
At least two people (Tamas, Peter) have suggested turning the calls around
so each drops through to the next.  Gets rid of the goto's.  That is a
better idea, and shows that I don't live in assembly-land.

If you needed 8-element characters, you could use the carry as a ninth bit,
calling it a "stop bit" and stopping when w = 0000001.  At the expense of
code size, so I know you'll never go there :-)  Really I said that just to
give you guys more ideas.  Maybe it was done already but I only get an hour
a day to read this stuff.

As for decoding--now, that's the interesting part.   Generating CW is
simple.  But can you decode it?  I mean my fist, not some machine...   I
may want to play with some of the code you guys put up here.   I would
think it deserves a new subject line, too.

Barry



2007\04\11@155345 by David VanHorn

picon face
On 4/11/07, Brooke Clarke <EraseMEbrookespampacific.net> wrote:
> Hi Peter:
>
> For a graphical implementation of the dichotomic search see the MORSE CODE
> DECODER COIN at: http://coins.hallwindmeter.com/index.php#decoder
>

cute, but no numbers, punctuation, or prosigns

2007\04\11@155641 by Peter P.

picon face
Brooke Clarke <brooke <at> pacific.net> writes:

> Hi Peter:
>
> For a graphical implementation of the dichotomic search see the MORSE CODE
> DECODER COIN at: http://coins.hallwindmeter.com/index.php#decoder

He he, thanks, that is neat. I might get one in a while. Eventually I hope to
get by without it however (learning code).

Peter P.


2007\04\11@155844 by David VanHorn

picon face
> The sounder already works but the code is un-clean. I'm still well under 200
> words. I think that I can fit a complete sender and receiver in the smallest
> available pics (12{c,f}508} with an external eeprom for some fun projects.

I'm interested to see how you implement the decoder part, particularly
with off-air signals.  I know the boxcar integrator approach for tone
filtering, I've used it in several DF projects, but hadn't thought
that you could implement it in a more wideband version.

2007\04\11@163710 by David VanHorn

picon face
>
> He he, thanks, that is neat. I might get one in a while. Eventually I hope to
> get by without it however (learning code).


They already nuked the code requirements for a ham ticket in the US.
No requirement for any class of licence.

2007\04\11@200915 by Peter P.

picon face
David VanHorn <dvanhorn <at> microbrix.com> writes:

> > He he, thanks, that is neat. I might get one in a while. Eventually I hope to
> > get by without it however (learning code).
>
> They already nuked the code requirements for a ham ticket in the US.
> No requirement for any class of licence.

And the good part about it is ... ? I thought CBers and AMers were jamming ham
bands occasionally (i.e. twice a day, when propagation was optimal). While
it's true that their effect was negligible wrt. the broadcast stations which
barged into the same space, now you can be sure that they can do it *legally*.
But even that is going to look pleasant if power line communications get their
way.

I live in a city that is not famous for RFI concerns. As a result we already
have the level of RFI associated with PLC on the wiring. F.ex. I remember a
long time ago when there was a power outage and I got to listen to HF and LW on
batteries. Now, that gave me an idea about just what level of RFI is floating
here. And I think that it's mostly the same with most city dwellers. So with
this level of RFI, the only chance to do something is with very narrow band
modes. Like CW.

Besides code is not about licenses. It's about low cost reliable and portable
gear (and often diy).

Peter P.


2007\04\12@094123 by Walter Banks

picon face
I wrote a Morse decode for demonstration for a friend for a ham
convention in the early 70's on a PDP8/e. It was designed to be
speed tracking and worked quite well on hand sent code. The
algorithm I used was to base the starting speed on the the last
received character and analyse the speed of the received
character to update the received speed. I remember two
things debugging the code. For a while small noise pulses
were interpreted as dots and were hard (at the time) to filter
out in software. the second thing that should not have been
a surprise was the dit / dah ratio in hand sent code was far
from close and we did some tracking on the ratio as well.

It was a weekend project I wrote the code and Roger Grant
created a interface to a receiver. It was a hit around the ham
convention. One of the attendees was an old railway telegraph
operator whose code on a straight key might as well have been
machine generated. The console on this old computer was
a teletype and his code might as well have been typed from
a file.

The code is somewhere in the historical records department
at Byte Craft then all I need is to find a paper reader that
has been run in the last 20 years.

w..


David VanHorn wrote:

> > The sounder already works but the code is un-clean. I'm still well under 200
> > words. I think that I can fit a complete sender and receiver in the smallest
> > available pics (12{c,f}508} with an external eeprom for some fun projects.
>
> I'm interested to see how you implement the decoder part, particularly
> with off-air signals.  I know the boxcar integrator approach for tone
> filtering, I've used it in several DF projects, but hadn't thought
> that you could implement it in a more wideband version.
> -

2007\04\12@110631 by Peter P.

picon face
Walter Banks <walter <at> bytecraft.com> writes:

> I wrote a Morse decode for demonstration for a friend for a ham
> convention in the early 70's on a PDP8/e. It was designed to be
> speed tracking and worked quite well on hand sent code. The
> algorithm I used was to base the starting speed on the the last
> received character and analyse the speed of the received
> character to update the received speed. I remember two
> things debugging the code. For a while small noise pulses
> were interpreted as dots and were hard (at the time) to filter
> out in software. the second thing that should not have been
> a surprise was the dit / dah ratio in hand sent code was far
> from close and we did some tracking on the ratio as well.

Yes I know about timing issues. Inspecting my own ham (pun!) fist (re-pun!)
output on a waterfall display does not show anything promising wrt. to easy
decoding by machine. I was thinking along the lines of 'listening' for a while,
measuring timings, and then setting a set of discrimination levels and starting
decoding, while continuing to track average timings and tweaking the
discrimination levels to follow. I have no intention to base this on standard
timings at all. As a rough guide from my waterfall 'analysis' I'd say anything
from 50% to 200% dot is a valid dot, ditto symbol-symbol breaks, dashes from
220% to 500% dot and character-character gaps the same.

{Quote hidden}

I think that that could be helped. There is a way to transfer paper tapes into
computers using a scanner and a black sheet of paper as backing. The computer
assembles the parts by itself and decodes the info. Somebody wrote software for
that (*nix probably). There is also the same for punched cards I think. Nowadays
this could work with a webcam (on *nix the scanner interface permits 'scanning'
from *any* video source - that includes webcams, video cards and screenshots by
the way).

thnaks for posting,
Peter P.



2007\04\12@115238 by Alan B. Pearce

face picon face
>I have no intention to base this on standard timings at all.
>As a rough guide from my waterfall 'analysis' I'd say anything
>from 50% to 200% dot is a valid dot,

I seem to remember this sort of program appearing Byte magazine (or maybe
QST) in the early days of the "computer revolution" as a 'whatduzitdo' type
program for hams. I seem to remember periods of 50% to 150% being used for
timing received streams.

>> The code is somewhere in the historical records department
>> at Byte Craft then all I need is to find a paper reader that
>> has been run in the last 20 years.
>
>I think that that could be helped. There is a way to transfer paper tapes
>into computers using a scanner and a black sheet of paper as backing.

Oh, I hadn't heard of that scheme. Sounds like it could be a do-er though,
but would require a fair amount of operator time. I have some old tapes of
bits I wouldn't mind getting at, and have been considering building a little
reader with some surface mount leads on some strip board as receivers, and a
second set as emitters, with a small stepper or DC motor to pull the tape
through. A suitable small PIC with UART to send it out as serial stream and
control the motor would complete the scheme.

2007\04\12@142359 by Rich Satterlee

flavicon
face
Hi-

"with a small stepper or DC motor to pull the tape through."

You don't need a stepper for this.  Use the sprocket hole from the paper tape
as the sensor for the data bits from the tape and just pull the tape along.  This
was done in the very early days of home computing.  Late 70's type stuff.  In
fact, in those days, there were little kits for just such pull along paper tape
readers.  Anybody else still have an S100 buss machine?

 Cheers,

  Rich S.


---- Original Message ----
From:                Alan B. Pearce
Date:                Thu 4/12/07 9:13
To:                Microcontroller discussion list - Public.
Subject:        Re: [PIC] Morse Code Firmware -- not big enough

>I have no intention to base this on standard timings at all.
>As a rough guide from my waterfall 'analysis' I'd say anything
>from 50% to 200% dot is a valid dot,

I seem to remember this sort of program appearing Byte magazine (or maybe
QST) in the early days of the "computer revolution" as a 'whatduzitdo' type
program for hams. I seem to remember periods of 50% to 150% being used for
timing received streams.

>> The code is somewhere in the historical records department
>> at Byte Craft then all I need is to find a paper reader that
>> has been run in the last 20 years.
>
>I think that that could be helped. There is a way to transfer paper tapes
>into computers using a scanner and a black sheet of paper as backing.

Oh, I hadn't heard of that scheme. Sounds like it could be a do-er though,
but would require a fair amount of operator time. I have some old tapes of
bits I wouldn't mind getting at, and have been considering building a little
reader with some surface mount leads on some strip board as receivers, and a
second set as emitters, with a small stepper or DC motor to pull the tape
through. A suitable small PIC with UART to send it out as serial stream and
control the motor would complete the scheme.

2007\04\12@145407 by David VanHorn

picon face
On 4/12/07, Rich Satterlee <RemoveMEpicEraseMEspamEraseMEsatterlees.com> wrote:
> Hi-
>
> "with a small stepper or DC motor to pull the tape through."
>
> You don't need a stepper for this.  Use the sprocket hole from the paper tape
> as the sensor for the data bits from the tape and just pull the tape along.  This
> was done in the very early days of home computing.  Late 70's type stuff.  In
> fact, in those days, there were little kits for just such pull along paper tape
> readers.  Anybody else still have an S100 buss machine?

Nine phototransistors and a processor, and you can have the output in
hex, or whatever.

2007\04\12@164425 by Peter P.

picon face
Alan B. Pearce <A.B.Pearce <at> rl.ac.uk> writes:
> program for hams. I seem to remember periods of 50% to 150% being used for
> timing received streams.

I'd rather measure timing for a while and sort marks into two bins, 'long' and
'short', *then* I'd compute some discrimination limits based on that, and then,
I'd try to start decoding based on that, and while updating it (and maybe
median filtering to cast out 'aliens'). There would also be two averages for
spaces (short and long(er)). But for a PIC, this gets a little long in the
tooth, so I'll try something simple, like:

// pseudocode, untested and almost certainly wrong and lacking in more than one
// way
Hunt=0; // 0...HUNTED, RECEIVING
Ditcount=0; Dittime=0;
Dahcount=0; Dahtime=0;
Ditspcount=0;    Ditsptime=0;
LLspcount=0;     LLsptime=0;
Acc = 1;
Flags &= ~(IDLE | RECEIVED_CHAR);
// try to decode characters. Output in Buffer marked by Flag
while((what,time)=measure_period()) {
 // detect no signal
 if(what == TIMEOUT) {
   Flags |= IDLE;
   if(Hunt == RECEIVING) {
     Buffer = Acc; Flags |= RECEIVED_CHAR; Acc = 1;
   }
   continue;
 } else { Flags &= ~IDLE; }
 // detect enough training
 if(Hunt < HUNTED) {
   if((Ditcount >= DITS) && (Dahcount >= DAHS)
     && (Ditspcount >= DITSPCS) && (LLspcount >= LLSPCS))
       Hunt = HUNTED; // now wait for a long space which will start recv.
 }
 // key down
 if(what == MARK) {
   // first assume dits
   if(!Ditcount++) { Dittime = time; continue; }
   else {
     if(time > 2 * Dittime) {
       if(!Dahcount++) {Dahtime = time;}
       else {Dahtime += time; Dahtime /= 2;}
     } else {
       if(time < 0.5 * Dittime) {
         if((Hunt < HUNTED) && (time > GLITCH)) {
           // got it wrong, swap dit and dah accumulators
           t = Dittime;  Dittime  = Dahtime;  Dahtime  = t;
           t = Ditcount; Ditcount = Dahcount; Dahcount = t;
         } else {
           // toss current char on glitch
           if(Hunt >= HUNT) {
             Acc = 1; Hunt = HUNT;
             Buffer = GLITCH_CHARACTER; Flags |= RECEIVED_CHAR;
           }
           continue;
         }
       }
       if(!Ditcount++) Dittime = time;
       else {Dittime += time; Dittime /= 2;}
     }
   }
 }
 // key up
 if(what == SPACE) {
   // ... similar to above to fill initial bins

 }
 // start/stop condition iff ready (HUNTED or RECEIVING)
 if((Hunt >= HUNTED) && (time > 5 * Ditsp)) {
     // end of previous character
     if(Hunt == RECEIVING) {
       Buffer = Acc; Flags |= RECEIVED_CHAR; Acc = 1; Acl = 0; continue;
     }
     // expecting first symbol of next (or first) char
     if(Hunt == HUNTED) Hunt = RECEIVING;
   }
 }
 // if everything works, receive symbols
 if(Hunt == RECEIVING) {
   Acc <<= 1; if((what == MARK) && (time > 2 * Dittime)) ++Acc;
   if(Acc == 0x100) {
     // 8 dits, drop it (max receivable is 7 symbols/char due to byte enc.
     Buffer = ERROR_CHARACTER; Acc = 1; Hunt = HUNTED; Flags |= RECEIVED_CHAR;
   }
 }
}

Note1: the symbol TRAINED can be used instead of HUNTED.

Note2: the bins need not start empty. But during receiving, if the speed changes
abruptly, the system should be reset or forced into training mode. Some
heuristics may have to be used for this.

Note3: There may be a more elegant way to do this, but likely involving a single
'action' function and a lot of variables stored as a structure. Then the code
could be shared for MARK and SPACES sections.

{Quote hidden}

The hint about the camera and (which is also a) scanner is the winner. Just run
the camera in capture mode and pull the tape slowly in front of it. The computer
can make sense of the resulting movie. Note that I haven't seen this part
working but it should. There is no difference between individual consecutive
frames split from a movie and a set of consecutive scans. If the camera manages
10fps and its fov spans 10 x 10 cm you can pull the tape with at least 50 cm/sec
without losing data. That is not so slow.

Peter P.



2007\04\12@170755 by Peter P.

picon face
David VanHorn <dvanhorn <at> microbrix.com> writes:

> Nine phototransistors and a processor, and you can have the output in
> hex, or whatever.

Please, you can buy 300,000 phototransistors in a USB webcam for $20 and the
average 1.5 GHz CPU is more than enough to work with that output in realtime
(and likely faster than any original paper tape reader ever did with some
tweaks).


Peter P.


2007\04\12@222822 by Martin Klingensmith

picon face
Sorry to nit-pick, but a CCD is a bunch of "opto-capacitors" not photo
transistors.
--
Martin K

On 4/12/07, Peter P. <RemoveMEplpeter2006spam_OUTspamKILLspamyahoo.com> wrote:
{Quote hidden}

2007\04\13@043315 by Alan B. Pearce

face picon face
>"with a small stepper or DC motor to pull the tape through."
>
>You don't need a stepper for this.  Use the sprocket hole from
>the paper tape as the sensor for the data bits from the tape
>and just pull the tape along.

Yeah, I was expecting to use the sprocket holes for clocking, it was more a
case of using a small stepper (like might be recovered from an old floppy
drive) may be easier that sourcing a suitable DC motor.

2007\04\13@072853 by Peter P.

picon face
Martin Klingensmith <martin.klingensmith <at> gmail.com> writes:

> Sorry to nit-pick, but a CCD is a bunch of "opto-capacitors" not photo
> transistors.

They are photodiodes with stray capacitance that is put to good use ...

Peter P.


More... (looser matching)
- Last day of these posts
- In 2007 , 2008 only
- Today
- New search...