Setting HC06 name and password from within a sketch not working...

Hi,

I would like to be able to change both BT name and password from within my sketch.
From the following Sketch AT+NAME:xxx works great but AT+PSWD:yyyy does not.

String btName = "myBT";
String btPass = "2222";

void setup() { 
 //Initialize serial and wait for port to open:
  Serial2.begin(38400); 

  Serial2.print("AT+NAME:");
  Serial2.println(btName);
  delay(1000);

  Serial2.print("AT+PSWD:");
  Serial2.println(btPass);
  delay(1000);

} 


void loop() { 

}

I am using an ESP32 but the same happens with my UNO.
Any assistance welcome.
Thanks
Paulo

(deleted)

Hi, thanks for the feedback.
I have already tried:

Serial2.print("AT+PSWD=");

and 

Serial2.print("AT+PSWD");

But as before, name is updated successfully but not password.

Thanks again
Paulo

Try "AT+PIN:xxxx" in the various iterations with and without the : and =

Hi, thanks for that.

The model I have uses the following syntax:

AT COMMANDS to HC-06
VERSION:3.0-20170609
Change name:                      AT+NAME:DesiredName
Change speed to 115200:      AT+UART=115200,0,0
Change pin:                         AT+PSWD:"0000"

And this very syntax works perfectly via terminal.
At the terminal if I do not enclose the new password in quotes it does not work.
But if I do it changes the password every time I try.

So I have also tried:

String btPass = "'2222'";

also tried:

char* btPass = '2222';

then:
Serial2.print("AT+PSWD:");
Serial2.print(btPass);

I also tried:
Serial2.println(btPass);

and 

Serial2.print(btPass);
Serial2.print("\n");

None of the arrangements above worked but I believe the problem is related with the way this syntax is arranged.

Thanks again
Paulo

Hi
I don't know if you are responding to me or cattledog. I deleted my post becauese I wasn't sure it was correct. I believe the problem is due to you having the latest version.
Your lines
Serial2.print(btPass); etc.
are redundant.
Since you are hooked up, I would be very grateful if you would test the following

/* 
 This is for MEGA and HC-06. Latest versiom 3.0-2017 requires commas
e.g.      Serial1.print("AT+NAME:name");   
 
HC-06 only responds to 9600 internally.  Even if you set the baud rate to 115200, you don’t need to know that, and you can reprogramme the module again with 9600.
 
 JY-MCU board pins
 RX    - 18   Tx1     orange
 TX    - 19   Rx1     white
 GND   - GND        black 
 VCC   - 5v             red
 
 Kudos to marguskohv - he sowed the seed....
Serial monitor is just aide memoire
 */

String command = ""; // Stores response from HC-06 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);       //monitor
  Serial1.begin(9600);      //bluetooth 

  Serial.print("AT      ");  
  Serial1.print("AT");                  //PING confirmation of kosher connection!!
  if (Serial1.available()) {
    while(Serial1.available()) { // While there is more to be read, keep reading.
    delay(3);
    char c = Serial1.read();
      command += c;    
    }

  Serial.print("AT+NAME:Fosters      "); 
  Serial1.print("AT+NAME:Fosters");        //CHANGE NAME
  if (Serial1.available()) {
    while(Serial1.available()) { // While there is more to be read, keep reading.
        delay(3);
      command += (char)Serial1.read();  
    }
  }
  delay(2000);
  Serial.println(command);
  command = ""; // No repeats

  Serial.println("AT+PIN:1234");
  Serial1.print("AT+PIN:1234");        //CHANGE PASSWORD
  if (Serial1.available()) {
    while(Serial1.available()) { // While there is more to be read, keep reading.
        delay(3);
      command += (char)Serial1.read();  
    }
  }
  delay(2000);   
  Serial.println(command);
  command = ""; // No repeats

  Serial.print("AT+BAUD:8 ");  
  Serial1.print("AT+BAUD:8");               //CHANGE SPEED TO 115K
  if (Serial1.available()) {
    while(Serial1.available()) { // While there is more to be read, keep reading.
      command += (char)Serial1.read();    
    } 
  } 
delay(2000);       
Serial.println(command);
}

void loop(){
}   //one-shot - nothing here

