Last evening, I shared the experience of creating a FeldHell-like QRSS beacon. The bulk of the effort was in creating an acceptable font. The Propeller chip has a rather nice font already in ROM but it is more suited for TV video output than for QRSS due to its 16x32 size. I felt that this was too much bandwidth to occupy for a single signal in the QRSS band.
I created the font definition in a text editor and decided to try a 5x7 font initially. With this format, each character is 5 bytes (one byte for each column of the font character). For example, the letter "A" is represented thus:
Each colum of the character in the 5x7 grid is encoded as a byte where the "X" character above is encoded as a set bit and the lack of an "X" is encoded as a 0. So to create this, I defined all my characters (0..9, A..Z) as shown above in a text file. I then imported the text file into a spreadsheet and rotated the rows and columns 90 degrees using the spreadsheet "Transpose" function. This had the effect of laying all the characters down on their sides, thus:
I then exported the file back to a text file for further processing. You have to now imagine each of the font characters lying on their sides like the example above, occupying five very long lines of my text file. I then globally replaced all the space characters (there is a space in each 5x7 grid anyplace there is no "X") with a "0" character and replaced the "X" characters with "1". For the "A" character above, this resulted in:
I then turned this mess into a valid DAT block containing binary byte values like so:
' FeldHell font definitions
' A B etc
Col5 BYTE %0111111, %xxxxxxx, ...
Col4 BYTE %1001000, %xxxxxxx, ...
Col3 BYTE %1001000, %xxxxxxx, ...
Col2 BYTE %1001000, %xxxxxxx, ...
Col1 BYTE %0111111, %xxxxxxx, ...
Now I can index into this table and obtain the column data I need for each character. So now in the main loop, I can call this procedure to process the beacon text:
' Send Feld Hell beacon text
The code to send each character is a quick hack, so don't beat me up too much. I am still playing around with the timing to make it look nice. Each character of the message text is looked up in the DAT table above to obtain the byte containing each of the 5 column definitions. The character is sent from bottom left (least significant bit of Col1) to the top of the column and then proceeding with the next column until all five columns have been sent. I test the least significant bit of each byte of column data and send a tone if it is set and send nothing if unset. Right shift to get the next bit and continue for all 7 bits.
PUB sendFeldHellChar(ch) | i, j, iCol, columnData, Time
Time := 300
' set up column index to default to space character
iCol := -1
"a".."z": iCol := ch - "a" + 10
"A".."Z": iCol := ch - "A" + 10
"0".."9": iCol := ch - "0"
if iCol < 0
delay(Time*12) ' Handle the space character specially
repeat i from 4 to 0 ' 5 columns in reverse order
columnData := Col5[iCol+(i*36)] ' get the current column data
repeat j from 0 to 6
if columnData & 1 ' If the font bit is set, send a tone
columnData >>= 1 ' Right shift font data to get next bit
delay(Time) ' Give a little space between columns
delay(Time*6) ' Give a little more space between letters
So, that is it... Simple, eh? Since the font definition is five really long lines of text, I am not going to post the entire program here. If you would like to have a copy of it however, I will be happy to email it to you if you will drop me a comment to this post on the blog.
I will be creating "a".."z" characters in the font and some punctuation, but have no plans to create any characters beyond what would be in a typical QRSS message. I am using Eldon's 10 minute QRSS sync algorithm for stacked grabbers. See his article here.
Here is what it looks like on the air: