Noise coming on a Bluetooth serial connection

Hi guys,

I’m struggling to get rid of some noisy characters coming on my Bluetooth serial connection on the receiving end.

On the sender side I’m reading the values of two potentiometers and sending the binary values down a Bluetooth connection at 115200 baud. For the serial code, i’m re-using the code in example 6 of this very helpful thread:

My code on the sender side:

/*

*/

#include <SoftwareSerial.h>                         // Software Serial Port

#define RxD         2
#define TxD         3

#define DEBUG_ENABLED  1

const char KNOB_PIN = 0; // set the input for the amplitude to analog pin 0
const char LDR_PIN = 1; // set the input for the delay to analog pin 1

SoftwareSerial blueToothSerial(RxD, TxD);

void setup()
{
  Serial.begin(115200);
  pinMode(RxD, INPUT);
  pinMode(TxD, OUTPUT);
  pinMode(9, INPUT);

  setupBlueToothConnection();
  //wait 1s and flush the serial buffer
  delay(1000);
  Serial.flush();
  blueToothSerial.flush();
}

void loop()
{

  byte startMarker = 254;
  byte endMarker = 255;

  byte amplitude = readPot0();
  byte mydelay = readPot1();



  blueToothSerial.write(startMarker); // send start character
  blueToothSerial.write(amplitude); // send amplitude down BT
  blueToothSerial.write(mydelay); // send mydelay down BT
  blueToothSerial.write(endMarker); // send end character

  Serial.print(amplitude);
  Serial.print("   ");
  Serial.println(mydelay);


}



/***************************************************************************
   Function Name: readPot0
   Description:  read potentiometer 0 and return amplitude
   Parameters:
   Return:
***************************************************************************/
int readPot0()
{

  // read the potentiometer 0
  byte amplitude_raw = analogRead(KNOB_PIN); // value is 0-1023
  byte amplitude = map(amplitude_raw, 0, 1023, 0, 255); //my mod

  // print the value to the Serial monitor for debugging
  //Serial.print("amplitude = ");
  //Serial.print((int)amplitude);
  //Serial.print("\t"); // prints a tab

  return amplitude;

}

/***************************************************************************
   Function Name: readPot1
   Description:  read potentiometer 1 and return delay
   Parameters:
   Return:
***************************************************************************/
int readPot1()
{

  // read the potentiometer 1
  byte delay_raw = analogRead(LDR_PIN); // my mod
  byte mydelay = map(delay_raw, 0, 1023, 5, 80); //my mod
  if (mydelay > 75) {
    mydelay = 1000; // to stop the beat when motor is stopped or very slow
  }

  // print the value to the Serial monitor for debugging
  //Serial.print("delay = ");
  //Serial.print(mydelay);
  //Serial.print("\t"); // prints a tab
  //Serial.println(); // next line

  return mydelay;

}


/***************************************************************************
   Function Name: setupBlueToothConnection
   Description:  initilizing bluetooth connction
   Parameters:
   Return:
***************************************************************************/
void setupBlueToothConnection()
{

  blueToothSerial.begin(115200);

  blueToothSerial.print("AT");
  delay(400);

  blueToothSerial.print("AT+ROLEM");             // Set to master
  delay(400);

  blueToothSerial.print("AT+LNK000BBB0B49D0");    // connect to slave
  delay(400);

  blueToothSerial.flush();

}

And this is the code on the receiving end:

/*

 */



#include <SoftwareSerial.h>   //Software Serial Port

#define RxD         2
#define TxD         3

#define PINOUT      9

#define DEBUG_ENABLED  1

    byte amplitude;
    byte mydelay;

SoftwareSerial blueToothSerial(RxD,TxD);

const byte numBytes = 32; 
byte receivedBytes[numBytes]; 
byte numReceived = 0; 
boolean newData = false; 

void setup()
{
    Serial.begin(115200);
    pinMode(RxD, INPUT);
    pinMode(TxD, OUTPUT);
    pinMode(PINOUT, OUTPUT);
    
    setupBlueToothConnection();
    

}