To get quotation marks you need to use the escape "

char* btPass = "\"2222\"";
 Serial2.print(btPass);

I'm uncertain about what you need for termination characters. \n \r You may need to add them with as well.

Hi, success!

String btName = "BT09";
char* btPass = "\"2222\"";

void setup() { 
 //Initialize serial and wait for port to open:
  Serial2.begin(38400); 

  //Serial2.println("AT+UART=38400,0,0");

  Serial2.print("AT+PSWD:");
  Serial2.println(btPass);
  delay(1000);
  
  Serial2.print("AT+NAME:");
  Serial2.println(btName);
  delay(1000);
} 


void loop() { 

}

Thanks Nick, thanks cattledog

Regards
Paulo

Hi again...

Test sketch problem solved but when I get to the implementation phase I stumble on new problem:

When the variable representing the btPass is typed by the user it is in the format, say: "3333"

How do I Serial2.print("/" ...
then btPass that is for instance "3333"
then "");

Perhaps with printf...
But how to format it?

Thanks in advance
Paulo

When the variable representing the btPass is typed by the user it is in the format, say: “3333”
How do I Serial2.print("/" …
then btPass that is for instance “3333”
then “”);

How are you reading “3333” from the monitor into the sketch?

There are several ways to do this, and you did not indicate your reading algorithm. One of the best is covered by Robin2 in this Serial tutorial. http://forum.arduino.cc/index.php?topic=396450

You can enter the data in the monitor as <“3333”>.
Read the data into sketch with recvWithStartEndMarkers(); and forward the received message with Serial2.println() like you are currently doing.

Alternatively, you have the user enter AT+PSWD:“3333” read it with recvWithStartEndMarkers(); and send the full command with Serial2.println().

Hi,

You mean, instead of the user typing 3333 he should type "3333"?
It sounds an alternative.

My final purpose is to have the user change the BT password from an active BT connection.

I know it cannot be done while BT is connected so my plan is to take the newPass typed by the user over BT and store it in a variable BTpass on EEPROM to reset the BT password.

Perform a Power cycle.

Next boot the sketch checks if the variable BTpass is not blank, resets the BT password and sets BTpass on the EEPROM to blank again so next reboot nothing will happen.

Do you believe the "3333" will be stored intact for latter use in the schema above?

Thanks
Paulo

My final purpose is to have the user change the BT password from an active BT connection.
my plan is to take the newPass typed by the user over BT and store it in a variable BTpass on EEPROM to reset the BT password.

Your plan sounds reasonable.

Your first task is to have the Arduino/bluetooth module read the character string "3333" from the phone or whatever bluetooth client you are using. It would certainly be possible to enter 3333 and append the " " in the Arduino.

How do you expect the Arduino with bluetooth to read this input password?

Once you have the new password on the Arduino, storing and reading the characters to/from EEPROM is no issue.

Hi,

How do you expect the Arduino with bluetooth to read this input password?

These are the details I am trying to iron out at the moment.
Yesterday I did a simulation that did not go well.

Here is where BT text is captured:

  while (Serial2.available()) {
    delay(3);
    c = Serial2.read();
    BTString += c;
  }

At the test I did the user was suposed to type: btsenha="3333" (senha=pass).

I used my main app that is too big to post here but the basics are as follow.

The following peace of code takes what was typed by the user and writes it to EEPROM, this peace works ok.

    if (adminPass != "") {
      EEPROM.writeString(0, BTString.substring(8));
      Serial2.println(EEPROM.readString(0));     //---------------------WORKS OK prints "3333"
    } else {
      Serial2.println("Command ignored.");
      return;
    }

Before SETUP():

#include "EEPROM.h"
#define EEPROM_SIZE 64

The next peace of code is run after power cycle and the BTpass does not come as intended printing only an kind or ARROW UP character.
The following code is inside SETUP() and are still to be optimized once it works.

  if (!EEPROM.begin(EEPROM_SIZE)){
      Serial.println("failed to initialise EEPROM"); 
  } else { 
    Serial.print("EEPROM contents: ");
    Serial.println(EEPROM.readString(0));   //---------An strange arrowUP is printed
    Serial2.print("AT+PSWD:");
    Serial2.println(EEPROM.readString(0));
    EEPROM.write(0,0);
  }

