Sending commands to sparkfuns rn52 bluetooth module

Hi, I'm not a guru, but I have learned quite a bit about this subject in the last couple of weeks. My particular project involves sending analog audio from a 2 meter ham radio via bluetooth to a bluetooth headset. I want to be able to enable push to talk from the bluetooth headset. I bought two rn52's a couple of years ago and they have sat on my desk until this past thanksgiving. I also intend to use an Arduino Nano for the time being on the source/master unit.(i'll explain in a moment). I am learning about all the bluetooth protocalls, and I have learned that the rn52 comes configured as a A2DP sink, able to pair with your phone rite out of the box, hook up some speakers and play music.

However I wanted to configure one as a master and the other a slave. The rn52 documentation does mention a command to change it to a master, but through searching I found out you have to upload a different firmware from sparkfun rn52scr. That accomplished, I am able to stream audio from master to slave with the A2DP, and AVARP.

Ok that accomplished, I needed to figure out how to use my Arduino to give my rn52 commands via a sketch, and see what it does in real time.
I knew almost nothing about serial communications so this also has been a learning experience. After hours of futile searching and failure to communicate, I read about needing level converters between 5v arduino and 3.3v rn52, so I ordered some. That didn't work (yet lol).I finally read somewhere that I cant talk to my rn52 through the same rx/tx 0-1 pins that the usb is using to upload sketches. I would need to us SoftwareSerial to designate two other digital pins For the Arduino to to talk to the rn52 through. So I have reconfigured my tx/rx pins pins 3,4, gnd, 5v from the Arduino to the High side of the level converter, and low side to the rn52. Dont forget to hook the rx to the tx. I then took my 3.3v FTDI breakout and hooked the rx to the tx on the rn52 so I can monitor output on the rn52. So I have the Arduino hooked to com port 5, to upload sketches, and the FTDI is on com port 4 so I can watch com port 4 on the serial monitor.

After that, the big challenge was to learn enough code syntax to mySerial.write('D') in a sketch, load it into the arduino and see what happens. Bingo it worked. There is a softwareSerial sample sketch, but it is mostly concerned with talking back to your computer, but its a start, at least as far as starting serial communications.

My next challenge: while the rn52 is configured for A2DP audio streaming, it doesn't transmit data, but AVARP is enabled. I think I can use my Arduino to monitor the output from the rn52 serial port, and perhaps hijack one of the AVARP command function not being used play/pause for example, and when the arduino sees it, close the push to talk circuit via a transistor. That way only one microcontroller is required on the master side. So in the void loop, i will monitor the rn52 serial port, when the output ='s a string, then transister pin high, delay 100 ms, check serial output not = to string transistor low, or something like that.

On the headset I can wire the push to talk button to the play/pause button to the corresponding GPIO pin on the rn52.

At any rate that is the goal, and I have read and learned enough to share what I have learned, and maybe help someone else along.
Any advice is welcome, and so are question.

SS_send_commands_to_rn52.ino (3.8 KB)

@seaurchin1969

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Ok, I made some progress today. I was able to use part of a serial event sketch from the example library, and modify it for my purposes. It took some fiddling, because it was designed for Serial communications from the computer. Anyway this code will among other things capture the Serial output of the bletooth radio, and Serial.print it to the same Serial monitor the Arduino is on. I was able to eliminate using the FTDI basic to monitor the serial output of the radio, and establish that my Arduino is in fact able to capture that Serial output, and Serial.print it back to the computer serial monitor.

//include Software Serial Library

#include<SoftwareSerial.h>

//assign pins 3 a,d 4 tx and rx
SoftwareSerial mySerial(3,4);

//Declare Strings

String slave1;
String slave2;
String inChar;
String inputString = "";
boolean stringComplete = false;

void setup() {

  //enable Serial Communications at 115200 baud

  mySerial.begin(115200);
  Serial.begin(115200);
  //reserve 200 bytes for the input string
  inputString.reserve(200);
 
  
  //Assign slave1 and slave2 their values
 
  slave1 = "c,00066653745A\r";
  slave2 = "c,38F32EA742CF\r";

  mySerial.write("\r");
  delay(10);
  mySerial.write("\r");
  delay(10);
  

  //Have the rn52 reportits version

  mySerial.write("v");
  mySerial.write("\r");
  delay(100);

  //Have rn52 connect with slave1,and slave2 devices

  mySerial.write("slave1");
  delay(10);
  mySerial.write("slave2");

  // put your setup code here, to run once:

}

void loop() {
  //Print string when a new line arrives
  if (stringComplete){
    Serial.println(inputString);
    //clear the string:
    inputString = "";
    stringComplete = false;
  
  }

/*SerialEvent occurs whenever a new datacomes in the 
  ardware serial rx. This routine is run between each
  time loop() runs, so using delay inside loop can delay
  response. Multiple bytes of data may be available.
 */
 while (mySerial.available()) {
    //get the new byte
    char inChar = (char)mySerial.read();
    
    delay(10);
    inputString += inChar; 
    if (inChar == '\n') {
      stringComplete = true;
    }
  } 
}

It also tells me that I have data in a String that I compare to a known Value. This way I can monitor for a Specific value,
Like a AVARCP command from the slave radio, and have the Arduino act on it.

Ok I have been able to get the program to do what I want for now. I have been able to write a program so that my Arduino will monitor the Serial output from the RN52 line by line. It will then take each line and Serial print it, and take the first 7 chars of the line and put it into a string named "compare". Then an If statement sees if "compare", and "compareString" are equal, and if true turn on the led for one second. Im not sure I'll be able to use an AVARCP button to do what I want, as it doesn't seem to repeat the command when the button is held down. I may have to monitor the state register, and use GPIO6 On the rn52 as an output. This may just not be possible in A2DP, possibly HSF. I intend to play with A2DP more before giving it up.

If I use the GPIO6 on the slave rn52, as an output, I dont know what if anything it will send to the master, it may just be a 1 or 0 to indicate high or low that would be enough though. So ill have to get back on it when I get home.

Anyway I've posted the program code here.

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

//assign pins 3 a,d 4 tx and rx
SoftwareSerial mySerial(3,4);

//Declare Strings
String compString = ("AVRCP:V");
String inputString = "";
boolean stringComplete = false;
int led = 13;
String compare = "";

void setup() {
  
    //pin mode will be set to output on pin 13
  pinMode(led, OUTPUT);

  //enable Serial Communications at 115200 baud

  mySerial.begin(115200);
  Serial.begin(115200);
  //reserve 200 bytes for the input string
  inputString.reserve(200);
  compare.reserve(200);
  
  //reset the rn52
  mySerial.write("r,1\r");
  //this while loop, which you will see following each command issued, in the setup,
  //to the rn52 is to Serial Print the rn52's response following each command.
  //both the Serial print statements, and the while loops can be removed. once the program
  //is working properly.
     while (mySerial.available()){
      delay(1);
      char inChar = (char)mySerial.read();
      Serial.print(inChar);
      delay(10);}
      
  //give rn52 time to reset
  delay(5000);
  
  //command rn52 to connect with known bluetooth devices
  //make sure rn52 is awake and responding first
  mySerial.write("\r");
    while (mySerial.available()){
       delay(1);
      char inChar = (char)mySerial.read();
      Serial.print(inChar);
      delay(10);} 
  mySerial.write("\r");
  while (mySerial.available()){
       delay(1);
      char inChar = (char)mySerial.read();
      Serial.print(inChar);
      delay(10);}
  //this is a trace that serial prints the connect comand.    
  Serial.println("connect to 00066653745A RN52 slave");
  //commands rn52 to connect with the Slave rn52. it should respond AOK
  mySerial.write("c,00066653745A\r");
  delay(1000);
   while (mySerial.available()){
       delay(1);
      char inChar = (char)mySerial.read();
      Serial.print(inChar);
      delay(10);} 
  //this is a trace that serial prints the connect comand.        
  Serial.println("connect to 38F32EA742CF HESH headset");
  //commands rn52 to connect with the HESH headset. it should respond AOK    
  mySerial.write("c,38F32EA742CF\r");
  delay(1000);
    while (mySerial.available()){
       delay(1);
      char inChar = (char)mySerial.read();
      Serial.print(inChar);
      delay(10);}
}
void loop() {
  //MySerial write the commands I issue from the Serial monitor to the rn52 
  //while the loop is running
      while (Serial.available()){
        delay(1);
        char inChar = (char)Serial.read();
        mySerial.print(inChar);
        delay(10); 
      }
      //prints the inputString, and parces out the first 7 characters to compare to compString
      //when compString and compare are == then turn on the led for 1 second     
      if (stringComplete){
        //take the first 7 chars of inputString and assign to compare String, 
        compare = inputString.substring(0,7);
        if (compare == compString){
          Serial.println("led on");
          digitalWrite(led,HIGH);
          delay(1000);} 
          digitalWrite(led,LOW);
           //clear the string:
           inputString = "";
           compare = "";
           stringComplete = false;
      }
/*durring mySerial event, builds a string from incomming data until it gets a line return 
 *once it sees the line return, it changes boolean value of stringComplete to true. which 
 *triggers the above if statement. printing the string, and looks for a specific string
 */
  while (mySerial.available()) {
    //get the new byte
    char inChar = (char)mySerial.read();
    Serial.print(inChar);
    delay(2);
    inputString += inChar; 
    if (inChar == '\n') 
      stringComplete = true;       
   } 
}