void loop()
{

       
  recvBytesWithStartEndMarkers();  
  showNewData();  


}




/***************************************************************************
 * Function Name: setupBlueToothConnection
 * Description:  initilizing bluetooth connction
 * Parameters: 
 * Return: 
***************************************************************************/
void setupBlueToothConnection()
{  

  blueToothSerial.begin(115200);  
  
  blueToothSerial.print("AT");
  delay(400); 


    blueToothSerial.flush();

}
/*************************************************************************** 
   Function Name: recvBytesWithStartEndMarkers 
   Description:  recvBytesWithStartEndMarkers 
   Parameters: 
   Return: 
***************************************************************************/ 
void recvBytesWithStartEndMarkers() {  
static boolean recvInProgress = false;  
static byte ndx = 0;  
byte startMarker = 254;  
byte endMarker = 255;  
byte rb;  
  
//Serial.print("debug");
//delay(100);
while (blueToothSerial.available() > 0 && newData == false) {   
rb = blueToothSerial.read();  
  
if (recvInProgress == true) {  
if (rb != endMarker) {  
receivedBytes[ndx] = rb;  
ndx++;  
if (ndx >= numBytes) {  
ndx = numBytes - 1;  
} 
} 
else {  
receivedBytes[ndx] = '\0'; // terminate the string  
recvInProgress = false;  
numReceived = ndx; // save the number for use when printing  
ndx = 0;  
newData = true;  
} 
} 
  
else if (rb == startMarker) {  
recvInProgress = true;  
} 
} 
} 
/*************************************************************************** 
   Function Name: showNewData 
   Description:  showNewData 
   Parameters: 
   Return: 
***************************************************************************/ 
void showNewData() {  
if (newData == true) {  
Serial.print("This just in (HEX values)... ");  
for (byte n = 0; n < numReceived; n++) {  
Serial.print(receivedBytes[n], HEX);  
Serial.print(' ');  
} 
Serial.println();  
newData = false;  
} 
}

Also running at 115200 for the BT connection and serial to print on monitor.

I see the correct values coming in most of the time, but sometimes the value FE comes in between. If i insert a delay >100 on the sender side, the noise is mostly gone, but if i have no delay then the values look like on the attached image. Basically i should only see 0 and 5, nothing else.

I'm amazed that anything works when you try SoftwareSerial at 115200 baud. Change it to 9600 baud and if that works try increasing it little by little. I thing 38400 is about the max that is reliable.

If you need high baud rates use a Mega which has 3 spare HardwareSerial ports.

...R

Robin2:
I’m amazed that anything works when you try SoftwareSerial at 115200 baud. Change it to 9600 baud and if that works try increasing it little by little. I thing 38400 is about the max that is reliable.

If you need high baud rates use a Mega which has 3 spare HardwareSerial ports.

…R

thanks for the quick feed-back,

i changed the serial speed to print the characters on screen to 9600 on both sender and receiver, a bit of improvement but still quite noisy.

i guess you meant to change also the Bluetooth speed, right ?

Now i changed the BT speed also to 9600 just to test, on both side, but the noise is about the same surprisingly.

Only when i add a delay(>20) i get rid of the noise.

ANd now back at 115200 on both side for BT and screen, noise disappears if i insert a delay(>30)

Strange.

You seem to be trying to send data as fast as you can generate it. That won’t work - an Arduino is much faster than even a fast serial connection. For testing try adding delay(1000); into loop() in your transmitting program so it only sends data once per second.

You should not need any delay()s on the receiving side - you want that to be as responsive as possible.

If this does not help post the latest versions of your programs.

…R

Hi Rob,

yes the delay i'm adding is on the sending side and when everything is set at 115200 then the noise disappears when the delay becomes greater than 30ms, which should not impact too much the response time.

thanks a lot for your guidance, and the serial code for binary transmissions, you saved me a lot of time.

Hugues

hlalibe:
when the delay becomes greater than 30ms, which should not impact too much the response time.

You have not posted the program with the delay in it so I don't really know what you are doing.

A 30msec interval between messages is very short. You need to calculate what size of message can be be delivered comfortably within that time. Remember that Serial.print() does not wait until the message has been sent.

...R

sorry, here’s the code on sender side, the only modification is the delay line at the end of the loop(). I’ll increase it when i have my complete prototype working, then i can judge if the response time is good enough. Thanks again.

/*

*/

#include <SoftwareSerial.h>                         // Software Serial Port

#define RxD         2
#define TxD         3

#define DEBUG_ENABLED  1

const char KNOB_PIN = 0; // set the input for the amplitude to analog pin 0
const char LDR_PIN = 1; // set the input for the delay to analog pin 1

SoftwareSerial blueToothSerial(RxD, TxD);

void setup()
{
  Serial.begin(115200);
  pinMode(RxD, INPUT);
  pinMode(TxD, OUTPUT);
  pinMode(9, INPUT);

  setupBlueToothConnection();
  //wait 1s and flush the serial buffer
  delay(1000);
  Serial.flush();
  blueToothSerial.flush();
}

void loop()
{

  byte startMarker = 254;
  byte endMarker = 255;

  byte amplitude = readPot0();
  byte mydelay = readPot1();


  blueToothSerial.write(startMarker); // send start character
  blueToothSerial.write(amplitude); // send amplitude down BT
  blueToothSerial.write(mydelay); // send mydelay down BT
  blueToothSerial.write(endMarker); // send end character

  Serial.print(amplitude);
  Serial.print("   ");
  Serial.println(mydelay);

   delay(40);

}



/***************************************************************************
   Function Name: readPot0
   Description:  read potentiometer 0 and return amplitude
   Parameters:
   Return:
***************************************************************************/
int readPot0()
{

  // read the potentiometer 0
  byte amplitude_raw = analogRead(KNOB_PIN); // value is 0-1023
  byte amplitude = map(amplitude_raw, 0, 1023, 0, 255); //my mod

  // print the value to the Serial monitor for debugging
  //Serial.print("amplitude = ");
  //Serial.print((int)amplitude);
  //Serial.print("\t"); // prints a tab

  return amplitude;

}

/***************************************************************************
   Function Name: readPot1
   Description:  read potentiometer 1 and return delay
   Parameters:
   Return:
***************************************************************************/
int readPot1()
{

  // read the potentiometer 1
  byte delay_raw = analogRead(LDR_PIN); // my mod
  byte mydelay = map(delay_raw, 0, 1023, 5, 80); //my mod
  if (mydelay > 75) {
    mydelay = 1000; // to stop the beat when motor is stopped or very slow
  }

  // print the value to the Serial monitor for debugging
  //Serial.print("delay = ");
  //Serial.print(mydelay);
  //Serial.print("\t"); // prints a tab
  //Serial.println(); // next line

  return mydelay;

}


/***************************************************************************
   Function Name: setupBlueToothConnection
   Description:  initilizing bluetooth connction
   Parameters:
   Return:
***************************************************************************/
void setupBlueToothConnection()
{

  blueToothSerial.begin(115200);

  blueToothSerial.print("AT");
  delay(400);

  blueToothSerial.print("AT+ROLEM");             // Set to master
  delay(400);

  blueToothSerial.print("AT+xxxxxxxxxxxxxxxx");    // connect to slave
  delay(400);

  blueToothSerial.flush();

}

hlalibe:
I'll increase it when i have my complete prototype working,

I may be misunderstanding something but this seems like putting the cart before the horse.

Sort out problems while the program is small - then extend it to include extra features.

Have you tried (say) delay(500); ?

...R

Yes, 500 works nicely too. The code on the sending end won't get much more complicated than this actually.

On the receiving end, once in a while I still have some noise coming down. But your code counts the number of incoming bytes, and as I send only two bytes at a time, I was thinking of adding a check on number of bytes received, and discard that run if number of bytes is greater than two. That would get rid of the occasional noise and keep my response time fast.