0
\$\begingroup\$

I thought that hooking the same wire into two pins(2 and 3, on an Uno) would work, but it doesn't appear to be.

The sketch looks like such.

byte b;

NewSoftSerial nss(2,3);

void setup()
{
  nss.begin(9600);
  Serial.begin(9600);
}

void loop() {
  // if theres data from the bluetooth module
  if (nss.available()>0) {//this is never true
    //echo it to the serial monitor
    Serial.print("nss echo:");
    Serial.println((char)nss.read(),BYTE);
  }
  if (Serial.available()>0) {
    b=Serial.read();
    //echo it back to the serial monitor
    Serial.print("serial echo:");

    Serial.println(b,BYTE);
    //send it to the bluetooth module
    nss.print(b,BYTE);
  }
}

I expected to see pairs of outputs for every input.

serial echo:g
nss echo:g

What am I doing wrong?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You're probably not doing anything wrong, but you are hitting a limitation of the library.

NewSoftSerial disables interupts on transmission, to ensure clean timing of the transmitted byte. As NSS receives data by picking up an interrupt on the receive pin, that interupt isn't fired, meaning nothing is received.

For reference, the write(byte) function of NSS

void NewSoftSerial::write(uint8_t b)
{
      //irrelevant code

  uint8_t oldSREG = SREG;
  cli();  // turn off interrupts for a clean txmit

  // Write the start bit
  tx_pin_write(_inverse_logic ? HIGH : LOW);
  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);

      //code to send a byte, omitted for brevity

  SREG = oldSREG; // turn interrupts back on
  tunedDelay(_tx_delay);
}

And the recv function:

void NewSoftSerial::recv()
{
  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())
  {
    // Wait approximately 1/2 of a bit width to "center" the sample
    tunedDelay(_rx_delay_centering);

    // Read each of the 8 bits
    for (uint8_t i=0x1; i; i <<= 1)
    {
      tunedDelay(_rx_delay_intrabit);
      uint8_t noti = ~i;
      if (rx_pin_read())
        d |= i;
      else // else clause added to ensure function timing is ~balanced
        d &= noti;
    }

    // skip the stop bit
    tunedDelay(_rx_delay_stopbit);

            //buffer code omitted
  }
}

Two things to note: both routines assume they'll have control while sending/receiving. Basically, NSS is half duplex, no simultaneous read and write.

If you want to test it, what you could do is tie the RX pin from the arduino (pin 0 I think; will be TX of the USB serial chip) to RX of NSS. What this will do is any data coming down from USB serial will be sent to both Serial and NSS. You can then transmit the NSS received data using Serial. Should work, but has not been tested.

\$\endgroup\$
0

Your Answer

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

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