Uno R3 Fails Serial Loopback Test Pins 10, 11

I have been having trouble with the serial connection between an Uno and a DY player, so I ran a loopback test last night and I get no response. Not sure if I just need to replace the Uno, or if there are other options. I put a jumper wire between pins 10 and 11 and ran the following code. Also tried pins 12 and 13 adjusting the code to reflect the pin change. It should be noted that I do get "Testing Pins 10/11..." in the serial monitor. Sometimes it prints twice or something like "Tes Pins 10/11..." but no response from the Rx pin. Appreciate any advice.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {

Serial.begin(9600); // USB Monitor

mySerial.begin(9600); // Software Serial

Serial.println("Testing Pins 10/11...");

}

void loop() {

mySerial.print("T"); // Send test data out of 11

if (mySerial.available()) {

char c = mySerial.read(); // Read it back into 10

Serial.print("Received: ");

Serial.println(c);

}

delay(500);

}

From Software Serial in the Arduino docs:

Limitations of This Library

SoftwareSerial library has the following known limitations:

  • It cannot transmit and receive data at the same time.

@van_der_decken nailed it, that library is blocking. Here is the part that is getting you:

Transmission (write) is fully blocking:
While a byte is being sent, the CPU is tied up bit-banging each bit at the correct baud rate. Nothing else runs during that time.

You can try the AltSoftSerial or NeoSWerial libraries. The best solution is to use a processor with two asynchronous ports.

Thank you. I found another thread "Loop Back Test - Sticky?" that suggest holding the processor in reset while using terminal. Would this be an effective way of testing Tx Rx on pins 10 & 11?

That ONLY tests your PC!!! Your Arduino will not be running at all!

Got it. Thanks.

Hi @analog-ev. I'll provide some sketches you can use to test the basic functionality of the SoftwareSerial interface:

Transmit

/*
  # SoftwareSerial Transmit Test

  Use for testing SoftwareSerial transmit functionality.

  A standard loopback configuration can't be used with SoftwareSerial because it doesn't support transmitting and
  receiving data at the same time.

  ## Circuit

  Connect SoftwareSerial TX pin to pin 1 (TX).

  ## Usage

  1. Upload this sketch to the board.
  2. Disconnect the USB cable from the board.
  3. Connect the SoftwareSerial TX pin to pin 1 on the board (TX)*.
  4. Connect the board to your computer with the USB cable.
  5. Open Serial Monitor.
  6. Select "9600" from the Serial Monitor baud rate menu.

  You should now see "Hello, world!" printed at 0.5 Hz to the Serial Monitor output panel.

  IMPORTANT: Once you are finished, disconnect the circuit. You must do this before attempting another sketch
  upload, as otherwise the circuit may interfere with the upload.

  ### Footnotes

  * This connection may seem wrong, since we must always connect the transmit pin to the receive pin. However, the
  "TX" label on pin 1 is in relation to its connection to the board's primary microcontroller. In this case, we are
  actually communicating directly between the software serial interface and the board's USB to serial bridge to the PC.
  The bridge chip has an RX-TX connection to the board's primary microcontroller, so the pin labeled "TXT" on the board
  is actually connected to the RX pin on the bridge chip.

  ---

  This work is licensed under the CC0 1.0 license:
  https://creativecommons.org/publicdomain/zero/1.0/
*/

// See: https://docs.arduino.cc/learn/built-in-libraries/software-serial/
#include <SoftwareSerial.h>

// See: https://docs.arduino.cc/learn/built-in-libraries/software-serial/#limitations-of-this-library
const byte softwareSerialRxPin = 10;
const byte softwareSerialTxPin = 11;

// See: https://docs.arduino.cc/learn/built-in-libraries/software-serial/#limitations-of-this-library
const unsigned int baudRate = 9600;

SoftwareSerial SoftSerial(softwareSerialRxPin, softwareSerialTxPin);

void setup() {
  SoftSerial.begin(baudRate);
}

void loop() {
  SoftSerial.println("Hello, world!");
  delay(1000);
}

Receive

/*
  # SoftwareSerial Receive Test

  Use for testing SoftwareSerial receive functionality.

  ## Usage

  1. Upload this sketch to the board.
  2. Disconnect the USB cable from the board.
  3. Connect the SoftwareSerial RX pin to pin 1 on the board (TX).
  4. Connect the board to your computer with the USB cable.

  You should see the onboard LED blink at 0.5 Hz.

  IMPORTANT: Once you are finished, disconnect the circuit. You must do this before attempting another sketch
  upload, as otherwise the circuit may interfere with the upload.

  ---

  This work is licensed under the CC0 1.0 license:
  https://creativecommons.org/publicdomain/zero/1.0/
*/

