polling version in pseudocode
byte = 0;
wait for low;
wait 1.5 ms; // go to middle of start bit
for (int i=0; i< 7; i++)
{
wait 3ms; // middle of next bit;
byte = byte << 1 + digitalRead(pin);
}
You can make it also interrupt based and compare the timestamp of the LOW with the timestamp of the last HIGH.
You need an ISR on CHANGE
pseudocode not tested
ISR()
{
if (pin == HIGH) lastHIGH = millis();
else
{
if (millis() - lastHIGH == 3)
{
byte = 0; // start a new byte
count = 0;
}
else if (millis() - lastHIGH == 2) byte << 1 + 1;
else byte << 1;
count++;
if (count == 8) ==> action on the byte.
}
}