Yes the plan is a message format with an address and error check at the end. My concern is that if a reception is triggered by anything I could never be in sync.
Consider this usual stream format:
START LEN PAYLOAD CRC
By choosing START magic number properly, odds that it is repeated in payload are made smaller (can be multibyte):
acdcabba 05 (01 02 03 04 05) 13 37
Now it's still possible that acdcabba repeats in data:
acdcabba 05 (01 ac dc ab ba) 21 18
When you start parsing at correct start id, CRC check succeeds -> you are now in sync with the stream.
But let's say you are out of sync and accidentally sync to the wrong acdcabba. Now 0x21 in above example is interpreted as length. You have to read many bytes and lose many packets before you get to what you think is CRC, get mismatch and only then detect the error.
Worse, if the unlucky packets containing acdcabba are recurring, chances are you always try to resynchronize on the wrong start id, and never get a sync.
Solution to this is to buffer bytes and if CRC mismatch happens, scan old bytes in the buffer to find another acdcabba. One of them must be the right identifier. You can guarantee to get back in sync this way, but scanning the whole buffer many times is more work and also requires much more processing than byte-by-byte parsing while bytes are received.
Or, you can just accept not to cover this problem. With a long (say 32-bit), randomly chosen magic number and low error rates, the failure condition of never getting sync is extremely rare.
One way of mitigating the problem of having to waste a lot of packets due to misidentification or corruption of length field, is to use separate CRC for header only. For example, a 8-byte header block: START32 LEN16 MSGID8 CRC8, followed by payload and then CRC16 over the payload. Now, chances of this 64-bit sequence (including valid CRC) occurring in payload is extremely small, and that repeating in every data frame even more slim.
This post is assuming you want to use all possible byte values in payload. If you are willing to remove 1:1 mapping from raw payload to packet payload, you can choose unique values for start/end identifiers as peter-h suggests, but then you need to escape these values in data, and data length becomes different to original raw payload.
ASCII is good when you want human interoperability, but on the other hand, ASCII-based systems have been notoriously troublesome, despite good intentions.