Originally Posted by midin
- how do I recognize the start/parity/stop bitin every scan code sentence?
That all depends on the serial protocol and the serial port settings. Those settings could include transmission rates (AKA "baud rate"), type of parity, number of data bits, number of stop bits, all depending on that particular serial protocol -- see Serial Port: Settings
Back in the late 1980's, I wrote assembly code for a low-powered Intel processor, ¿8749? (it's been a few decades, after all), which was coincidentally of the same family as the microprocessor in the original IBM/PC keyboards. Our devices communicated via an RS-232 serial port. Normally, you would use a separate hardware device called a UART to receive and send RS-232 serial streams and convert between the serial stream waveform and bytes of data; in some microprocessors a UART is built in. But to cut down on the size and cost of our devices (sensors and controllers for greenhouses), we did it all in software. It's been a long time, but here's a brief explanation from memory. Bear in mind that this is for one particular implementation of RS-232, often called the "non-standard standard" because of a wide number of variants; your own serial protocol may very well be quite different:
A character wave-form consists of the following parts in this order:
1. The "mark hold".
2. The start bit.
3. Several data bits (though a fixed number of them, depending on the settings). Note that normally with RS-232 we would receive the least significant bit first (LSB), on contrast to your protocol which receives the MSB first.
4. Optional parity bit, depending on the settings.
5. 1 to 2 stop bits, depending on the settings.
6. Reinstatement of the mark hold.
Characters are sent asynchronously, meaning that the next character could arrive unannounced at any time. The signal level between characters is a constant high (1) and is called a "mark hold". When the signal drops from the mark hold to a zero, then that marks the beginning of the start bit. Since you know beforehand what the baud rate is, you know how wide each bit is in terms of time. One bit-width later will be the start of the first data bit. What you want to do to read each data bit is to wait until the middle of the bit; that way you ensure that you are reading that bit and only that bit. Furthermore, you read it at least three times and then "take a vote" in order to prevent false values due to noise or other factors. Then you wait a full bit width for the next data bit and so on until all the data bits have been read. The number of data bits will depend on the settings. Then if you are using parity, you will read the parity bit the same way you read the data bits. Finally, you get to the stop bits. Some devices, especially electromechanical teletypes, rely on the stop bits, but our devices did not so we just merely observed that they were present and marked their passage. Then the signal level returns back to the mark hold.
One thing to note is that timing is critical. My microprocessor had a defined clock speed and each machine instruction had a defined number of clock cycles that it would take to execute, so I could, and did, read through a series of machine instructions and calculate exactly how long they would all take to execute. I needed to do that in order to obtain the timing needed to mark out each bit width. And whenever I had to perform a conditional jump, which was often (an industry average that we were taught in school was that on average one instruction in four is a jump), I had to trace through both branches of that jump to ensure that they were both of exactly the same length time-wise -- I would have to insert however many NOP instructions as were needed to pad that out. Please also note that the only reason I was able to do that was because I was working in assembly. It would have been impossible to do that with C or any other higher-level language (our host computer ran a Pascal program to communicate with the devices), since you have no control over the assembly code that a compiler would emit.
Again, your mileage with your own particular serial protocol and your own particular microprocessor may vary.