Initial commit: ESP32-S3 UWB positioning system
- Added anchor and tag implementations for MaUWB modules - Configured for 6.8Mbps communication with range filtering - Support for multiple tags (tag/tag2 environments) - OLED display integration for real-time measurements - Simplified code without sleep mode and OTA functionality - Complete UWBHelper library for AT command interface
This commit is contained in:
commit
a89215b7ff
10 changed files with 806 additions and 0 deletions
56
src/config.h
Normal file
56
src/config.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
// Hardware Pin Definitions for ESP32-S3
|
||||
#define RESET_PIN 16
|
||||
#define IO_RXD2 18
|
||||
#define IO_TXD2 17
|
||||
#define I2C_SDA 39
|
||||
#define I2C_SCL 38
|
||||
|
||||
// UWB Configuration
|
||||
#ifndef UWB_INDEX
|
||||
#define UWB_INDEX 0
|
||||
#endif
|
||||
|
||||
#ifndef NETWORK_ID
|
||||
#define NETWORK_ID 1234
|
||||
#endif
|
||||
|
||||
// System Configuration
|
||||
#define MAX_DEVICES 10
|
||||
#define MAX_ANCHORS 8
|
||||
#define UWB_TAG_COUNT 64
|
||||
|
||||
// Timing Configuration
|
||||
#define DISPLAY_UPDATE_INTERVAL 500
|
||||
#define DEVICE_TIMEOUT 5000
|
||||
#define SLEEP_DURATION 5000
|
||||
|
||||
// Display Configuration
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1
|
||||
#define SCREEN_ADDRESS 0x3C
|
||||
|
||||
// Serial Configuration
|
||||
#define SERIAL_BAUD 115200
|
||||
|
||||
// Debug Configuration
|
||||
#ifdef DEBUG_ENABLED
|
||||
#define DEBUG_PRINT(x) Serial.print(x)
|
||||
#define DEBUG_PRINTLN(x) Serial.println(x)
|
||||
#define DEBUG_PRINTF(x, ...) Serial.printf(x, __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINTF(x, ...)
|
||||
#endif
|
||||
|
||||
// WiFi Configuration (optional)
|
||||
#ifdef OTA_ENABLED
|
||||
#define WIFI_SSID "YOUR_WIFI_SSID"
|
||||
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_H
|
||||
183
src/main_anchor.cpp
Normal file
183
src/main_anchor.cpp
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include "config.h"
|
||||
#include "UWBHelper.h"
|
||||
|
||||
// Function declarations
|
||||
void showStartupScreen();
|
||||
void processUWBData();
|
||||
void updateDisplay();
|
||||
void checkTimeouts();
|
||||
|
||||
// Hardware setup
|
||||
HardwareSerial uwbSerial(2);
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
UWBHelper uwb(&uwbSerial, RESET_PIN);
|
||||
|
||||
// Data storage
|
||||
DeviceData tags[UWB_TAG_COUNT];
|
||||
DistanceFilter tagFilters[UWB_TAG_COUNT];
|
||||
String response = "";
|
||||
unsigned long lastDisplayUpdate = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(SERIAL_BAUD);
|
||||
Serial.println("Starting UWB Anchor...");
|
||||
|
||||
// Initialize I2C and display
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
||||
Serial.println(F("SSD1306 allocation failed"));
|
||||
for (;;);
|
||||
}
|
||||
|
||||
showStartupScreen();
|
||||
|
||||
// Initialize UWB
|
||||
uwbSerial.begin(115200, SERIAL_8N1, IO_RXD2, IO_TXD2);
|
||||
delay(1000);
|
||||
|
||||
if (!uwb.begin()) {
|
||||
Serial.println("UWB initialization failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Configure as anchor
|
||||
Serial.println("Configuring as Anchor...");
|
||||
uwb.configureDevice(UWB_INDEX, true); // true = anchor
|
||||
uwb.setCapacity(UWB_TAG_COUNT, 10, 1);
|
||||
uwb.setNetwork(NETWORK_ID);
|
||||
uwb.enableReporting(true);
|
||||
uwb.saveConfiguration();
|
||||
delay(1000);
|
||||
uwb.restartDevice();
|
||||
delay(2000);
|
||||
|
||||
// Initialize tag data
|
||||
for (int i = 0; i < UWB_TAG_COUNT; i++) {
|
||||
tags[i].deviceId = -1;
|
||||
tags[i].active = false;
|
||||
tags[i].distance = 0.0;
|
||||
tags[i].rssi = 0.0;
|
||||
tags[i].lastUpdate = 0;
|
||||
}
|
||||
|
||||
Serial.println("Anchor ready! Waiting for tags...");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
processUWBData();
|
||||
updateDisplay();
|
||||
checkTimeouts();
|
||||
|
||||
// Handle serial passthrough for debugging
|
||||
while (Serial.available()) {
|
||||
uwbSerial.write(Serial.read());
|
||||
}
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void processUWBData() {
|
||||
while (uwbSerial.available()) {
|
||||
char c = uwbSerial.read();
|
||||
if (c == '\r') continue;
|
||||
if (c == '\n') {
|
||||
if (response.length() > 0) {
|
||||
Serial.println("Received: " + response);
|
||||
if (uwb.parseRangeData(response, tags, UWB_TAG_COUNT)) {
|
||||
// Successfully parsed data
|
||||
for (int i = 0; i < UWB_TAG_COUNT; i++) {
|
||||
if (tags[i].active && (millis() - tags[i].lastUpdate < 1000)) {
|
||||
Serial.printf("Tag %d: %.2fm, RSSI: %.1fdBm\n",
|
||||
tags[i].deviceId, tags[i].distance, tags[i].rssi);
|
||||
}
|
||||
}
|
||||
}
|
||||
response = "";
|
||||
}
|
||||
} else {
|
||||
response += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateDisplay() {
|
||||
if (millis() - lastDisplayUpdate < DISPLAY_UPDATE_INTERVAL) return;
|
||||
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
|
||||
// Header
|
||||
display.setCursor(0, 0);
|
||||
display.printf("Anchor %d (Net:%d)", UWB_INDEX, NETWORK_ID);
|
||||
|
||||
display.setCursor(0, 10);
|
||||
display.println("Active Tags:");
|
||||
|
||||
// Show active tags
|
||||
int activeCount = 0;
|
||||
int yPos = 20;
|
||||
|
||||
for (int i = 0; i < UWB_TAG_COUNT && yPos < 55; i++) {
|
||||
if (tags[i].active) {
|
||||
display.setCursor(0, yPos);
|
||||
display.printf("T%d: %.2fm", tags[i].deviceId, tags[i].distance);
|
||||
display.setCursor(70, yPos);
|
||||
display.printf("%.0fdBm", tags[i].rssi);
|
||||
yPos += 8;
|
||||
activeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeCount == 0) {
|
||||
display.setCursor(0, 30);
|
||||
display.println("No active tags");
|
||||
display.setCursor(0, 40);
|
||||
display.println("Waiting...");
|
||||
}
|
||||
|
||||
// Status line
|
||||
display.setCursor(0, 56);
|
||||
display.printf("Active: %d/%d", activeCount, UWB_TAG_COUNT);
|
||||
|
||||
display.display();
|
||||
lastDisplayUpdate = millis();
|
||||
}
|
||||
|
||||
void checkTimeouts() {
|
||||
unsigned long currentTime = millis();
|
||||
for (int i = 0; i < UWB_TAG_COUNT; i++) {
|
||||
if (tags[i].active && (currentTime - tags[i].lastUpdate > DEVICE_TIMEOUT)) {
|
||||
tags[i].active = false;
|
||||
Serial.printf("Tag %d timeout\n", tags[i].deviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showStartupScreen() {
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
display.setCursor(0, 0);
|
||||
display.println("MaUWB Anchor");
|
||||
|
||||
display.setCursor(0, 15);
|
||||
display.printf("ID: %d", UWB_INDEX);
|
||||
|
||||
display.setCursor(0, 25);
|
||||
display.printf("Network: %d", NETWORK_ID);
|
||||
|
||||
display.setCursor(0, 35);
|
||||
display.println("6.8Mbps Mode");
|
||||
|
||||
display.setCursor(0, 45);
|
||||
display.println("Initializing...");
|
||||
|
||||
display.display();
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
168
src/main_tag.cpp
Normal file
168
src/main_tag.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include "config.h"
|
||||
#include "UWBHelper.h"
|
||||
|
||||
// Function declarations
|
||||
void showStartupScreen();
|
||||
void processUWBData();
|
||||
void updateDisplay();
|
||||
void checkTimeouts();
|
||||
|
||||
// Hardware setup
|
||||
HardwareSerial uwbSerial(2);
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
UWBHelper uwb(&uwbSerial, RESET_PIN);
|
||||
|
||||
// Data storage
|
||||
DeviceData anchors[MAX_ANCHORS];
|
||||
String response = "";
|
||||
unsigned long lastDisplayUpdate = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(SERIAL_BAUD);
|
||||
|
||||
// Initialize display
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
||||
Serial.println(F("SSD1306 allocation failed"));
|
||||
for (;;);
|
||||
}
|
||||
|
||||
showStartupScreen();
|
||||
|
||||
// Initialize UWB
|
||||
uwbSerial.begin(115200, SERIAL_8N1, IO_RXD2, IO_TXD2);
|
||||
|
||||
if (!uwb.begin()) {
|
||||
Serial.println("UWB initialization failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Configure as tag
|
||||
Serial.println("Configuring as Tag...");
|
||||
uwb.configureDevice(UWB_INDEX, false); // false = tag
|
||||
uwb.setCapacity(10, 10, 1);
|
||||
uwb.setNetwork(NETWORK_ID);
|
||||
uwb.enableReporting(true);
|
||||
uwb.saveConfiguration();
|
||||
delay(1000);
|
||||
uwb.restartDevice();
|
||||
delay(2000);
|
||||
|
||||
// Initialize anchor data
|
||||
for (int i = 0; i < MAX_ANCHORS; i++) {
|
||||
anchors[i].deviceId = -1;
|
||||
anchors[i].active = false;
|
||||
}
|
||||
|
||||
Serial.println("Tag ready!");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
processUWBData();
|
||||
updateDisplay();
|
||||
checkTimeouts();
|
||||
|
||||
// Handle serial passthrough for debugging
|
||||
while (Serial.available()) {
|
||||
uwbSerial.write(Serial.read());
|
||||
}
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void processUWBData() {
|
||||
while (uwbSerial.available()) {
|
||||
char c = uwbSerial.read();
|
||||
if (c == '\r') continue;
|
||||
if (c == '\n') {
|
||||
if (response.length() > 0) {
|
||||
Serial.println("Received: " + response);
|
||||
if (uwb.parseRangeData(response, anchors, MAX_ANCHORS)) {
|
||||
// Successfully parsed data
|
||||
for (int i = 0; i < MAX_ANCHORS; i++) {
|
||||
if (anchors[i].active && (millis() - anchors[i].lastUpdate < 1000)) {
|
||||
Serial.printf("Anchor %d: %.2fm, RSSI: %.1fdBm\n",
|
||||
anchors[i].deviceId, anchors[i].distance, anchors[i].rssi);
|
||||
}
|
||||
}
|
||||
}
|
||||
response = "";
|
||||
}
|
||||
} else {
|
||||
response += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateDisplay() {
|
||||
if (millis() - lastDisplayUpdate < DISPLAY_UPDATE_INTERVAL) return;
|
||||
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
|
||||
// Header
|
||||
display.setCursor(0, 0);
|
||||
display.printf("Tag %d (Net:%d)", UWB_INDEX, NETWORK_ID);
|
||||
|
||||
display.setCursor(0, 10);
|
||||
display.println("Anchors:");
|
||||
|
||||
int activeCount = 0;
|
||||
int yPos = 20;
|
||||
|
||||
for (int i = 0; i < MAX_ANCHORS && yPos < 55; i++) {
|
||||
if (anchors[i].active) {
|
||||
display.setCursor(0, yPos);
|
||||
display.printf("A%d: %.2fm", anchors[i].deviceId, anchors[i].distance);
|
||||
display.setCursor(70, yPos);
|
||||
display.printf("%.0fdBm", anchors[i].rssi);
|
||||
yPos += 8;
|
||||
activeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeCount == 0) {
|
||||
display.setCursor(0, 30);
|
||||
display.println("Searching...");
|
||||
display.setCursor(0, 40);
|
||||
display.println("for anchors...");
|
||||
}
|
||||
|
||||
// Status line
|
||||
display.setCursor(0, 56);
|
||||
display.printf("Found: %d/%d", activeCount, MAX_ANCHORS);
|
||||
|
||||
display.display();
|
||||
lastDisplayUpdate = millis();
|
||||
}
|
||||
|
||||
void checkTimeouts() {
|
||||
unsigned long currentTime = millis();
|
||||
for (int i = 0; i < MAX_ANCHORS; i++) {
|
||||
if (anchors[i].active && (currentTime - anchors[i].lastUpdate > DEVICE_TIMEOUT)) {
|
||||
anchors[i].active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void showStartupScreen() {
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
display.setCursor(0, 0);
|
||||
display.println("MaUWB Tag");
|
||||
display.setCursor(0, 15);
|
||||
display.printf("ID: %d", UWB_INDEX);
|
||||
display.setCursor(0, 25);
|
||||
display.printf("Network: %d", NETWORK_ID);
|
||||
display.setCursor(0, 35);
|
||||
display.println("Initializing...");
|
||||
display.display();
|
||||
delay(2000);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue