使用 RSSI 与 HC05 模块和 Arduino 进行室内定位的源代码
本帖最后由 z01228 于 2021-9-17 13:23 编辑使用 RSSI 与 HC05 模块和 Arduino 进行室内定位的源代码
https://github.com/pasks87/HC05_bluetooth_RSSI_localization
#include <SoftwareSerial.h>
#include <time.h>
//Define Pins
#define RxD 11//Receive Serial pin
#define TxD 10//Transmit Serial pin
SoftwareSerial bt(RxD, TxD) ;
//Define for Data
char btData;
String splitString(String str, String devider, int arrayNumber);
String deviceAddress;
String deviceClass;
String deviceRSSI;
String message;
bool RSSIVisible = true;
String atQuestEnd = "?\r\n";
String atSetEnd = "\r\n";
String atStart = "AT+";
String Initialize = "INIT";
String accesCode = "IAC=9E8B33";
String deviceType = "CLASS=0";
String searchRSSI = "INQM=1,1,20";
//INQM=<Par1>,<Par2>,<Par3> Par1: 0--inquiry mode standard/1--inquiry mode rssi
// Par2: Numero max di device Bluetooth che rispondono
// Par3: Tempo (1-48 : 1.28s to 61.44s)
String receiveRSSI = "INQ";
String roleIsMaster = "ROLE=1";
String roleIsSlave = "ROLE=0";
float n;
#define BTkey 9
void ATCmdSetup() {
bt.listen();
bt.print(atStart + Initialize + atSetEnd); //initialize device
bt.print(atStart + accesCode + atSetEnd); //defines the accesCode this device shares with the others
bt.print(atStart + deviceType + atSetEnd); //defines device type
bt.print(atStart + searchRSSI + atSetEnd); //Search Bluetooth with RSSI value
}
void filterCode() {
if (message.substring(0, 5) == "+INQ:") {
deviceAddress = splitString(message, ",", 0).substring(5);
deviceClass = splitString(message, ",", 1);
deviceRSSI = splitString(message, ",", 2);
}
message = "";
}
String splitString(String str, String devider, int arrayNumber) {
int previousDevider = 0;
int deviders = 1;
for (int i = 0; i < str.length(); i++) {
if (str.substring(i, i + devider.length()) == devider) {
deviders++;
}
}
int devideCounter = 0;
String devidedString;
for (int i = 0; i < str.length(); i++) {
if (str.substring(i, i + devider.length()) == devider) {
if (devideCounter) {
devidedString = str.substring(devidedString.length() + 1, i);
} else {
devidedString = str.substring(0, i);
}
devideCounter++;
previousDevider = i + devider.length();
}
}
devidedString = str.substring(previousDevider, str.length());
if (arrayNumber > deviders) {
return "ERROR; array number not found. Array number is to big.";
} else {
return devidedString;
}
}
//Funzione che converte un numero esadecimale in decimale
unsigned int hexToDec(String hexString) {
unsigned int decValue = 0;
int nextInt;
for (int i = 0; i < hexString.length() - 2; i++) {
nextInt = int(hexString.charAt(i));
if (nextInt >= 48 && nextInt <= 57)
nextInt = map(nextInt, 48, 57, 0, 9);
if (nextInt >= 65 && nextInt <= 70)
nextInt = map(nextInt, 65, 70, 10, 15);
if (nextInt >= 97 && nextInt <= 102)
nextInt = map(nextInt, 97, 102, 10, 15);
nextInt = constrain(nextInt, 0, 15);
decValue = (decValue * 16) + nextInt;
}
return decValue;
}
//Funzione per il calcolo della distanza
void distanceRSSI() {
float tempo;
float rssi_dbm; //RSSI scansionato
float rssi_ref = -61; // RSSI ad 1 metro di distanza
float distanza; //Variabile usata per memorizzare i valori della distanza di ogni singolo beacon rispetto al nodo target
if (deviceAddress == "98D3:36:80EF77") {
rssi_dbm = hexToDec(deviceRSSI) - 65535; //complemento a due per determinare il valore RSSI in dBm
Serial.print(rssi_dbm);
Serial.print("");
n = (rssi_ref - rssi_dbm) / (10 * 1.73);
//Calcolo della distanza
distanza = (100) * (pow(10, n));
Serial.print(distanza);
tempo = millis();
Serial.print("");
Serial.println(tempo / 1000);
}
}
void setup() {
// define pin modes for tx, rx:
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
// Switch module to AT mode
pinMode(BTkey, OUTPUT);
digitalWrite(BTkey, HIGH);
Serial.begin(9600);
// Start the software serial - baud rate for AT mode is 38400
bt.begin(38400); // HC-05 default speed in AT command mode
ATCmdSetup();
Serial.flush();
}
void loop() {
// Keep reading from the HC-05 and send to the Arduino Serial Monitor
if (bt.available()) {
btData = bt.read();
message.concat(btData); // la concatenazione avviene in 0,654 secondi
if (btData == '\n') {
bt.print(atStart + receiveRSSI + atSetEnd);
filterCode();
if (RSSIVisible) {
distanceRSSI();
}
}
}
}
实现这个程序需要几个蓝牙模块呀楼主 这个准确性怎么样?
页:
[1]