Reorganize project structure and create development roadmap
- Move documentation to organized docs/ directory structure - Add dev notes - Create comprehensive 5-phase roadmap for indoor positioning system - Move AT command manual and hardware images to docs/ - Update README with hardware links and project overview - Remove sleep mode and OTA functionality for simplification - Clean up project structure for production development
This commit is contained in:
parent
ea370ac702
commit
e7c8fad272
8 changed files with 884 additions and 47 deletions
|
|
@ -1,32 +1,42 @@
|
|||
#include "UWBHelper.h"
|
||||
#include <math.h>
|
||||
|
||||
UWBHelper::UWBHelper(HardwareSerial* serial, int reset) {
|
||||
uwbSerial = serial;
|
||||
resetPin = reset;
|
||||
}
|
||||
|
||||
bool UWBHelper::begin() {
|
||||
pinMode(resetPin, OUTPUT);
|
||||
digitalWrite(resetPin, HIGH);
|
||||
|
||||
uwbSerial->begin(115200);
|
||||
delay(1000);
|
||||
|
||||
// Test communication
|
||||
// ===== BASIC COMMANDS (3.2-3.6) =====
|
||||
|
||||
bool UWBHelper::testConnection() {
|
||||
String response = sendCommand("AT?", 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
void UWBHelper::reset() {
|
||||
digitalWrite(resetPin, LOW);
|
||||
delay(100);
|
||||
digitalWrite(resetPin, HIGH);
|
||||
delay(1000);
|
||||
String UWBHelper::getVersion() {
|
||||
return sendCommand("AT+GETVER?", 2000);
|
||||
}
|
||||
|
||||
bool UWBHelper::configureDevice(int deviceId, bool isAnchor, int dataRate, int rangeFilter) {
|
||||
bool UWBHelper::restart() {
|
||||
String response = sendCommand("AT+RESTART", 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
bool UWBHelper::restore() {
|
||||
String response = sendCommand("AT+RESTORE", 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
bool UWBHelper::save() {
|
||||
String response = sendCommand("AT+SAVE", 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
// ===== CONFIGURATION COMMANDS (3.7-3.8) =====
|
||||
|
||||
bool UWBHelper::setConfig(int deviceId, int role, int dataRate, int rangeFilter) {
|
||||
String cmd = "AT+SETCFG=" + String(deviceId) + "," +
|
||||
String(isAnchor ? 1 : 0) + "," +
|
||||
String(role) + "," +
|
||||
String(dataRate) + "," +
|
||||
String(rangeFilter);
|
||||
|
||||
|
|
@ -34,6 +44,24 @@ bool UWBHelper::configureDevice(int deviceId, bool isAnchor, int dataRate, int r
|
|||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::getConfig() {
|
||||
return sendCommand("AT+GETCFG?", 2000);
|
||||
}
|
||||
|
||||
// ===== ANTENNA COMMANDS (3.9-3.10) =====
|
||||
|
||||
bool UWBHelper::setAntennaDelay(int delay) {
|
||||
String cmd = "AT+SETANT=" + String(delay);
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::getAntennaDelay() {
|
||||
return sendCommand("AT+GETANT?", 2000);
|
||||
}
|
||||
|
||||
// ===== CAPACITY COMMANDS (3.11-3.12) =====
|
||||
|
||||
bool UWBHelper::setCapacity(int tagCount, int timeSlot, int extMode) {
|
||||
String cmd = "AT+SETCAP=" + String(tagCount) + "," +
|
||||
String(timeSlot) + "," +
|
||||
|
|
@ -43,28 +71,104 @@ bool UWBHelper::setCapacity(int tagCount, int timeSlot, int extMode) {
|
|||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::getCapacity() {
|
||||
return sendCommand("AT+GETCAP?", 2000);
|
||||
}
|
||||
|
||||
// ===== REPORTING COMMANDS (3.13-3.14) =====
|
||||
|
||||
bool UWBHelper::setReporting(bool enable) {
|
||||
String cmd = "AT+SETRPT=" + String(enable ? 1 : 0);
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::getReporting() {
|
||||
return sendCommand("AT+GETRPT?", 2000);
|
||||
}
|
||||
|
||||
// ===== SLEEP COMMAND (3.16) =====
|
||||
|
||||
bool UWBHelper::setSleep(int sleepTime) {
|
||||
String cmd = "AT+SLEEP=" + String(sleepTime);
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
// ===== POWER COMMANDS (3.17-3.18) =====
|
||||
|
||||
bool UWBHelper::setPower(String powerValue) {
|
||||
String cmd = "AT+SETPOW=" + powerValue;
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::getPower() {
|
||||
return sendCommand("AT+GETPOW?", 2000);
|
||||
}
|
||||
|
||||
// ===== DATA COMMANDS (3.19-3.20) =====
|
||||
|
||||
bool UWBHelper::sendData(int length, String data) {
|
||||
String cmd = "AT+DATA=" + String(length) + "," + data;
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::receiveData() {
|
||||
return sendCommand("AT+RDATA", 2000);
|
||||
}
|
||||
|
||||
// ===== NETWORK COMMANDS (3.21-3.22) =====
|
||||
|
||||
bool UWBHelper::setNetwork(int networkId) {
|
||||
String cmd = "AT+SETPAN=" + String(networkId);
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
}
|
||||
|
||||
String UWBHelper::getNetwork() {
|
||||
return sendCommand("AT+GETPAN?", 2000);
|
||||
}
|
||||
|
||||
// ===== LEGACY WRAPPER FUNCTIONS =====
|
||||
|
||||
bool UWBHelper::begin() {
|
||||
pinMode(resetPin, OUTPUT);
|
||||
digitalWrite(resetPin, HIGH);
|
||||
|
||||
uwbSerial->begin(115200);
|
||||
delay(1000);
|
||||
|
||||
// Test communication
|
||||
return testConnection();
|
||||
}
|
||||
|
||||
void UWBHelper::reset() {
|
||||
digitalWrite(resetPin, LOW);
|
||||
delay(100);
|
||||
digitalWrite(resetPin, HIGH);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
bool UWBHelper::configureDevice(int deviceId, bool isAnchor, int dataRate, int rangeFilter) {
|
||||
return setConfig(deviceId, isAnchor ? 1 : 0, dataRate, rangeFilter);
|
||||
}
|
||||
|
||||
bool UWBHelper::enableReporting(bool enable) {
|
||||
String cmd = "AT+SETRPT=" + String(enable ? 1 : 0);
|
||||
String response = sendCommand(cmd, 2000);
|
||||
return isResponseOK(response);
|
||||
return setReporting(enable);
|
||||
}
|
||||
|
||||
bool UWBHelper::saveConfiguration() {
|
||||
String response = sendCommand("AT+SAVE", 2000);
|
||||
return isResponseOK(response);
|
||||
return save();
|
||||
}
|
||||
|
||||
bool UWBHelper::restartDevice() {
|
||||
String response = sendCommand("AT+RESTART", 2000);
|
||||
return isResponseOK(response);
|
||||
return restart();
|
||||
}
|
||||
|
||||
// ===== COMMUNICATION =====
|
||||
|
||||
String UWBHelper::sendCommand(String command, int timeout) {
|
||||
String response = "";
|
||||
|
||||
|
|
@ -75,8 +179,16 @@ String UWBHelper::sendCommand(String command, int timeout) {
|
|||
while ((millis() - startTime) < timeout) {
|
||||
while (uwbSerial->available()) {
|
||||
char c = uwbSerial->read();
|
||||
response += c;
|
||||
if (c == '\n' || c == '\r') {
|
||||
if (response.length() > 0) {
|
||||
Serial.println("Response: " + response);
|
||||
return response;
|
||||
}
|
||||
} else {
|
||||
response += c;
|
||||
}
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
|
||||
if (response.length() > 0) {
|
||||
|
|
@ -85,6 +197,8 @@ String UWBHelper::sendCommand(String command, int timeout) {
|
|||
return response;
|
||||
}
|
||||
|
||||
// ===== RANGE DATA PARSING =====
|
||||
|
||||
bool UWBHelper::parseRangeData(String data, DeviceData devices[], int maxDevices) {
|
||||
if (!data.startsWith("AT+RANGE=")) {
|
||||
return false;
|
||||
|
|
@ -108,7 +222,22 @@ bool UWBHelper::parseRangeData(String data, DeviceData devices[], int maxDevices
|
|||
if (rangeEnd == -1) return false;
|
||||
|
||||
String rangeData = data.substring(rangeStart, rangeEnd);
|
||||
float distance = rangeData.toFloat() / 100.0; // Convert cm to meters
|
||||
|
||||
// Parse first non-zero distance
|
||||
int commaIdx = 0;
|
||||
float distance = 0.0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int nextComma = rangeData.indexOf(',', commaIdx);
|
||||
if (nextComma == -1) nextComma = rangeData.length();
|
||||
|
||||
float dist = rangeData.substring(commaIdx, nextComma).toFloat();
|
||||
if (dist > 0) {
|
||||
distance = dist / 100.0; // Convert cm to meters
|
||||
break;
|
||||
}
|
||||
commaIdx = nextComma + 1;
|
||||
if (commaIdx >= rangeData.length()) break;
|
||||
}
|
||||
|
||||
// Parse RSSI data
|
||||
int rssiIndex = data.indexOf("rssi:(");
|
||||
|
|
@ -137,10 +266,154 @@ bool UWBHelper::parseRangeData(String data, DeviceData devices[], int maxDevices
|
|||
return false;
|
||||
}
|
||||
|
||||
String UWBHelper::getVersion() {
|
||||
return sendCommand("AT+GETVER?", 2000);
|
||||
bool UWBHelper::parseDetailedRangeData(String data, RangeResult* result) {
|
||||
if (!data.startsWith("AT+RANGE=")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse tid
|
||||
int tidIndex = data.indexOf("tid:");
|
||||
if (tidIndex == -1) return false;
|
||||
int commaPos = data.indexOf(',', tidIndex);
|
||||
if (commaPos == -1) return false;
|
||||
result->tagId = data.substring(tidIndex + 4, commaPos).toInt();
|
||||
|
||||
// Parse timer (if present)
|
||||
int timerIndex = data.indexOf("timer:");
|
||||
if (timerIndex != -1) {
|
||||
int timerComma = data.indexOf(',', timerIndex);
|
||||
if (timerComma == -1) timerComma = data.indexOf(',', timerIndex);
|
||||
result->timer = data.substring(timerIndex + 6, timerComma).toInt();
|
||||
}
|
||||
|
||||
// Parse timerSys (if present)
|
||||
int timerSysIndex = data.indexOf("timerSys:");
|
||||
if (timerSysIndex != -1) {
|
||||
int timerSysComma = data.indexOf(',', timerSysIndex);
|
||||
if (timerSysComma == -1) timerSysComma = data.indexOf(',', timerSysIndex);
|
||||
result->timerSys = data.substring(timerSysIndex + 9, timerSysComma).toInt();
|
||||
}
|
||||
|
||||
// Parse mask
|
||||
int maskIndex = data.indexOf("mask:");
|
||||
if (maskIndex != -1) {
|
||||
int maskComma = data.indexOf(',', maskIndex);
|
||||
result->mask = data.substring(maskIndex + 5, maskComma).toInt();
|
||||
}
|
||||
|
||||
// Parse sequence
|
||||
int seqIndex = data.indexOf("seq:");
|
||||
if (seqIndex != -1) {
|
||||
int seqComma = data.indexOf(',', seqIndex);
|
||||
result->sequence = data.substring(seqIndex + 4, seqComma).toInt();
|
||||
}
|
||||
|
||||
// Parse ranges
|
||||
int rangeIndex = data.indexOf("range:(");
|
||||
if (rangeIndex != -1) {
|
||||
int rangeStart = rangeIndex + 7;
|
||||
int rangeEnd = data.indexOf(')', rangeStart);
|
||||
String rangeData = data.substring(rangeStart, rangeEnd);
|
||||
|
||||
int startIdx = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int commaIdx = rangeData.indexOf(',', startIdx);
|
||||
if (commaIdx == -1) commaIdx = rangeData.length();
|
||||
|
||||
result->ranges[i] = rangeData.substring(startIdx, commaIdx).toFloat() / 100.0;
|
||||
startIdx = commaIdx + 1;
|
||||
if (startIdx >= rangeData.length()) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse RSSI
|
||||
int rssiIndex = data.indexOf("rssi:(");
|
||||
if (rssiIndex != -1) {
|
||||
int rssiStart = rssiIndex + 6;
|
||||
int rssiEnd = data.indexOf(')', rssiStart);
|
||||
String rssiData = data.substring(rssiStart, rssiEnd);
|
||||
|
||||
int startIdx = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int commaIdx = rssiData.indexOf(',', startIdx);
|
||||
if (commaIdx == -1) commaIdx = rssiData.length();
|
||||
|
||||
result->rssi[i] = rssiData.substring(startIdx, commaIdx).toFloat();
|
||||
startIdx = commaIdx + 1;
|
||||
if (startIdx >= rssiData.length()) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse anchor IDs
|
||||
int ancidIndex = data.indexOf("ancid:(");
|
||||
if (ancidIndex != -1) {
|
||||
int ancidStart = ancidIndex + 7;
|
||||
int ancidEnd = data.indexOf(')', ancidStart);
|
||||
String ancidData = data.substring(ancidStart, ancidEnd);
|
||||
|
||||
int startIdx = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int commaIdx = ancidData.indexOf(',', startIdx);
|
||||
if (commaIdx == -1) commaIdx = ancidData.length();
|
||||
|
||||
result->anchorIds[i] = ancidData.substring(startIdx, commaIdx).toInt();
|
||||
startIdx = commaIdx + 1;
|
||||
if (startIdx >= ancidData.length()) break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===== ADVANCED FUNCTIONS =====
|
||||
|
||||
bool UWBHelper::requestAnchorPosition(int anchorId, AnchorPosition* position) {
|
||||
// Custom command to request anchor position
|
||||
String cmd = "AT+GETPOS=" + String(anchorId);
|
||||
String response = sendCommand(cmd, 2000);
|
||||
|
||||
if (response.indexOf("POS=") >= 0) {
|
||||
// Parse response format: POS=id,x,y,confidence
|
||||
int idStart = response.indexOf("=") + 1;
|
||||
int comma1 = response.indexOf(",", idStart);
|
||||
int comma2 = response.indexOf(",", comma1 + 1);
|
||||
int comma3 = response.indexOf(",", comma2 + 1);
|
||||
|
||||
if (comma1 > 0 && comma2 > 0 && comma3 > 0) {
|
||||
position->anchorId = response.substring(idStart, comma1).toInt();
|
||||
position->x = response.substring(comma1 + 1, comma2).toFloat();
|
||||
position->y = response.substring(comma2 + 1, comma3).toFloat();
|
||||
position->confidence = response.substring(comma3 + 1).toFloat();
|
||||
position->valid = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
position->valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UWBHelper::calculatePosition(DeviceData devices[], int deviceCount, float* x, float* y) {
|
||||
// Simple trilateration with first 3 active devices
|
||||
int activeCount = 0;
|
||||
DeviceData activeDevices[3];
|
||||
|
||||
for (int i = 0; i < deviceCount && activeCount < 3; i++) {
|
||||
if (devices[i].active) {
|
||||
activeDevices[activeCount] = devices[i];
|
||||
activeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeCount < 3) return false;
|
||||
|
||||
// For now, assume anchors are at fixed positions (would need anchor position data)
|
||||
// This is a placeholder - real implementation would use actual anchor coordinates
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===== UTILITY FUNCTIONS =====
|
||||
|
||||
bool UWBHelper::isResponseOK(String response) {
|
||||
return response.indexOf("OK") >= 0;
|
||||
}
|
||||
|
|
@ -148,12 +421,16 @@ bool UWBHelper::isResponseOK(String response) {
|
|||
void UWBHelper::printDiagnostics() {
|
||||
Serial.println("=== UWB Diagnostics ===");
|
||||
Serial.println("Version: " + getVersion());
|
||||
Serial.println("Config: " + sendCommand("AT+GETCFG?", 2000));
|
||||
Serial.println("Capacity: " + sendCommand("AT+GETCAP?", 2000));
|
||||
Serial.println("Power: " + sendCommand("AT+GETPOW?", 2000));
|
||||
Serial.println("Config: " + getConfig());
|
||||
Serial.println("Capacity: " + getCapacity());
|
||||
Serial.println("Antenna: " + getAntennaDelay());
|
||||
Serial.println("Power: " + getPower());
|
||||
Serial.println("Network: " + getNetwork());
|
||||
Serial.println("Reporting: " + getReporting());
|
||||
}
|
||||
|
||||
// DistanceFilter Implementation
|
||||
// ===== DISTANCE FILTER IMPLEMENTATION =====
|
||||
|
||||
DistanceFilter::DistanceFilter() : index(0), filled(false) {
|
||||
for (int i = 0; i < FILTER_SIZE; i++) readings[i] = 0;
|
||||
}
|
||||
|
|
@ -195,4 +472,71 @@ void DistanceFilter::reset() {
|
|||
index = 0;
|
||||
filled = false;
|
||||
for (int i = 0; i < FILTER_SIZE; i++) readings[i] = 0;
|
||||
}
|
||||
|
||||
// ===== POSITION CALCULATOR IMPLEMENTATION =====
|
||||
|
||||
bool PositionCalculator::trilaterate(float x1, float y1, float r1,
|
||||
float x2, float y2, float r2,
|
||||
float x3, float y3, float r3,
|
||||
float* x, float* y) {
|
||||
// Trilateration algorithm
|
||||
float A = 2 * (x2 - x1);
|
||||
float B = 2 * (y2 - y1);
|
||||
float C = pow(r1, 2) - pow(r2, 2) - pow(x1, 2) + pow(x2, 2) - pow(y1, 2) + pow(y2, 2);
|
||||
float D = 2 * (x3 - x2);
|
||||
float E = 2 * (y3 - y2);
|
||||
float F = pow(r2, 2) - pow(r3, 2) - pow(x2, 2) + pow(x3, 2) - pow(y2, 2) + pow(y3, 2);
|
||||
|
||||
float denominator = A * E - B * D;
|
||||
if (abs(denominator) < 0.001) return false; // Points are collinear
|
||||
|
||||
*x = (C * E - F * B) / denominator;
|
||||
*y = (A * F - D * C) / denominator;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PositionCalculator::multilaterate(AnchorPosition anchors[], float distances[], int count, float* x, float* y) {
|
||||
if (count < 3) return false;
|
||||
|
||||
// Use least squares method for more than 3 anchors
|
||||
if (count == 3) {
|
||||
return trilaterate(anchors[0].x, anchors[0].y, distances[0],
|
||||
anchors[1].x, anchors[1].y, distances[1],
|
||||
anchors[2].x, anchors[2].y, distances[2],
|
||||
x, y);
|
||||
}
|
||||
|
||||
// For more than 3 anchors, use weighted least squares (simplified version)
|
||||
float sumX = 0, sumY = 0, sumW = 0;
|
||||
|
||||
for (int i = 0; i < count - 1; i++) {
|
||||
for (int j = i + 1; j < count; j++) {
|
||||
for (int k = j + 1; k < count; k++) {
|
||||
float tempX, tempY;
|
||||
if (trilaterate(anchors[i].x, anchors[i].y, distances[i],
|
||||
anchors[j].x, anchors[j].y, distances[j],
|
||||
anchors[k].x, anchors[k].y, distances[k],
|
||||
&tempX, &tempY)) {
|
||||
float weight = anchors[i].confidence * anchors[j].confidence * anchors[k].confidence;
|
||||
sumX += tempX * weight;
|
||||
sumY += tempY * weight;
|
||||
sumW += weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sumW > 0) {
|
||||
*x = sumX / sumW;
|
||||
*y = sumY / sumW;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
float PositionCalculator::calculateDistance(float x1, float y1, float x2, float y2) {
|
||||
return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
|
||||
}
|
||||
|
|
@ -12,6 +12,25 @@ struct DeviceData {
|
|||
bool active;
|
||||
};
|
||||
|
||||
struct AnchorPosition {
|
||||
int anchorId;
|
||||
float x;
|
||||
float y;
|
||||
float confidence;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
struct RangeResult {
|
||||
int tagId;
|
||||
int mask;
|
||||
int sequence;
|
||||
float ranges[8];
|
||||
float rssi[8];
|
||||
int anchorIds[8];
|
||||
unsigned long timer;
|
||||
unsigned long timerSys;
|
||||
};
|
||||
|
||||
class UWBHelper {
|
||||
private:
|
||||
HardwareSerial* uwbSerial;
|
||||
|
|
@ -20,26 +39,68 @@ private:
|
|||
public:
|
||||
UWBHelper(HardwareSerial* serial, int reset);
|
||||
|
||||
// Initialization
|
||||
// Basic Commands (3.2-3.6)
|
||||
bool testConnection(); // AT?
|
||||
String getVersion(); // AT+GETVER?
|
||||
bool restart(); // AT+RESTART
|
||||
bool restore(); // AT+RESTORE
|
||||
bool save(); // AT+SAVE
|
||||
|
||||
// Configuration Commands (3.7-3.8)
|
||||
bool setConfig(int deviceId, int role, int dataRate = 1, int rangeFilter = 1); // AT+SETCFG
|
||||
String getConfig(); // AT+GETCFG?
|
||||
|
||||
// Antenna Commands (3.9-3.10)
|
||||
bool setAntennaDelay(int delay); // AT+SETANT
|
||||
String getAntennaDelay(); // AT+GETANT?
|
||||
|
||||
// Capacity Commands (3.11-3.12)
|
||||
bool setCapacity(int tagCount, int timeSlot = 10, int extMode = 0); // AT+SETCAP
|
||||
String getCapacity(); // AT+GETCAP?
|
||||
|
||||
// Reporting Commands (3.13-3.14)
|
||||
bool setReporting(bool enable); // AT+SETRPT
|
||||
String getReporting(); // AT+GETRPT?
|
||||
|
||||
// Range Command (3.15)
|
||||
bool parseRangeData(String data, DeviceData devices[], int maxDevices);
|
||||
bool parseDetailedRangeData(String data, RangeResult* result);
|
||||
|
||||
// Sleep Command (3.16)
|
||||
bool setSleep(int sleepTime); // AT+SLEEP
|
||||
|
||||
// Power Commands (3.17-3.18)
|
||||
bool setPower(String powerValue = "FD"); // AT+SETPOW
|
||||
String getPower(); // AT+GETPOW?
|
||||
|
||||
// Data Commands (3.19-3.20)
|
||||
bool sendData(int length, String data); // AT+DATA
|
||||
String receiveData(); // AT+RDATA
|
||||
|
||||
// Network Commands (3.21-3.22)
|
||||
bool setNetwork(int networkId); // AT+SETPAN
|
||||
String getNetwork(); // AT+GETPAN?
|
||||
|
||||
// Legacy wrapper functions for backward compatibility
|
||||
bool begin();
|
||||
void reset();
|
||||
|
||||
// Configuration
|
||||
bool configureDevice(int deviceId, bool isAnchor, int dataRate = 1, int rangeFilter = 1);
|
||||
bool setCapacity(int tagCount, int timeSlot = 10, int extMode = 1);
|
||||
bool setNetwork(int networkId);
|
||||
bool enableReporting(bool enable);
|
||||
bool saveConfiguration();
|
||||
bool restartDevice();
|
||||
|
||||
// Communication
|
||||
String sendCommand(String command, int timeout = 2000);
|
||||
bool parseRangeData(String data, DeviceData devices[], int maxDevices);
|
||||
|
||||
// Advanced parsing
|
||||
bool requestAnchorPosition(int anchorId, AnchorPosition* position);
|
||||
|
||||
// Utility
|
||||
String getVersion();
|
||||
bool isResponseOK(String response);
|
||||
void printDiagnostics();
|
||||
|
||||
// Position calculation helpers
|
||||
bool calculatePosition(DeviceData devices[], int deviceCount, float* x, float* y);
|
||||
};
|
||||
|
||||
// Data filtering class
|
||||
|
|
@ -57,4 +118,16 @@ public:
|
|||
void reset();
|
||||
};
|
||||
|
||||
// Position calculation class
|
||||
class PositionCalculator {
|
||||
public:
|
||||
static bool trilaterate(float x1, float y1, float r1,
|
||||
float x2, float y2, float r2,
|
||||
float x3, float y3, float r3,
|
||||
float* x, float* y);
|
||||
|
||||
static bool multilaterate(AnchorPosition anchors[], float distances[], int count, float* x, float* y);
|
||||
static float calculateDistance(float x1, float y1, float x2, float y2);
|
||||
};
|
||||
|
||||
#endif // UWBHELPER_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue