This commit is contained in:
Joshua King
2026-10-02 12:23:58 -04:00
parent f0af1dbbcb
commit ad1e7e6d01
219 changed files with 488314 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
# TFmini Plus distance bench
This is a receive-only sketch for a DFRobot DFR1154 ESP32-S3 camera board and the owned TFmini Plus. It **compiles but has not been flashed or run**. It reads the sensor's default 9-byte UART frames, checks the checksum and signal strength, and reports distance and a range-only `near` flag over USB serial. It does not perform person detection or change either eye. The TF-Luna uses the same default frame, but this sketch's 10 cm minimum must be changed to 20 cm before using it with that sensor.
Before wiring, confirm the actual camera board revision and sensor cable against the [DFRobot board documentation](https://wiki.dfrobot.com/dfr1154/) and [Benewake TFmini Plus manual](https://en.benewake.com/uploadfiles/2025/04/20250430175221028.pdf). The manual's stock cable lists red +5V, white RXD, green TXD, and black GND. Verify the cable on the unit at hand before applying power. The intended receive-only connection is:
| TFmini Plus | DFR1154 bench connection |
| --- | --- |
| +5V | Regulated 5 V supply, sized for at least the manual's 140 mA peak |
| GND | Supply ground joined to DFR1154 ground |
| TXD | Exposed DFR1154 GPIO44 / RXD (3.3 V UART signal) |
| RXD | Leave disconnected for this read-only test |
Do not use the camera board's 3.3 V pin to supply the TFmini Plus; the manual specifies 5 V ±0.5 V. The sketch assumes the sensor still has its factory UART setting of 115200 baud and 9-byte frames in centimeters. It rejects bad checksums, signal strength below 100 or overexposure, and distances under the 10 cm rated minimum. It reports `near=1` at or below 61 cm and returns to `near=0` at or above 76 cm or after 300 ms without a valid reading. Those thresholds are bench settings; the final effect also needs person confirmation and synchronized messages to both eyes.
The compile-only board profile used on this laptop is `esp32:esp32:esp32s3:FlashSize=16M,PSRAM=opi,PartitionScheme=app3M_fat9M_16MB,USBMode=hwcdc,CDCOnBoot=cdc` with Arduino ESP32 core 3.3.5. The build uses 322,359 bytes program storage and 21,360 bytes static RAM. The DFR1154's actual flash/PSRAM and USB configuration must be checked before upload. Uploading this sketch would replace whatever camera firmware is currently installed; save its recovery path first.
For a bench run, record the printed distance and strength at approximately 10, 20, 45, 60, and 75 cm, a very-close position, several off-axis positions, and when a nearby object is present without a person. Record observations in `tracking/proximity-bench.md` and decide whether the narrow beam and mounting position are acceptable.
@@ -0,0 +1,96 @@
// Benewake TFmini Plus receive-only bench test for the DFRobot DFR1154 camera.
// Sensor default: 9-byte/cm frames at 115200 baud. Confirm the exact board
// revision and sensor cable pinout before wiring or flashing.
//
// TFmini Plus needs regulated 5 V (+/-0.5 V), not the 3.3 V Gravity pin.
// Join supply and DFR1154 grounds. Connect sensor TXD to camera GPIO44/RXD.
// Sensor RXD is not needed. The TF-Luna uses the same default frame, but its
// minimum rated distance is 20 cm rather than the 10 cm used below.
#include <Arduino.h>
namespace {
constexpr int kLidarRxPin = 44;
constexpr int kUnusedLidarTxPin = -1;
constexpr uint32_t kLidarBaud = 115200;
constexpr uint16_t kNearEnterCm = 61;
constexpr uint16_t kNearExitCm = 76;
constexpr uint32_t kReportPeriodMs = 100;
HardwareSerial lidar(1);
uint8_t frame[9] = {};
uint8_t frame_index = 0;
uint16_t distance_cm = 0;
uint16_t strength = 0;
bool valid_range = false;
bool near_range = false;
uint32_t last_valid_ms = 0;
uint32_t last_report_ms = 0;
void accept_frame() {
uint8_t sum = 0;
for (int i = 0; i < 8; ++i) sum += frame[i];
if (sum != frame[8]) return;
distance_cm = static_cast<uint16_t>(frame[2]) |
(static_cast<uint16_t>(frame[3]) << 8);
strength = static_cast<uint16_t>(frame[4]) |
(static_cast<uint16_t>(frame[5]) << 8);
valid_range = strength >= 100 && strength != 0xFFFF && distance_cm >= 10;
// This is a range-only preview. The final red state also requires a
// camera-confirmed person and both eye boards receiving the same message.
if (valid_range) {
last_valid_ms = millis();
if (!near_range && distance_cm <= kNearEnterCm) near_range = true;
if (near_range && distance_cm >= kNearExitCm) near_range = false;
}
}
void accept_byte(uint8_t value) {
if (frame_index == 0) {
if (value == 0x59) frame[frame_index++] = value;
return;
}
if (frame_index == 1) {
if (value == 0x59) {
frame[frame_index++] = value;
} else {
frame_index = 0;
}
return;
}
frame[frame_index++] = value;
if (frame_index == sizeof(frame)) {
accept_frame();
frame_index = 0;
}
}
} // namespace
void setup() {
Serial.begin(115200);
lidar.begin(kLidarBaud, SERIAL_8N1, kLidarRxPin, kUnusedLidarTxPin);
delay(250);
Serial.println("TFmini Plus receive-only bench: GPIO44/RXD, 115200, cm frames");
}
void loop() {
while (lidar.available()) accept_byte(static_cast<uint8_t>(lidar.read()));
const uint32_t now = millis();
if (now - last_valid_ms > 300) {
valid_range = false;
near_range = false;
}
if (now - last_report_ms >= kReportPeriodMs) {
last_report_ms = now;
if (valid_range) {
Serial.printf("distance_cm=%u strength=%u near=%u\n", distance_cm,
strength, near_range ? 1 : 0);
} else {
Serial.println("range=invalid_or_waiting");
}
}
}