2

I am trying to setup bluetooth with a board that contains Arduino Leonardo chip.

My full setup is:

The main board: https://www.dfrobot.com/product-1148.html

The base shield: https://coolcomponents.co.uk/products/grove-base-shield-for-arduino-v2

The bluetooth module: https://wiki.seeedstudio.com/Grove-Serial_Bluetooth_v3.0/

The bluetooth module is connected to D8 port of the base shield. The reason is "not all pins on the Leonardo and Micro support change interrupts, so only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)." as explained here: https://www.arduino.cc/en/Reference/SoftwareSerial

Here is the full code.

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

/*Connect your Bluetooth Module to D8 otherwise it will not work due to Arduino Leonardo */

#define RxD         8
#define TxD         9
 
SoftwareSerial blue(RxD,TxD);

void setup()
{
    Serial.begin(9600);
    blue.begin(9600); //anything other than 9600 will not work
   
    // wait for serial port to connect. Needed for native USB
    while(!Serial){
    ;
    }
   
    pinMode(RxD, INPUT);
    pinMode(TxD, OUTPUT);
   
    Serial.print("Started\n");
    setupBlueToothConnection();
   
}

void loop() {
char recvChar;
    while(1)
    {
        if(blue.available())
        {//check if there's any data sent from the remote bluetooth shield
            recvChar = blue.read();
            Serial.print(recvChar);
           
        }
        if(Serial.available())
        {//check if there's any data sent from t he local serial terminal, you can add the other applications here
            recvChar  = Serial.read();
            blue.print(recvChar);
            delay(400);
        }
    }
}

void setupBlueToothConnection()
{
  //blue.begin(9600);
 
  blue.print("AT");
  delay(400);
 
  blue.print("AT+ROLES");  // set the role as slave
  delay(400);
 
  blue.print("AT+NAMESlave");   // set the bluetooth name as "Slave" ,the length of bluetooth name must less than 12 characters.
  delay(400);
 
  blue.print("AT+AUTH1");
  delay(400);
  blue.flush();
}

The output from the Serial Monitor (set as BOTH NL & CR, 9600) as follows:

Started
OKOK+Set:SOK+Set:SlaveOK+Set:1

The problem is when I send AT commands from terminal I get nothing in return. However if I send AT command from the IDE, I am getting feedback from the bluetooth.

5
  • get rid of the almost 1/2 second delay in loop() .... also get rid of the while(1) ... loop() is already a while(1)
    – jsotola
    Dec 9, 2020 at 22:43
  • why do you use SoftwareSerial and not Serial1? use Serial.write(recvChar);. maybe you don't send a line end character to terminate the command
    – Juraj
    Dec 10, 2020 at 6:36
  • @jsotola - I will need two while loops that is why I left it like that. Reducing it 1 loop and removing delay did not fix the issue. I will be also adding a Zigbee module that is why I used software serial. I have also tried with "Serial1" but nothing changed. Just to clarify - sending AT command via code works such as "Serial1.print("AT"), however if I send it from Serial Monitor nothing returns.
    – Mr. Panda
    Dec 11, 2020 at 11:35
  • I was going to ask you what exactly you're sending from the terminal, specifically what line termination. But now I see you have no termination on your AT commands in setupBlueToothConnection. Is this really the code you're testing with?
    – timemage
    Dec 11, 2020 at 13:47
  • Yes @timemage it is the exact same code that I am testing.
    – Mr. Panda
    Dec 11, 2020 at 15:12

1 Answer 1

2

The issue is fixed.

Note: This is the version includes Serial1 rather than SoftwareSerial. The rest is the same.

Serial.read()

Returns the first byte of incoming serial data available.

So, when I send AT command from terminal, it does send "A" and then "T" rather than "AT" as a string which Bluetooth expects as stated in the product's documentation:

AT Command format: Uppercase AT command format. string format, without any other symbol. (e.g. \r or \n).

Hence, I have added the following function:

String SerialString() {   // Function to generate string from chars sent via Serial Monitor
  
  String inputString = "";  // to hold the string
  
  while (Serial.available()) {
    
    char inputChar = (char)Serial.read(); // get the new byte:
    inputString += inputChar;             // add it to the inputString:
    }
    
    return inputString;     // returns completed string 
}

Then inside void loop():

String WholeCommand = ""; 
if(Serial.available() > 0){
    WholeCommand = SerialString();
    Serial1.print(WholeCommand);
  }

Now, when I send AT from Serial Monitor, I can get OK from Bluetooth.

5
  • 1
    This is bizarre to me. Normally when devices accept AT-commands they will give you all the time in the world to complete the command and completing it means sending '\r'. I wonder if there isn't a setting that will make this thing behave in a normal way.
    – timemage
    Dec 11, 2020 at 15:17
  • I definitely agree your point, this is why I struggled. However in their documentation: link this is how they state it.
    – Mr. Panda
    Dec 11, 2020 at 15:51
  • 1
    I found the reference "Uppercase AT command format. string format, without any other symbol. (e.g. \r or \n)." For future readers you might put that quote and the datasheet link into your answer. If it were me, I'd toss this thing and get a different module though.
    – timemage
    Dec 11, 2020 at 16:01
  • Included them as you suggested. Unfortunately these are bought in bulk, so I need to figure out the best way to utilise them.
    – Mr. Panda
    Dec 11, 2020 at 16:11
  • Yeah I understand. It's good that your question/answer exists and can be found and understood regardless.
    – timemage
    Dec 11, 2020 at 16:19

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.