Also, how to add the cotes if it is not collected elong with the newBTpass?

Thanks in advance
Paulo

These are the details I am trying to iron out at the moment.
Yesterday I did a simulation that did not go well.

I don’t think you are headed in the right direction. First, some general comments.

Avoid use of the String Object class (String with capital S). Usage of Strings in the limited memory environment of the Arduino can create memory fragmentation problems and program crashes. It is far better to use the c-style null terminated character arrays (strings with a small s) and explicitly reserved memory locations.

I do not understand your EEPROM functions. Where are you getting them from? I do not think you really need anything other than the standard .write() and .read() functions. Possibly, .put() and .get() for the character arrays may be more convenient.

You can not store a String object in the EEPROM. A String is really just a pointer to a memory location, and you need to store the actual bytes. This is another reason to be working with the c string character arrays.

For reading your input into the Arduino, the best method (non-blocking) is what was presented in the previously referenced tutorial by Robin2.

But, here is an example of some simple code which uses .readBytes() to bring the six bytepassword message “xxxx” from the monitor (send with no line ending) and saves and retrives from EEPROM.

#include <EEPROM.h>
char BTstring[7] = ""; //sized for "xxxx" six chars and null terminator.
int BTstringAddress = 50; //eeprom address 
void setup() {
  Serial.begin(115200);
}

void loop() {

  while (Serial.available() > 0)
  {
    delay(10);//allow complete message to arrive
    byte len = Serial.readBytes(BTstring, 6); //six bytes
    BTstring[len] = '\0'; //null terminate
    Serial.println(BTstring);
    EEPROM.put(BTstringAddress, BTstring);
    //null terminator is stored as part of BTstring
    char msg[7] = "";//for BTstring read from EEPROM
    EEPROM.get(BTstringAddress, msg);
    Serial.println(msg);

    //Serial2.print("AT+PSWD:");
    //Serial2.println(msg);
  }
}

Hi, I decided to drop the use o EEPROM and found a way to organize the flow using SD but it still does not work.

I have the following piece of code collecting the new BT Password:

Here the new password is collected and writen to /btsetup.txt:

 if (BTString.substring(8, 0) == "btsenha=") {    
    #ifdef codeDebug
      Serial.println("BT - BT New Pass...");
    #endif
    if (adminPass != "") {
      deleteFile(SD, "/btsetup.txt");
      dataFile = SD.open("/btsetup.txt", FILE_WRITE);
      dataFile.println(BTString.substring(8));
      dataFile.close();
      Serial2.println("Bt Pass stored, switch off and back on again.");
    } else {
      Serial2.println("Comand ignored.");
      return;
    }
  }

After that I checked the btsetup.txt and the new Pass was successfully recorded.

Then, when the system reboots it runs the following code from setup():

void setBTParms(){
  char buf[12];
  //Set BT password
  if (SD.exists("/btsetup.txt")) {
    dataFile = SD.open("/btsetup.txt", FILE_READ);
    dataFile.readStringUntil('\n').toCharArray(buf, 12);
    #ifdef codeDebug
      Serial.print("New BT PassWord: ");
      Serial.print("AT+PSWD:\"");
      Serial.print(buf);
      Serial.println("\"");
    #endif
    Serial2.print("AT+PSWD:\"");
    Serial2.print(buf);
    Serial2.println("\"");
    dataFile.close();
    deleteFile(SD, "/btsetup.txt");
  }
}

But still the BT Password is not changed!

Thanks in advance.
Paulo

In reply #7 you said that these magic words sent by the Arduino over Serial2 to the BTmodule change the password

AT+PSWD:"2222"

Baud rate was 38400 and there was a \n terminator.

What does the Serial print debug show from setBTParms()?

Certainly this looks correct and output is AT+PSWD:"3333"

void setup() {
    char buf[12] = "3333";
    Serial.begin(115200);
    Serial.print("AT+PSWD:\"");
    Serial.print(buf);
    Serial.println("\"");
}
void loop() {}

What is actually being written to the SD card with this?

dataFile = SD.open("/btsetup.txt", FILE_WRITE);
      dataFile.println(BTString.substring(8));
      dataFile.close();

