使用 RSSI 与 HC05 模块和 Arduino 进行室内定位的源代码-Arduino中文社区 - Powered by Discuz! Archiver

z01228 发表于 2021-9-13 13:16

使用 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();
      }
    }
}
}

anxin25252 发表于 2022-2-24 03:18

实现这个程序需要几个蓝牙模块呀楼主

z01228 发表于 2022-2-28 16:03

这个准确性怎么样?
页: [1]
查看完整版本: 使用 RSSI 与 HC05 模块和 Arduino 进行室内定位的源代码