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

  • 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. – Ignacio Vazquez-Abrams Aug 5 '16 at 18:06
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.

  • 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. – chugadie Aug 8 '16 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? – Majenko Aug 8 '16 at 12:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.