so presumably I have some code in my MCU that scans through what it is receiving from the PC and when it recognizes a code it carries out instructions.
Yes, you decide on a packet length you want. (or you can code a variable packet length protocol if you want something a bit more robust for large data transfers)
It's easy/fast to use a fixed length and have a hardcoded start of packet marker.
This is really crude, but you might have a 8 byte frame like this..
STR,a,cd
Where
STR = 3 byte start of packet marker
a = 1 address byte (so 255 possible nodes on the bus)
c = 1 command byte
d = 1 data/payload byte
, = separator (more on this later)
You would start filling up an array when you detect the letters STR in sequence. After 8 bytes you run some packet handling code to do whatever events you want based on the a,c,d data.
You can ignore the packet if the address doesn't match the address of the mcu checking it. etc..
Use a C switch statement on the command byte. That would give you 255 possible commands and each could carry 1 byte of info.
eg, command=45 (says flash LED1) payload=10 (says flash this led 10 times)
The reason i included the 2 commas was so you cannot physically have a STR in the data/address section, this is crude but means you can never get out of sync (where STR inside the packet gets interpreted as the start of a packet).
You could add a checksum as well, a simple XOR of all the bytes and attach the result to the end of the packet.
If, when receiving a packet, it doesn't match ignore the packet (it's corrupt).
It gets more complex if you need a protocol that ensures a packet gets to the destination without being corrupted.
You then need to code an packet acknowledge and resend system etc..