fix: throttle BLE writes to TAG — GPS 1Hz, IMU 2Hz

Tag was crashing ~5s after BLE connect due to GPS_RX at 5Hz +
IMU_RX at 10Hz flooding NimBLE while DW1000 UWB SPI also runs.
Combined 15 writes/sec exceeded ESP32 processing capacity.

GPS: 0.2s interval → 1.0s (5Hz → 1Hz)
IMU: 0.1s interval → 0.5s (10Hz → 2Hz)
Total BLE write load: 15/s → 3/s

Updated BLEStatusView captions to match new rates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sl-ios 2026-04-06 17:31:30 -04:00
parent b2bda0f467
commit 6fa2a1b03f
2 changed files with 8 additions and 8 deletions

View File

@ -74,7 +74,7 @@ struct BLEStatusView: View {
Label { Label {
VStack(alignment: .leading, spacing: 2) { VStack(alignment: .leading, spacing: 2) {
Text("GPS → Tag") Text("GPS → Tag")
Text("5 Hz · 20 bytes/packet") Text("1 Hz · 20 bytes/packet")
.font(.caption).foregroundStyle(.secondary) .font(.caption).foregroundStyle(.secondary)
} }
} icon: { } icon: {
@ -86,7 +86,7 @@ struct BLEStatusView: View {
Label { Label {
VStack(alignment: .leading, spacing: 2) { VStack(alignment: .leading, spacing: 2) {
Text("IMU → Tag") Text("IMU → Tag")
Text("10 Hz · 22 bytes/packet (accel + gyro + mag)") Text("2 Hz · 22 bytes/packet (accel + gyro + mag)")
.font(.caption).foregroundStyle(.secondary) .font(.caption).foregroundStyle(.secondary)
} }
} icon: { } icon: {

View File

@ -116,8 +116,8 @@ final class SensorManager: NSObject, ObservableObject {
// MARK: - Timers // MARK: - Timers
private var mqttGPSTimer: Timer? // 1 Hz MQTT publish private var mqttGPSTimer: Timer? // 1 Hz MQTT publish
private var bleGPSTimer: Timer? // 5 Hz BLE GPS write private var bleGPSTimer: Timer? // 1 Hz BLE GPS write
private var bleIMUTimer: Timer? // 10 Hz BLE IMU write private var bleIMUTimer: Timer? // 2 Hz BLE IMU write
private var uwbStalenessTimer: Timer? private var uwbStalenessTimer: Timer?
private var rateTimer: Timer? private var rateTimer: Timer?
@ -263,13 +263,13 @@ final class SensorManager: NSObject, ObservableObject {
private func startBLETimers() { private func startBLETimers() {
stopBLETimers() stopBLETimers()
// GPS tag at 5 Hz (200 ms) // GPS tag at 1 Hz (1000 ms) throttled to avoid flooding constrained ESP32
bleGPSTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) { [weak self] _ in bleGPSTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
guard let self, let loc = self.lastKnownLocation else { return } guard let self, let loc = self.lastKnownLocation else { return }
self.ble.sendGPS(BLEPackets.gpsPacket(from: loc)) self.ble.sendGPS(BLEPackets.gpsPacket(from: loc))
} }
// IMU tag at 10 Hz (100 ms) // IMU tag at 2 Hz (500 ms) throttled to avoid flooding constrained ESP32
bleIMUTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in bleIMUTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in
guard let self, let motion = self.lastKnownMotion else { return } guard let self, let motion = self.lastKnownMotion else { return }
self.ble.sendIMU(BLEPackets.imuPacket(from: motion)) self.ble.sendIMU(BLEPackets.imuPacket(from: motion))
} }