Arduino y HC-05: Asistente de menú Serial (6 / 6 paso)

Paso 6: código:

Abajo está el código de Arduino (también se puede descargar el mismo archivo)

Prestar atención al uso intensivo de la cadena en este programa. Me enfrenté a muchos problemas porque si esta ya podríamos resolver par de ellos con las siguientes observaciones:

  • Utilice la función 'String.reserve()' de la memoria dinámica para la instancia de string, esto permite mejor manipulación en las asignaciones de memoria en el montón. Pero todavía no es suficiente, no garantiza nada.
  • Uso de la macro 'F()': que permite el almacenamiento de cadenas en memoria flash en lugar de RAM. Funciona sólo con cadenas estáticas dentro de las operaciones de impresión/println. Esto es muy útil pero no suficiente (no funciona con cuerdas dinámicas)
  • disminuir el número de cuerdas reservados: no pide encontrar hasta 10 dispositivos, si esto no es realmente lo que quieres,. 3 sería suficiente por ejemplo.

El problema que el programa ejecutar y cargar en cualquier caso, que funcionará de forma inesperada, respondiendo a las diferentes consultas que la escribió y no mostrar algunas cadenas y cosas así.

La manera de resolverlo es usar arrays char (o char *) en lugar de cadenas. Este es mi siguiente paso pero ahora no tengo tiempo para hacerlo ;)

 /* * 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('\n')); tmpStr.trim(); delay(50); if (discardOK) mySerial.readStringUntil('\n'); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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('\n')); 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 = ""; } 

Artículos Relacionados

Serial Servo Controller w/Arduino - Control hasta 12 Servos a la vez utilizando el Arduino y una conexión USB

Serial Servo Controller w/Arduino - Control hasta 12 Servos a la vez utilizando el Arduino y una conexión USB

voy a mostrarle cómo usar el Arduino para controlar hasta 12 servos a la vez con variación mínima.  Mediante una sencilla interfaz serial puede controlar la posición del servo hasta 12 canales.  Hasta 10 posiciones instantáneas se puede guardar y rep
Usando arduino Serial UART 16 x 2 LCD

Usando arduino Serial UART 16 x 2 LCD

El serial UART 16 × 2 LCD le permite controlar un LCD paralelo basadosobre una interfaz serial de un alambre. La LCD serial se encarga de todos los comandos de HD44780 lo que permite una perfecta integración con cualquier micro que puede comunicarse
Cómo conectar una LCD serial a un Arduino UNO

Cómo conectar una LCD serial a un Arduino UNO

En este instructable le demostraré cómo conecté un serial LCD 16 X 2 a un Arduino UNO.Hay un montón de instructables y tutoriales que muestra cómo conectar un LCD normal a un Arduino pero no muchos mostrando una LCD serial y en mi Arduino las clavija
Proceso de comunicación serial en Arduino

Proceso de comunicación serial en Arduino

El hardware de Arduino tiene soporte incorporado para la comunicación serial en los pines 0 y 1 (que también va a la computadora vía la conexión USB). El soporte nativo de la serie pasa a través de una pieza de hardware (integrado en el chip) llamada
Función de Arduino Serial.read() y Serial.readString()

Función de Arduino Serial.read() y Serial.readString()

Serial monitor de Arduino es una característica muy útil. Serie se utiliza para ver recibir datos, enviar datos, imprimir datos y así sucesivamente. Serie monitor está conectado con el Arduino a través de comunicación serial. Esta comunicación serial
PyDuino, interfaz Arduino con Python a través de comunicación serial

PyDuino, interfaz Arduino con Python a través de comunicación serial

Aprender a interfaz arduino a través de comunicación serial con python usando la librería pyduino. Hay algunos otros tutoriales que hay en instructables en cómo interfaz arduino con python, pero no demuestran cómo hacerlo todo, donde esperamos que es
Cómo conectar Arduino a un PC a través del puerto serial

Cómo conectar Arduino a un PC a través del puerto serial

a lo que yo he utilizado un ordenador con Ubuntu 12.04 y el lenguaje de programación C++, pero si quieres usa Windows el código funciona, sólo tienes que cambiar el puerto utilizado para conectar con arduino, pero esto se explica en el siguiente paso
Adición de Digispark (con bootloader) soporte para Arduino existente 1.6. x IDE

Adición de Digispark (con bootloader) soporte para Arduino existente 1.6. x IDE

Digispark es pequeño Arduino IDE desarrollo compatible placa basada en el attiny85 Atmel que se conecta directamente al USB. Tiene muy pocos pernos, pero todavía puede hacer algunas cosas en limpios. Digispark derechos de autor por Digistump LLC (dig
Control remoto de Arduino DIY y Lego RC vehículo!!!!

Control remoto de Arduino DIY y Lego RC vehículo!!!!

Actualizar (29/08/13): lectores gracias por sus palabras de entusiasmo y tipo con respecto a este proyecto! Ha sido un viaje tremendo desde que comencé este proyecto en marzo, pero estoy muy contento con el producto resultante y el entusiasmo con que
SensoDuino: Convertir su teléfono Android en un concentrador de sensores inalámbricos para Arduino

SensoDuino: Convertir su teléfono Android en un concentrador de sensores inalámbricos para Arduino

Actualizaciones23 de noviembre de 2013: SensoDuino 0.160 obtiene una cara izquierda.19 de noviembre. 2031: opinión: la increíble sinergia entre Arduino y Android.19 de noviembre de 2013: SensoDuino 0.159 está hacia fuera. Fecha teléfono Android (y, m
Arduino Mini Lux metro

Arduino Mini Lux metro

Necesitaba un medidor de Lux para las pruebas de linternas. Hay algunos buenos lux metros disponibles en la gama de $15-25, pero envío siempre lleva mucho tiempo y necesitaba ahora. Es entonces cuando me di cuenta que tenía un inusitado BH1750 medido
Guía de iniciación a Arduino

Guía de iniciación a Arduino

Después de algunos años de experimentar con Arduino, he decidido que ha llegado el momento de compartir el conocimiento que he adquirido. Así aquí va, una guía de Arduino, con los fundamentos desnudos para principiantes y algunas explicaciones más av
Arduino XboxOne, TV y ventilador mando a distancia

Arduino XboxOne, TV y ventilador mando a distancia

En este instructable mostraré cómo utilizar un Arduino infrarrojo escudo de control remoto (IR) que hice para que puedan hacer un control para todos los dispositivos y decir adiós a múltiples controles y baterías AAA.Si usted no puede conseguir el es
Controlar múltiples LEDs con un Arduino Uno.

Controlar múltiples LEDs con un Arduino Uno.

Este instructable coversssets de instrucciones para el uso de un microcontrolador, llamado el Arduino Uno para crear diferentes secuencias de iluminación de diodos electroluminosos, más popularmente conocida como LED. Las siguientes instrucciones cub