I think you suggested Manchester encoding in the first place? If so many thanks! The good thing about it is that the Arduino version seems to work pretty well "straight out of the box".
You have given a very clear explanation above. I now understand that the "Preamble" also sets the clock amongst other things.
I quote the rather less clear Radiometrix guide below: (The links in the article don't work.)
"Your data over a simple radio link" By Myk Dormer - Senior RF design engineer, Radiometrix
First published in Electronics World magazine. March 2007 issue
Application note 028
A practical realisation:
It is possible to still use a hardware UART (rs232 type asynchronous interface) and fulfil all the requirements of the link, if
a little care is taken.
The data is sent in a burst, or packet, comprising of:
[preamble] [uart ‘start’ byte] [framing bytes] [data ‘payload’] [checksum]
Characters must be sent continuously, start bit to stop bit without gaps (or the mark:space ratio will become unpredictable)
Assuming 1+8+1 (one start, 8 data, 1 stop) format, a sequence of 55h (ascii U) characters provides a square wave
preamble. After the transmitter is turned on, a stream of these preamble bytes must be sent, until the ‘tx-on’ time spec. of
the radio module used has been met. (This will usually be between 3 and 50mS, depending on the module)
An FFh byte must immediately follow the preamble, so the UART can frame on an identifiable start bit. To maintain DC
balance, a 00h byte must follow the FFh. Both these bytes can form part of the decoded ‘framing’ sequence of the burst.
Then, to maintain mark:space balance, data can be sent by using only those characters with an equal number of ones and
zeros in them. Of the 256 possible 8 bit codes, 70 contain 4 ones & 4 zeros. Omitting 0Fh, F0h, 3Ch and C3h (worst case
‘four ones in a row’ bit sequences) still leaves 66 usable codes per byte, which allows six bits of actual data to be coded
into each transmitted byte.
(A full explanation of this method can be found here: http://www.radiometrix.co.uk/products/bimsheet.htm#rs232)
It is necessary to use a number of fixed value bytes preceding the actual data ‘payload’ as packet identification (or
‘framing’ ), to allow the decoder to tell a valid data burst from random channel noise. (In my experience, to avoid false
triggering of the decoder, at lease 3-4 bytes of framing data will be necessary.)
Additionally, one or more ‘address’ bytes may be added (to allow co-located operation of multiple systems, or polled
access of multiple receivers by a single transmitter), and ideally, a checksum of some kind should be added to the data
packet, as an extra precaution against spurious triggering.
I have described a very simple protocol here. There are many, far more sophisticated techniques in use throughout the
industry. The method described does not even offer the best in S/N performance (as the edge triggered UART receiver is
overly susceptible to data bit jitter and dropouts compared to a proper duration measuring biphase decoder) but it shows a
workable technique, with a minimum of software effort and processing overheads.
Sometimes a simple approach is sufficient.