It's probably easier to try to get a purely software serial (i.e. no hardware timers) working. Here's some code that tries to do, but doesn't quite work.
The fudge
variable is used to slightly adjust the delay between bits for each byte read - an attempt to get the timing exactly right.
#define BAUDRATE 9600
// the width of a single bit of serial data in microseconds
// in each second (1000000 microseconds) there are a number of bits equal
// to the baud rate (e.g. 9600), so each bit lasts for 1000000 / baudrate
// microseconds
int width = 1000000 / BAUDRATE;
int fudge = 20;
int val = 0;
int count = 0;
int rx = 6;
void setup() {
pinMode(rx,INPUT);
digitalWrite(13,HIGH);
beginSerial(BAUDRATE);
}
void loop() {
int offset;
boolean error = true;
// one byte of serial data (LSB first)
// ...--\ /--\/--\/--\/--\/--\/--\/--\/--\/--...
// \--/\--/\--/\--/\--/\--/\--/\--/\--/
// start 0 1 2 3 4 5 6 7 stop
while (digitalRead(rx));
// frame start indicated by a falling edge and low start bit
// jump to middle of start bit
//delayMicroseconds(width / 2 + fudge);
// confirm that this is a real start bit, not line noise
//if (digitalRead(rx) == LOW) {
for (offset = 0; offset < 8; offset++) {
// jump to middle of next bit
delayMicroseconds(width + fudge);
val |= digitalRead(rx) << offset;
}
// check stop bit is high
delayMicroseconds(width + fudge);
if (digitalRead(rx) == HIGH) {
error = false;
}
serialWrite(val);
count++;
if (count % 2 == 0) {
fudge--;
serialWrite(width + fudge);
}
//}
}