With reading, Is this code getting the correct value into buf?

dataFile = SD.open("/btsetup.txt", FILE_READ);
    dataFile.readStringUntil('\n').toCharArray(buf, 12);

Hi, thanks again for the assistance.

It is working now!

The code to collect the new pass and write it to SD is as follow:

  if (BTString.substring(8, 0) == "btsenha=") {    
    #ifdef codeDebug
      Serial.println("BT - BT new pass...");
    #endif
    if (adminPass != "") {
      dataFile = SD.open("/btsetup.txt", FILE_WRITE);
      dataFile.print(BTString.substring(8));
      dataFile.close();
      Serial2.println("New BT pass recorded. Switch off and back on for it to take effect.");
    } else {
      Serial2.println("Comand ignored.");
      return;
    }
  }

The one to read and print is:

void setBTParms(){
  String btNewPass;
  //Set BT password
  if (SD.exists("/btsetup.txt")) {
    dataFile = SD.open("/btsetup.txt", FILE_READ);
    btNewPass = dataFile.readStringUntil('\n');
    btNewPass.trim();

    #ifdef codeDebug
      Serial.print("New BT PassWord: ");
      Serial.print("AT+PSWD:\"");
      Serial.print(btNewPass);
      Serial.println("\"");
      Serial.println(btNewPass.length());
    #endif
    Serial2.print("AT+PSWD:\"");
    Serial2.print(btNewPass);
    Serial2.println("\"");
    dataFile.close();
    deleteFile(SD, "/btsetup.txt");
  }
}

I had to give up char strings for a moment to concentrate on making the code work.
I will have to optimize it now and see if I can get rid of Strings.
I believe the problem was related with white spaces and cr+lf.

Thanks again.
Paulo

It is working now!

:slight_smile:

Can you explain some things to me, as I don't use Strings.

if (BTString.substring(8, 0) == "btsenha=")

I don't understand the syntax, particularly the second parameter == 0. What is BTString to make it true?

How does it go along with

dataFile.print(BTString.substring(8));

What is actually on the SD card and read out with

btNewPass = dataFile.readStringUntil('\n');

Hi, well, I am not such an advanced user but here we go:

if (BTString.substring(8, 0) == "btsenha=")

Before that line I have a menu.
I print the menu to Serial2 which is attached to the Bluetooth and thus is printed to the user's smartphone.

BTString is captured from what the user types via the Bluetooth device.
The user types the command followed by the parameter (command=parameter) and at the above line I identify the command the user is using.
I am checking the 8 first characters to verify if they match the command serviced by this part of the sketch.

dataFile.print(BTString.substring(8));

That is the second half of what the user typed, the parameter.
It is just below the "if" in the previous sentence.
It prints (writes) the new BT password to the text file (btsetup.txt) that will be used during the next boot.
So, if the first half is btsenha= (same as btPass=) the second half will be the actual senha (or Password).

btNewPass = dataFile.readStringUntil('\n');

Here I am reading the only line that exists at btsetup.txt up to '/n'

I believe the '/n' was the one causing the problem because it was been sent as part of the password to the HC-06.
When I used btNewPass.trim() it removed all blank spaces and apparently the '/n' as well and the whole thing started working.

Hope my explanation is clear
Regards
Paulo

Hope my explanation is clear

Yes, Thanks.

I don't use the String class, so I was not aware that the function prototype for BTString.substring() reverses the start and end markers when the second number is less than the first. I expected to see
BTString.substring(0,8).

I suggest that you follow through with the conversion of the sketch from Strings to strings. If you need help, I recommend start a new thread with the title of "Help me convert this sketch from using Strings" you will get plenty of help. It will be best to provide your entire program, and make a first attempt by yourself. Certainly review the previously referenced Serial tutorial.

BTString is captured from what the user types via the Bluetooth device.
The user types the command followed by the parameter (command=parameter) and at the above line I identify the command the user is using.
I am checking the 8 first characters to verify if they match the command serviced by this part of the sketch.

If you had a null terminated character array read from the phone, then the equivalent test for a match of the first 8 characters would be

if(strncmp(BTstring, "btsenha=", 8) ==0)