// See: https://docs.arduino.cc/learn/built-in-libraries/software-serial/
#include <SoftwareSerial.h>

// See: https://docs.arduino.cc/learn/built-in-libraries/software-serial/#limitations-of-this-library
const byte softwareSerialRxPin = 10;
const byte softwareSerialTxPin = 11;

// See: https://docs.arduino.cc/learn/built-in-libraries/software-serial/#limitations-of-this-library
const unsigned int baudRate = 9600;

SoftwareSerial SoftSerial(softwareSerialRxPin, softwareSerialTxPin);

unsigned long previousMillis;
byte ledPinState;

void setup() {
  Serial.begin(baudRate);
  SoftSerial.begin(baudRate);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  const char transmitData[] = "hello\r\n";
  if (millis() - previousMillis >= 1000) {
    previousMillis = millis();
    Serial.write(transmitData);
  }

  if (SoftSerial.available()) {
    delay(10);  // Give time for all data to be received.
    if (SoftSerial.available() != strlen(transmitData)) {
      // Ignore received data of unexpected length.
      // Clear the receive buffer.
      while (SoftSerial.available()) {
        SoftSerial.read();
      }
    } else {
      // Received data has expected length.
      char receiveBuffer[sizeof(transmitData) + 1];
      SoftSerial.readBytes(receiveBuffer, sizeof(receiveBuffer) - 1);

      // Check if received data has correct content.
      if (strcmp(receiveBuffer, transmitData) == 0) {
        // Toggle the LED state.
        if (ledPinState == HIGH) {
          ledPinState = LOW;
        } else {
          ledPinState = HIGH;
        }
        digitalWrite(LED_BUILTIN, ledPinState);
      }
    }
  }
}

Thank you very much ptillisch. I appreciate the detailed instructions.

Zach

Hi, @analog-ev

A schematic and some images of your project would help also.

Tom.... :smiley: :+1: :coffee: :australia:

AN alternative is to add an LCD display to the project and use it to display your messages. Then you can use the one built-in serial interface for other purposes.

The first time I tried the transmit test, I got no response and I lost the USB connection despite removing the jumper as directed. However, I was able to reestablish the USB connection and now the transmit test works. For the receive test, the Tx LED blinks. Seems like pins 10 and 11 are working for the serial connection. Maybe there's an issue with my sketch.

