步骤1:硬件:
hc-05 smd模块(我从aliexpress获得)
arduino nano(同样来自aliexpress)
3x7cm双面原型板(同样来自aliexpress)
两个led
单芯线的耦合
2.54厘米标头
步骤2:hc-05模块:
实际上,我使用的参考手册是关于具有不同产品编号的模块的,但是实际上,它是与hc-05相同的模块(我发现它写得很好并且带有漂亮的图形)。该模块的名称为 egbt-045ms ,您可以在此处找到该手册。
特别是,我们对以下8个引脚感兴趣:
引脚1,2 :tx,rx:将发送/接收引脚连接到arduino上的串行(或软件串行)引脚。
引脚12,13 :vcc,gnd:为模块加电。
引脚31,32 :指示led,特别是“状态” led和“以数据模式连接” led
pin 11 》:重置引脚,用于重置模块以切换操作模式(at/data)
引脚34 :命令模式引脚,用于
步骤3:连接:
要连接5v主机,您需要在hc-05 rx引脚上使用分压器(电阻器对),而不必在vcc上使用因为它是5v容忍的(这就是手册至少说了。)
现在,说实话,我为3.3v arduino pro mini进行了连接,但是后来我使用了5v arduino nano,并且我没有遵循指南向其添加电阻器rx线。但是,猜猜是什么,它可以正常工作,所以我将其保持不变;)
注意:我并不是说它将与您一起使用还是这种方式是正确的,我认为它只是偶然地与我合作。请按照接线图进行正确连接。
现在,将hc-05正确放置在原型板上(注意,hc-05是间距为1.5毫米,而面包板的间距为2.45毫米。因此,孔没有对齐,但只有很少的相邻电缆,您可以设法将其穿过)
接下来,放置arduino nano和hc-05引脚,两个用于led的电阻器,led本身(从另一端连接到gnd),我还为i2c显示设置了连接(将在附近的另一条说明中添加和解释)
注意: 我没有将hc-05连接线连接到特定的arduino引脚,我现在通过跳线进行此操作,以使其与其他组件(如果有)保持模块化。
步骤4:at模式和hc-05重置。
在大多数参考文献中,要求您手动断开/重新连接hc-05的电源,以便将其放入at模式(引脚34置于高电平)或返回数据模式(同一引脚为低电平状态)。如果您的应用程序需要按顺序从/向at命令模式来回切换,则没有任何意义。
诀窍是允许arduino控制reset引脚(11号引脚)来重置模块。该过程如下
进入at命令模式:
digitalwrite(pinen,high); // set the enable pin (no.34) to high, and keep it during the at command
digitalwrite(pinre,low); // set the reset pin (no.11) to low, this postpones the module in preparation to reset
delay(100); // a short delay (should be more that 10 ms) to simulate a negative pulse on the reset pin
digitalwrite(pinre,high); // set the reset pin back to high, and with enable pin set to high, the module restarts in at command mode.
进入数据传输模式:
digitalwrite(pinen,low); // set the enable pin (no.34) to low, and keep it during the data transmission mode
digitalwrite(pinre,low); // set the reset pin (no.11) to low, this postpones the module in preparation to reset
delay(100); // a short delay (should be more that 10 ms) to simulate a negative pulse on the reset pin
digitalwrite(pinre,high); // set the reset pin back to high, and with enable pin set to low, the module restarts in data transmission mode.
第5步:交互使用用户输入
在我们的程序中,用户可以在三种模式之一中操作模块
at命令模式: :您可以通过在串行终端中键入‘#start’来启用它,您需要在其中键入每个命令,并从中读取确切的响应
数据传输模式: :您可以通过在序列号中键入‘#end’来启用它终端,其中与模块的所有无线通讯都将列在串行监视器中,并且无法控制模块参数。
操作菜单模式: ,您可以通过在串行终端中键入‘#op’来启用它,这会将模块放入at命令模式,但不是由用户直接提供命令,而是通过具有预定义操作的交互式菜单来发出命令。
操作菜单允许进行以下操作:
显示模块设置
名称,波特率,角色,连接模式,密码
修改当前设置
修改模块名称
修改uart设置
修改配对代码/密码
切换角色(主/从)
更改连接模式
后退。..
重置为原始设置
仅限主机操作
发现附近的设备
与设备配对
连接到设备
从配对列表中删除设备
绑定设备
返回。..
第6步:代码:
下面是arduino代码(您也可以下载文件本身)
请注意该程序中密集的字符串用法。我遇到了很多问题,因为如果这样做,我可以通过以下说明解决其中的几个问题:
使用‘string.reserve()’函数为字符串实例预先保留动态内存,这样可以更好地处理堆中的内存分配。但这还不够,因为它不能保证任何事情。
使用‘f()’宏:它允许将字符串存储在闪存而不是ram中。它仅适用于print/println操作中的静态字符串。这非常有用,但还不够用(对动态字符串无济于事)
减少保留的字符串数:如果这不是您真正想要的,不要询问最多10个设备。例如3个就足够了。
在任何情况下该程序都将执行并上载的问题,但是它将以意外的方式运行,响应的查询与您键入的查询不同,并且
解决该问题的方法是使用char数组(或char *)代替字符串。这是我的下一步,但现在我没有时间去做;)
/*
* at_at_mode.ino - a wizard for hc-05 bluetooth modules
* copyright (c) 2016 rami baddour. all right reserved.
* http://ramibaddour.com/ https://ch.linkedin.com/in/ramibaddour
*
* a program to view, set, modify and use the hc-05 bluetooth with an interactive textural menus
* over serial monitore
*
* you can include parts of the code that does specific functionality (e.g. search for devices)
* to your own program
*
* note that this code uses intensively the string class, which has some unpredictable behaviour
* when virtual memory is not possible to researve. it is tested to work perfectly when restricting
* number of recorded searched devices to 3. above this can have some problems with displyed strings.
*
* newer version will use char arrays instead, hopefully with better stability.
*
*
*/
#include
softwareserial myserial(5, 4);// rx, tx where the hc-05 is connected
#define pinre 3 // the reset pin, connected to hc-05 pin no. 11
#define pinen 6 // the enable pin, connected to hc-05 pin no. 34
#define inq1 1 // inquire acces mode: 0-standard 1-rssi(default)
#define inq2 100 // maximum number of devices responce: 0-to-32000
#define inq3 30 // inquire timeout: 1-to-48 sec
#define maxdev 1 // maximum number of devices to record.
#define pairto “25” // pairing timout in seconds
#define maxstrlen 50 // maximum buffer researved for string variables.
#define atstart “#start” // the token string to start at command input
#define atend “#end” // the token string to end at command or operational menu input
#define atop “#op” // the token string to start the operation menu.
// column widths in character count for the discovred bt devices‘ list
#define colw1 6
#define colw2 45
#define colw3 20
#define colw4 7
int8_t currin = -1; // the current input, records the user selection and used within the program state machine
int8_t currst = -1; // the current state, defines the current status in regards to the menu selections
int8_t devicecount = 0; // the reset pin, connected to hc-05 pin no. 13
int devcount = 0; // how many devices in total have been discovered in the last device inquiry
int devloc = 0; // the location of the selected device within the list of discovered devices.
string serialstr, tmpname, tmpres; //some string variables to be used later
//define a data structure for each descovered device. it inlcudes basic information like the name, address, rrsi and service class
typedef struct inqdevices{
string name;
string address;
string rssi;
string class;
inqdevices(int defsize=maxstrlen){
name.reserve(defsize);
name = “”;
address.reserve(20);
address = “”;
rssi.reserve(20);
rssi = “”;
class.reserve(40);
class = “”;
}
}inqdevice;
inqdevice lstdevices[maxdev]; // this function takes a string of any length ’strin‘ and outputs a the same string but with fixed length ’strlen‘
// which is a substring of the input if length(strin)》strlen, is the same as ’strin‘ with the remaining characters
// filled with ’strfillchar‘ character.
// if ’strfill‘ is set to true, the input string is appended to the end of the result string as well.
string strfixed (string strin, int strlen, boolean strfill = false, string strfillchar = “ ”){
string tmpstr1 = strin.substring(0,strlen);
int tmplen = tmpstr1.length();
for (int i=0; i《 (strlen - tmplen); i++)
tmpstr1 = tmpstr1 + strfillchar;
if (strfill)
tmpstr1 = tmpstr1 + strin;
return (tmpstr1);
}
// a function to clear the contents of the device list array strings.
void cleardevicelist(){
for (int i = 0; i // use the ’discardok‘ setting if you want the function to discard the ’ok‘ result on the at command return.
// use the ’charstocutfrom‘ and ’charstocutto‘ if you want to get only a substring of the at command return. e.g. if you want to discard
// the ’+inq:‘ initial part in the ’at+inq‘ command responce and get directly the address and signal information of the descovered device.
string getfrommyserial(string strtowrite = “”, bool discardok=true, int charstocutfrom = 0, int charstocutto = 150){
if (strtowrite != “”)
{
myserial.println(strtowrite);
delay(50); // these delays may be not necessary, it just to accomodate slow responding hc-05 modules.
}
string tmpstr = (myserial.readstringuntil(’ ‘));
tmpstr.trim();
delay(50);
if (discardok)
myserial.readstringuntil(’ ‘);
return tmpstr.substring(charstocutfrom, charstocutto);
}
// this function is similar to the previous ’getfrommyserial‘。 but this one is used when the answer
// is not guarenteed after a fixed delay. e.g. if you wait to get remote bt device address or name in
// discovery process. also, it is used if you are not expecting a return value at all.
string getfrommyserialsimple(string strtowrite = “”, int charstocutfrom = 0, int charstocutto = 150){
if (strtowrite != “”)
{
myserial.println(strtowrite);
delay(100);
return “”;
}
else
{
while (!myserial.available()){delay(10);}
string tmpstr = (myserial.readstringuntil(’ ‘));
return tmpstr.substring(charstocutfrom, charstocutto);
}
} void setup() {
serial.begin(57600);
myserial.begin(38400); // default hc-05 baud rate at at-mode
serial.print(f(“to enter at mode please type ’”));
serial.print(atstart);
serial.print(f(“‘, to exist type ”));
serial.print(atend);
serial.print(f(“, or type ’”));
serial.print(atop);
serial.println(f(“ for the menu”));
pinmode(pinre, output);
pinmode(pinen, output);
serialstr = “”;
serialstr.reserve(maxstrlen);
tmpname.reserve(maxstrlen);
tmpres.reserve(maxstrlen);
} void loop(){
if (serial.available()) {
serialstr = (serial.readstringuntil(‘ ’));
serialstr.trim();
// entering at mode, you set en pin to high, and generate a 100ms negative pulse on the reset pin
if (serialstr.equalsignorecase(atstart)) {
serial.println(f(atstart));
serial.println(f(“you are now in at mode, enter at commands:”));
currin = -1;
currst = -5;
digitalwrite(pinen,high); // set the enable pin (no.34) to high, and keep it during the at command operation
digitalwrite(pinre,low); // set the reset pin (no.11) to low, this postpones the module in preparation to reset
delay(100); // a short delay (should be more that 10 ms) to simulate a negative pulse on the reset pin
digitalwrite(pinre,high); // set the reset pin back to high, and with enable pin set to high, the module restarts in at command mode.
serialstr = “”;
}
// exiting at mode into data transmission mode, you set en pin to low, and generate a 100ms negative pulse on the reset pin
else if (serialstr.equalsignorecase(atend)){
currin = -1;
currst = -1;
serial.println(f(atend));
serial.println(f(“you have quit at mode.”));
digitalwrite(pinen,low); // set the enable pin (no.34) to low, and keep it during the data transmission mode
digitalwrite(pinre,low); // set the reset pin (no.11) to low, this postpones the module in preparation to reset
delay(100); // a short delay (should be more that 10 ms) to simulate a negative pulse on the reset pin
digitalwrite(pinre,high); // set the reset pin back to high, and with enable pin set to low, the module restarts in data transmission mode.
}
// to enter the operational menu mode, you do the same as initiating at mode, but with the state variablle state to 0 so you enable the menu state machine
else if (serialstr.equalsignorecase(atop)){
currin = 0;
currst = 0;
serial.println(f(atop));
digitalwrite(pinen,high);
digitalwrite(pinre,low);
delay(100);
digitalwrite(pinre,high);
}
// for any other input, this is basically a selection of an item in the menu, or a command in at mode.
else{
serial.println(serialstr);
currin = serialstr.toint(); //any non-numerical input results in ‘0’
}
// this is when we start the at mode , all inputs are sent to the bluetooth module.
if (currst == -5){
myserial.println(serialstr);
}
}
// in case of responce or input from the bluetooth module itself
if (myserial.available()){
while (myserial.available()){
tmpname = (myserial.readstringuntil(‘ ’));
tmpname.trim();
serial.println(tmpname);
delay(50);
} }
if (currin 》= 0){ // enter the state machine only if we get a valid input
switch (currst){ // the menu display selection
case 0:{ // this is the main menu
switch (currin){ // based on the user input, selects the corresponding operation and therefore the next state
case 0:
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“please select from the following operations:”));
serial.println(f(“ 1- display the module settings”));
serial.println(f(“ 2- modify current settings”));
serial.println(f(“ 3- reset to original settings”));
serial.println(f(“ 4- master-only operations”));
serial.println(f(“ 5 -”));
serial.print(f(“(option no.) ”));
currin = -1; // we set to -1 to avoid entering into the state machine indefinately.
break;
case 1:
currst = 1;
break;
case 2:
currst = 2;
currin = 0;
break;
case 3:
currst = 3;
break;
case 4:
currst = 4;
currin = 0;
break;
default:
serial.println (f(“not a valid input, please select from the list”));
currst = 0;
currin = 0;
}
break;
}
case 1:{ // display the module main settings. for each, send the command and wait for the result and display it
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“the current module settings are:”));
serial.print(f(“ -- name : ”));
serial.println(getfrommyserial(“at+name”, true, 6));
serial.print(f(“ -- baudrate : ”));
serial.println(getfrommyserial(“at+uart”, true, 6));
serial.print(f(“ -- role : ”));
if (getfrommyserial(“at+role”, true, 6) == “1”)
serial.println(f(“master”));
else
serial.println(f(“slave”));
serial.print(f(“ -- conn. mode : ”));
tmpres = getfrommyserial(“at+cmode”, true, 6);
if ( tmpres == “0”)
serial.println(f(“single remote connection”));
else if ( tmpres == “1”)
serial.println(f(“any remote connection”));
else
serial.println(f(“test mode”));
serial.print(f(“ -- passowrd : ”));
serial.println(getfrommyserial(“at+pswd”, true, 6));
currst = 0;
currin = 0;
break;
}
case 2:{ // the menu to modify the bt module settings
switch (currin){
case 0:
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“please select from the following operations:”));
serial.println(f(“ 1- modify the module name”));
serial.println(f(“ 2- modify uart settings”));
serial.println(f(“ 3- modify the pairing code/pw”));
serial.println(f(“ 4- switch the role (master/slave)”));
serial.println(f(“ 5- change connection mode”));
serial.println(f(“ 6- back.。.”));
serial.print(f(“(option no.) ”));
currin = -1;
break;
case 1:
currst = 21;
currin = 0;
break;
case 2:
currst = 22;
currin = 0;
break;
case 3:
currst = 23;
currin = 0;
break;
case 4:
currst = 24;
currin = 0;
break;
case 5:
currst = 25;
currin = 0;
break;
case 6:
currst = 0;
currin = 0;
break;
default:
serial.println (f(“not a valid input, please select from the list”));
currst = 2; // stay in the same menu if wrong input is entered
currin = 0;
break;
}
break;
}
case 21:{ // modify the module‘s name
serial.println(f(“----------------------------------------------------------”));
serial.print(f(“the curent module name is : ”));
serial.println(getfrommyserial(“at+name”, true, 6));
serial.println(f(“please enter a new name, or leave blank to keep the current setting.”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
if (tmpname == “”)
serial.println(f(“name is left unchanged”));
else{
tmpname = “at+name=” + tmpname;
tmpres = getfrommyserial(tmpname, true);
if (tmpres == “ok”)
serial.println (f(“name change successful”));
else
serial.println (f(“faild to change the name, please check the name and try again”));
}
currst = 2;
currin = 0;
break;
}
case 22:{ // modify the serial uart port settings (baudrate, stop bit and parity bits)
serial.println(f(“----------------------------------------------------------”));
serial.print(f(“the curent uart (baudrate) settings are : ”));
tmpname = getfrommyserial(“at+uart”, true, 6);
string tmpbr = tmpname.substring(0,tmpname.indexof(’,‘)); // baud rate
string tmpsb = tmpname.substring(tmpname.indexof(’,‘)+1,tmpname.indexof(’,‘)+2);// stop bit
string tmppb = tmpname.substring(tmpname.indexof(’,‘)+3,tmpname.indexof(’,‘)+4);// parity bit
serial.println(tmpname);
serial.println(f(“choose new baudrate, or leave it blank to keep unchanged. possible options:”));
serial.println(f(“(1) 4800 (2) 9600 (3) 19200 (4) 38400 (5) 57600”));
serial.println(f(“(6) 115200 (7) 234000 (8) 460800 (9) 921600 (10) 1382400”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
if (tmpname == “”)
{
serial.print(f(“baudrate is left unchanged: ”));
serial.println(tmpbr);
}
else
{
int tmpint = tmpname.toint(); //baudrate
if ((tmpint 》 0)&&(tmpint 《 11))
serial.print(f(“baudrate channged successfully, the new baudrate is: ”));
switch (tmpint) {
case 1: case 2: case 3: case 4:
tmpbr = string(2400 * pow(2,tmpint),0);
serial.println(tmpbr);
break;
case 5: case 6: case 7: case 8: case 9:
tmpbr = string(1800 * pow(2,tmpint),0);
serial.println(tmpbr);
break;
case 10:
tmpbr = “1382400”;
serial.println(tmpbr);
break;
default:
serial.println(f(“incorrect input, baudrate is left unchanged”));
}
}
serial.println(); // stop bits
serial.println(f(“choose the number of stop bits, or leave it blank to keep unchanged. possible options:”));
serial.println(f(“(a) 0:1 bit (b) 1:2 bits”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
if (tmpname == “”)
{
serial.print(f(“stop bit number is left unchanged: ”));
serial.println(tmpsb);
}
else if ((tmpname == “a”)||(tmpname == “a”))
{
tmpsb = “0”;
serial.print(f(“stop bit number is channged successfully, the new setting is: ”));
serial.println(tmpsb);
}
else if ((tmpname == “b”)||(tmpname == “b”))
{
tmpsb = “1”;
serial.print(f(“stop bit number is channged successfully, the new setting is: ”));
serial.println(tmpsb);
}
else
serial.println(f(“incorrect input, stop bit number is left unchanged”));
serial.println(); //parity bits
serial.println(f(“choose parity bits setting, or leave it blank to keep unchanged. possible options:”));
serial.println(f(“(1) no parity (2) odd parity (3) even parity”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
int tmpint = tmpname.toint();
if (tmpname == “”)
{
serial.print(f(“parity bits setting is left unchanged: ”));
serial.println(tmppb);
}
else if ((tmpint 》0)&&(tmpint 《4))
{
tmppb = tmpname;
serial.print(f(“parity bits setting is channged successfully, the new setting is: ”));
serial.println(tmppb);
}
else
serial.println(f(“incorrect input, parity bits setting is left unchanged”));
tmpname = “at+uart=” + tmpbr + “,” + tmpsb + “,” + tmppb; // the overal uart settings command
string tmpres = getfrommyserial(tmpname, true);
if (tmpres == “ok”)
serial.println (f(“uart settings change successful”));
else
serial.println (f(“faild to change the uart settings, please try again”));
currst = 2;
currin = 0;
break;
}
case 23:{ // modify the password (pairing code)
serial.println(f(“----------------------------------------------------------”));
serial.print(f(“the curent pairing code is : ”));
serial.println(getfrommyserial(“at+pswd”, true, 6));
serial.println(f(“please enter a new pairing passkey, or leave blank to keep the current code.”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
if (tmpname == “”)
serial.println(f(“pairing passkey is left unchanged”));
else
{
tmpname = “at+pswd=” + tmpname;
string tmpres = getfrommyserial(tmpname, true);
if (tmpres == “ok”)
serial.println (f(“pairing passkey change successful”));
else
serial.println (f(“faild to change the pairing passkey , please check the code and try again”));
}
currst = 2;
currin = 0;
break;
}
case 24:{ // modify the role (master/slave/slave-loop)
serial.println(f(“----------------------------------------------------------”));
serial.print(f(“the curent role setting is : ”));
tmpname = getfrommyserial(“at+role”, true, 6);
tmpname.trim();
serial.print(tmpname);
if (tmpname == “0”)
serial.println(f(“ [slave]”));
else if (tmpname == “1”)
serial.println(f(“ [master]”));
else if (tmpname == “2”)
serial.println(f(“ [slave-loop]”));
serial.println(f(“choose a new role, or leave it blank to keep unchanged. possible options:”));
serial.println(f(“(0) 0:slave (1) 1:master (2) 2:slave-loop”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
if (tmpname == “”)
{
serial.print(f(“role is left unchanged: ”));
}
else
{
int tmpint = tmpname.toint();
switch (tmpint)
{
case 0: case 1: case 2:
tmpname = “at+role=” + tmpname;
tmpres = getfrommyserial(tmpname, true);
if (tmpres == “ok”)
serial.println (f(“role change successful”));
else
serial.println (f(“faild to change the role, please try again”));
break;
default:
serial.println(f(“incorrect input, role is left unchanged”));
break;
}
}
currst = 2;
currin = 0;
break;
}
case 25:{ // change the connection mode
serial.println(f(“----------------------------------------------------------”));
serial.print(f(“the curent connection mode is : ”));
tmpname = getfrommyserial(“at+cmode”, true, 6);
tmpname.trim();
serial.print(tmpname);
if (tmpname == “0”)
serial.println(f(“ [single remote connection]”));
else if (tmpname == “1”)
serial.println(f(“ [any remote connection]”));
else if (tmpname == “2”)
serial.println(f(“ [test mode]”));
serial.println(f(“choose a new connection mode, or leave it blank to keep unchanged. possible options:”));
serial.println(f(“(0) 0:single remote connection (1) 1:any remote connection (2) 2:test mode”));
while (!serial.available());
tmpname = (serial.readstringuntil(’ ‘));
tmpname.trim();
if (tmpname == “”)
{
serial.print(f(“connection mode is left unchanged: ”));
}
else
{
int tmpint = tmpname.toint();
switch (tmpint)
{
case 0: case 1: case 2:
tmpname = “at+cmode=” + tmpname;
tmpres = getfrommyserial(tmpname, true);
if (tmpres == “ok”)
serial.println (f(“connection mode change successful”));
else
serial.println (f(“faild to change the connection mode, please try again”));
break;
default:
serial.println(f(“incorrect input, connection mode is left unchanged”));
break;
}
}
currst = 2;
currin = 0;
break;
}
case 3:{ // reset the module to the original settings
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“the module settings are reset to original”));
getfrommyserial(“at+orgl”, false, 6);
serial.print(f(“ -- name : ”));
serial.println(getfrommyserial(“at+name”, true, 6));
serial.print(f(“ -- baudrate : ”));
serial.println(getfrommyserial(“at+uart”, true, 6));
serial.print(f(“ -- role : ”));
if (getfrommyserial(“at+role”, true, 6) == “1”)
serial.println(f(“master”));
else
serial.println(f(“slave”));
serial.print(f(“ -- passowrd : ”));
serial.println(getfrommyserial(“at+pswd”, true, 6));
currst = 0;
currin = 0;
break;
}
case 4:{ // the menu to perform the master module operations.
if (getfrommyserial(“at+role”, true, 6) != “1”) { // check if the module role=1 which mean the module is master.
serial.println(f(“the module should be in master role to perform these operations, please change the role.”));
currst = 2;
currin = 0;
}
else{
switch (currin){
case 0:
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“please select from the following operations:”));
serial.println(f(“ 1- discover nearby devices”));
serial.println(f(“ 2- pair with a device”));
serial.println(f(“ 3- connect to a device”));
serial.println(f(“ 4- remove devices from pairing list”));
serial.println(f(“ 5- bind with a device”));
serial.println(f(“ 6- back.。.”));
serial.print(f(“(option no.) ”));
currin = -1;
break;
case 1:
currst = 41; currin = 0; break;
case 2:
currst = 42; currin = 0; break;
case 3:
currst = 43; currin = 0; break;
case 4:
currst = 44; currin = 0; break;
case 5:
currst = 45; currin = 0; break;
case 6:
currst = 0; currin = 0; break;
default:
serial.println (f(“not a valid input, please select from the list”));
currst = 4; currin = 0; break;
}
}
break;
}
case 41:{ // inquire nearby devices (addresses + names)
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“list of nearby devices:”));
getfrommyserial(“at+init”, true); // discard the result, it may result in error if the spp profile is already opened
tmpname = string(“at+inqm=” + string(inq1) + “,” + string(inq2) + “,” + string(inq3));
tmpres = getfrommyserial(tmpname, true);
if (tmpres != “ok”)
serial.println (f(“inquire mode setting failed”));
else
{
getfrommyserialsimple(“at+inq”); // as multiple devices might be discovered, only execute the command then wait on serial for each new line until “ok” is received
cleardevicelist();
tmpname = getfrommyserialsimple(“”, 5); // at least, we have on result even if no devices were discovered, which is the “ok” output at the end of the inquire process
while ((tmpname !=“”)) // as “ok” is less than 5 characters long, the result will be empty string when ok is received.
{
int ind1st = tmpname.indexof(’,‘); // the index of the first comma
int ind2nd = tmpname.indexof(’,‘,ind1st + 1); // the index of the second comma
string devaddr = tmpname.substring(0,ind1st); // the device’s address
string devclas = tmpname.substring(ind1st+1,ind2nd); // the device‘s service class
string devrssi = tmpname.substring(ind2nd+1); // the device’s rssi
devloc = searchdevicelist(devaddr); // check ifthe device address is already discovered, as in most cases the same deie can be discovered multiple times with different rssi and/or different service classes
if ((devloc 《 0)&& devcount 《 maxdev) // a new device, not found in the list, but there is still empty slot in the list (did not exceed the maximum number of stored devices)
{
lstdevices[devcount].address = devaddr; // we store the new device data
lstdevices[devcount].class = devclas;
lstdevices[devcount].rssi = devrssi;
devcount++;
}
delay(10);
tmpname = getfrommyserialsimple(“”, 5); // get the next input from myserial (i.e. bt device)
}
serial.println (strfixed(“+”,colw1 + colw2 + colw3 + colw4 + 3,true,“-”)); // draw a table with the results
serial.println (“| ” + strfixed(“ind.”,colw1)+ strfixed(“bt device name:”,colw2) + strfixed(“bt device address”,colw3) + strfixed(“paired”,colw4)+ “ |”);
serial.println (“| ” + strfixed(“-----”,colw1)+ strfixed(“----------------”,colw2) + strfixed(“------------------”,colw3) + strfixed(“-------”,colw4)+ “ |”);
for (int i=0; i devcount){ // if a numerical input exceeds the number of stored/discovered devices
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“the selected index is out of bounds, please select within the list of available devices”));
serial.print(f(“(option no.) ”));
currin = -3; // stay in the same menu, until a correct index is entered or ‘q’ for exitting to previous menu
}
else{
devloc = currin - 1; // the index starts with 0
tmpname = lstdevices[devloc].address;
tmpname.replace(“:”,“,”);
tmpname = string(“at+pair=” + tmpname+“,”+pairto);
tmpres = getfrommyserialsimple(tmpname);
tmpres = getfrommyserialsimple(“”); // we do this as the pairing process can take longer, so we cannot rely on the timeout in the readstringuntil()
tmpres.trim();
if (tmpres == “ok”)
{
serial.println ((“you are now paired with the device ” + lstdevices[devloc].name +“ [” + lstdevices[devloc].address + “]”));
}
else
{
serial.println (tmpname);
serial.println (tmpres);
serial.println (f(“could not pair with the device, try again or initiat another search for devices”));
}
currst = 4;
currin = 0;
}
break;
}
case 43:{ // connect with one of the discovered devices
if (currin == 0){
if (serialstr.equalsignorecase(“q”)){ //‘q’ to quite to previous menu
currst = 4;
currin = 0;
}
else{
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“select the device index that you want to connect to, q to abort ”));
serial.print(f(“(option no.) ”));
currin = -3;
}
}
else if (currin 》 devcount){ // if a numerical input exceeds the number of stored/discovered devices
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“the selected index is out of bounds, please select within the list of available devices”));
serial.print(f(“(option no.) ”));
currin = -3;
}
else{
devloc = currin - 1; // the index starts with 0
tmpname = lstdevices[devloc].address;
tmpname.replace(“:”,“,”);
tmpname = string(“at+link=” + tmpname);
tmpres = getfrommyserialsimple(tmpname);
tmpres = getfrommyserialsimple(“”); // we do this as the linking/connecting process can take longer, so we cannot rely on the timeout in the readstringuntil()
tmpres.trim();
if (tmpres == “ok”){
serial.println ((“you are now connected with the device ” + lstdevices[devloc].name +“ [” + lstdevices[devloc].address + “], type ‘#end’ to disconnect and reset.”));
currst = 6;
currin = 0;
}
else{
serial.println (tmpname);
serial.println (tmpres);
serial.println (f(“could not connect with the device, try again or initiat another search for devices”));
}
currst = 4;
currin = 0;
}
break;
serialstr = “”;
}
case 44:{
if (currin == 0)
{
if (serialstr.equalsignorecase(“q”))
{
currst = 4;
currin = 0;
}
else if (serialstr.equalsignorecase(“a”))
{
tmpres = getfrommyserial(string(“at+adcn”), true, 6);
tmpres.trim();
int tmpcount = tmpres.toint();
for (int i=0; i devcount)
{
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“the selected index is out of bounds, please select within the list of available devices”));
serial.print(f(“(option no.) ”));
currin = -4;
}
else
{
devloc = currin - 1;
tmpname = lstdevices[devloc].address;
tmpname.replace(“:”,“,”);
tmpres = getfrommyserial(string(“at+fsad=”)+ tmpname, true);
tmpres.trim();
if (tmpres == “ok”)
{
tmpres = getfrommyserial(string(“at+rmsad=”)+ tmpname, true);
tmpres.trim();
if (tmpres == “ok”)
{
serial.println((“the device ” + lstdevices[devloc].name +“ [” + lstdevices[devloc].address + “] is removed from the paired devices list”));
}
}
else
{
serial.println (f(“the device is not within the paired devices list.”));
}
currin = 0;
}
break;
}
case 45:{
if (currin == 0)
{
if (serialstr.equalsignorecase(“q”))
{
currst = 4;
currin = 0;
}
else
{
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“select the device index that you want to bind with, q to abort ”));
serial.print(f(“(option no.) ”));
currin = -3;
}
}
else if (currin 》 devcount)
{
serial.println(f(“----------------------------------------------------------”));
serial.println(f(“the selected index is out of bounds, please select within the list of available devices”));
serial.print(f(“(option no.) ”));
currin = -3;
}
else
{
devloc = currin - 1;
tmpname = lstdevices[devloc].address;
tmpname.replace(“:”,“,”);
tmpname = string(“at+bind=” + tmpname);
tmpres = getfrommyserialsimple(tmpname);
tmpres = getfrommyserialsimple(“”);
tmpres.trim();
if (tmpres == “ok”)
{
serial.println ((“you are now binded with the device ” + lstdevices[devloc].name +“ [” + lstdevices[devloc].address + “], type ‘#end’ to disconnect and reset.”));
}
else
{
serial.println (f(“could not bind with the device, try again or initiat another search for devices”));
}
currst = 4;
currin = 0;
}
break;
}
case 6:{
for (int i=0; i《 serialstr.length(); i++)
myserial.write(serialstr[i]);
break;
}
}
}
serialstr = “”;
}
西门子HMI故障诊断方法分享-天拓四方
Java电子病历编辑器源码,B/S电子病历编辑器源码
鼎盛合方案芯片—电量计插座方案芯片CSE7761
Vayyar设立日本办事处扩大全球业务范围
DALI2.0和DALI1.0完美兼容同一个模块,测试每项可过协议
用于HC-05蓝牙模块的交互式向导
AIT技术
以机器换人产业升级不断推进 工业机器人进口呈现井喷态势
如何更有效保护投影机灯泡
小米11 Pro全新渲染图曝光
VIVO招聘芯片工程师,开价180w,网友回应:正常操作
电梯里的镜面显示屏将全新定义电梯广告
多传感器模块缓解室内农业设计挑战
DxOMark公布OPPO Reno 10倍变焦版后置镜头拍照评分 跻身榜单前三与华为P30 Pro战平
云存储的发展趋势是什么
NTSB正在呼吁波音公司重新设计737NG飞机的风扇整流罩结构
入窑提升机轴头磨损原因及修复方法
显示驱动器,显示驱动器基本原理是什么?
苹果13有侧边指纹吗
UltraScale架构在下一代无线通讯(5G)设计中的诸多优点