0

In the SoftwareSerial library, I see the beginning of recv() as follows

void SoftwareSerial::recv()
{
#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Preserve the registers that the compiler misses
// (courtesy of Arduino forum user *etracer*)
 asm volatile(
 "push r18 \n\t"
 "push r19 \n\t"
 "push r20 \n\t"
 "push r21 \n\t"
 "push r22 \n\t"
 "push r23 \n\t"
 "push r26 \n\t"
 "push r27 \n\t"
 ::);
#endif 
 uint8_t d = 0;
 // If RX line is high, then we don't see any start bit
 // so interrupt is probably not for us
 if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
 { 

This comment seems to be testing for if the pin change was from low to high, or high to low. If you are using inverse logic - where the line is held high, and start bits are low - then a call to rx_pin_read() should return 0.

This doesn't seem correct. In inverse logic the line is held high and a drop indicates a start bit.

Is the SoftwareSerial library ignoring the start bit and relying on some kind of return to zero break between the start bit and any subsequent bits?

It seems like it can't handle start bits followed by high bits since there would be no change in the pin state.

typical ttl

asked Aug 5, 2016 at 18:02
1
  • 1
    "If you are using inverse logic - where the line is held high, and start bits are low" No, that's normal logic for a UART. Commented Aug 5, 2016 at 18:06

1 Answer 1

1

This doesn't seem correct. In inverse logic the line is held high and a drop indicates a start bit.

No, in inverse logic (for a UART) the line is held LOW and a rise indicates a start bit. The diagrams you show in your question show that UART communication normally is HIGH with LOW for a start bit.

It seems like it can't handle start bits followed by high bits since there would be no change in the pin state.

The PCINT is only used to identify the falling (or rising in the case of inverse logic) edge of the start bit. From then on it samples at pre-defined periods to read each bit. Accurate timing is needed for that, so assembly code is used to give precise delays (see tunedDelay()). Once the whole 10-bit packet has been received the interrupt handler finishes and control is returned to the main thread again. The PCINT is then free to look for the next start bit.

answered Aug 7, 2016 at 16:36
2
  • But, it doesn't look for a start bit. It just ignores the start bit and hopes that the second bit has a rising edge. There's no tunedDelay() to wait for the next bit after the start bit. Commented Aug 8, 2016 at 12:34
  • No it doesn't. It uses the falling edge of the start bit to begin receiving. That is the ONLY edge that is ever looked at. It then immediately delays for half a bit to centre the readings properly, then reads 8 bits with a full bit delay preceding each read. Have you actually read and understood the ::recv() function? Commented Aug 8, 2016 at 12:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.