I will show it below. Also, here is how I have the DY player wired (except I'm using the 3.5mm output). I have two players. One has the resisters soldered inline and for the other one I am using a bread board. Both players are able to play a track when shorting Tx and ground.

#include <DYSVAudio5W.h>
#include <SoftwareSerial.h>
#define RX_PIN 10
#define TX_PIN 11
SoftwareSerial mySerial(RX_PIN, TX_PIN);
DYSVAudio5W player(Serial, 9600, Serial);  //Init

void setup()
// put your setup code here, to run once:
{
  mySerial.begin(9600);  //Serial comm to computer
  player.begin();
  player.setVolume(30);  // 50% Volume
}
void loop() {
  // Read the value from the potentiometer connected to analog pin A0
  int sensorValue = analogRead(A0);
  int percentage = map(sensorValue, 0, 1023, 0, 100);  // Maps 0-1023 to 0-100

  if (percentage < 20) {
    player.playTrack(1);  //Start playing track 1
  } else if (percentage >= 20 && percentage < 40) {
    player.playTrack(2);  //Start playing track 2
  } else if (percentage >= 40 && percentage < 60) {
    player.playTrack(3);  //Start playing track 3
  } else if (percentage >= 60 && percentage < 80) {
    player.playTrack(4);  //Start playing track 4
  } else if (percentage >= 80 && percentage < 100) {
    player.playTrack(5);  //Start playing track 5
  } else if (percentage == 100) {
    player.playTrack(6);  //Start playing track 6
  }
  delay(100);  // delay in between reads for stability
}

I probably need to post this as a new question, but I think I found a problem in the sketch where it says serial instead of mySerial. I fixed that but the DY player still doesn't play. Copy and pasting other people's code is not my favorite way of doing things. Here is the updated code:

#include <DYSVAudio5W.h>
#include <SoftwareSerial.h>
#define RX_PIN 10
#define TX_PIN 11
SoftwareSerial mySerial(RX_PIN, TX_PIN);
DYSVAudio5W player(mySerial, 9600, mySerial);  //Init

void setup()
// put your setup code here, to run once:
{
  mySerial.begin(9600);  //Serial comm to DY Player
  player.begin();
  player.setVolume(30);  // 100% Volume
}
void loop() {
  // Read the value from the potentiometer connected to analog pin A0
  int sensorValue = analogRead(A0);
  int percentage = map(sensorValue, 0, 1023, 0, 100);  // Maps 0-1023 to 0-100

  if (percentage < 20) {
    player.playTrack(1);  //Start playing track 1
  } else if (percentage >= 20 && percentage < 40) {
    player.playTrack(2);  //Start playing track 2
  } else if (percentage >= 40 && percentage < 60) {
    player.playTrack(3);  //Start playing track 3
  } else if (percentage >= 60 && percentage < 80) {
    player.playTrack(4);  //Start playing track 4
  } else if (percentage >= 80 && percentage < 100) {
    player.playTrack(5);  //Start playing track 5
  } else if (percentage == 100) {
    player.playTrack(6);  //Start playing track 6
  }
  delay(100);  // delay in between reads for stability
}

Does the InitializeStart example sketch that comes with the library work with your hardware ?

There is a difference between your call to the DYSVAudio5W constructor function and the example

Yours

DYSVAudio5W player(mySerial, 9600, mySerial);  //Init

The example

DYSVAudio5W player(Serial1, 9600, Serial); //Init

If I do that, it tells me, Compilation error: 'Serial1' was not declared in this scope.

This is a little above my pay grade...

Serial1 is the name given to the SoftwareSerial instance used in the example. You gave yours the name mySerial. Try using the syntax from the example but using your name for teh SoftwareSerial instance.

Note that the name appears twice in the example constructor parameters

I should point out that I have no experience of using the library and I am going on what I can see is different in your code

Thank you Bob. I appreciate the insight. I'm leaving for a business trip in the morning, so I will have to circle back to this in a week or so.

I started tinkering with this again. Updated the code, which hasn't helped. But, I did discover that when I lift the green wire at pin 11 on the Arduino, the DY player starts playing track 1. I thought this would prove something but then I realized it's just shorting Rx on the player to ground which plays the first track by design. I'm wondering if my actual wiring is not in line with the diagram I'm trying to follow, or if it's something else. Also, I added a capacitor which is above my pay grade, but nothing exploded - yet. Below is a drawing of how I have it wired (with the potentiometer) and how it is supposed to be wired. Any help is appreciated.


`#include <SoftwareSerial.h>
#include <DYSVAudio5W.h>
#define RX_PIN 10
#define TX_PIN 11
SoftwareSerial mySerial = SoftwareSerial(10, 11);
DYSVAudio5W player(mySerial, 9600, Serial); //Initialize player

void setup()
// put your setup code here, to run once:
{
mySerial.begin(9600); //Serial comm to DY Player
player.begin();
player.setVolume(30); // 100% Volume
}
void loop() {
// Read the value from the potentiometer connected to analog pin A0
int sensorValue = analogRead(A0);
int percentage = map(sensorValue, 0, 1023, 0, 100); // Maps 0-1023 to 0-100

if (percentage < 20) {
player.playTrack(1); //Start playing track 1
} else if (percentage >= 20 && percentage < 40) {
player.playTrack(2); //Start playing track 2
} else if (percentage >= 40 && percentage < 60) {
player.playTrack(3); //Start playing track 3
} else if (percentage >= 60 && percentage < 80) {
player.playTrack(4); //Start playing track 4
} else if (percentage >= 80 && percentage < 100) {
player.playTrack(5); //Start playing track 5
} else if (percentage == 100) {
player.playTrack(6); //Start playing track 6
}
delay(500); // delay in between reads for stability
}`

Hi, @analog-ev
Can you post some images of your project?
So we can see your component layout.
Thanks... Tom.... :smiley: :+1: :coffee: :australia:

Hello analog-ev

You have made a mistake in the wiring of the potential divider.
The 5V output from the Arduino should go to the other end of the 1kΩ resistor. The junction of the 1kΩ and 2kΩ resistors goes to the DY player RX input.

Here is a corrected version of your drawing. The changes are within the yellow circle.

Hi, @analog-ev

Can you post some images of your project?
So we can see your component layout.

Thanks.. Tom.... :smiley: :+1: :coffee: :australia: