In my previous post about completing my initial code for my MCU based beacon keyer I made mention to the use of memory. Indeed, my code was of such size I had to use the largest AVR ATtiny chip I could (well, memory wise). The ATtiny85 gave me a whopping 512 bytes of SRAM – and 512 of EEPROM and 8KB of flash. Who could ever need more than that right!
Sending just my callsign (VK1IS) worked fine with my code running on this MCU, however last night I thought I'd try the longer string of:
CQ CQ CQ DE VK1IS VK1IS VK1IS K
Could be useful for common CW comms.
Unfortunately, that resulted in the chip running out of memory when it got the third iteration of my callsign. With compile time memory usage being up at 260 bytes with this string; then the need for memory for active instructions; and then finally the dynamically allocated memory to store the encoded version of that string; there simply wasn't enough space. Indeed, with my current encoding method, to encode that string required more than 150 bytes and that was more than was available (after the 260 bytes at compile time and active instructions). (Note here, my look-up tables – by manual calculations – require 223 bytes!!)
So, it seems I should do some memory optimisations after all.
Conveniently, I received an email from Owen this morning (VK1OD) informing me that it is possible to encode all Morse characters in 8 bits. So after a bit of pondering I realised this would be possible by just using (for example) 1 for dit and 0 for dah. But seeing it's variable length what do you use for a marker for the start. In trying to figure this out, eventually I decided to be lazy and search the web. That search revealed this:
Seems all I need is to just mark the start of a sequence with a 1:
The format of each Morse character is as follows: Zero or more 0 bits, followed by a single 1 bit, followed by the Morse Code representation of the character in binary, with a 0 indicating a dit and a 1 indicating a dah.
That first "single 1 bit" is what then marks the start.
With this method one can definitely encode all 41 characters in the Koch set plus a good number of prosigns (AR, KN, etc.). As time permits I think I'll look at writing another cw library to implement this. Big memory will be saved – about 75% – and maybe I'll look to see if I bother with an intermediary encoding of the string or not (I have some ideas on how to deal with that to save significant memory.) Maybe it'll fit on an ATtiny13 yet (64 bytes of SRAM, 64 bytes of EEPROM and 1KB of Flash).
While looking at this I also looked at the code for the Freakin Beacon
. It seems rather than a look-up table they've gone down the path of a subroutine for every character. This would save on SRAM, but then the code size would be bigger. I may also consider looking at this as another option – should be able to generate the code for this from my current CW library. 😉