From b86c441045867602bf8a8d833415fe0289463799 Mon Sep 17 00:00:00 2001 From: shinya Date: Fri, 29 May 2026 09:30:44 +0200 Subject: [PATCH] updated readme and deploy script --- README.md | 32 ++++++++--- chip_test_example/README.md | 13 +---- chip_test_example/deploy.sh | 6 +- chip_test_example/lr1121_malnus_api.md | 76 ++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 20 deletions(-) create mode 100644 chip_test_example/lr1121_malnus_api.md diff --git a/README.md b/README.md index 18ca29e..2e7180e 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,28 @@ Pi Zero W 2 captures frames, runs a motion shader, sends diffs over LoRa. -- `camera_example/` — libcamera + libjpeg-turbo, streams MJPEG over TCP. Works. -- `shader_example/` — offscreen GL motion diff between two frames. Works on desktop. -- `math_example/` — pixel → 3D vertex projection (depth map to OBJ mesh). +- `camera_example/` — libcamera + libjpeg-turbo, streams MJPEG over TCP. Works. +- `shader_example/` — offscreen GL motion diff between two frames. Works on desktop. +- `math_example/` — pixel → 3D vertex projection (depth map to OBJ mesh). - `chip_test_example/` — LR1121 LoRa + ICM-20948 IMU + u-blox GPS drivers/tests. -- `main.cpp` — prototype that wires camera + shader + TCP together. +- `main.cpp` — prototype that wires camera + shader + TCP together. -References: -- https://www.youtube.com/watch?v=zFiubdrJqqI -- https://github.com/ConsistentlyInconsistentYT/Pixeltovoxelprojector/ +## Goal + +Automatic, real-time detection of fast high-flying objects (planes, drones) using +multiple Pi cameras and a GLES motion shader. Objects moving in straight lines or +smooth curves are kept; everything else is filtered out. + +Each node scans the sky, detects motion, extracts a vertex line from the diff frame, +timestamps it via GPS, and transmits the minimal payload over LoRa. +The central device is also a Pi camera node running the same base pipeline, with +additional functionality for receiving LoRa packets from other nodes, fusing +sightlines, and saving combined results locally. + +## Status + +The examples are all individually working. Final integration (camera → shader → math → +LoRa) is the next step. ## Build main.cpp @@ -20,3 +33,8 @@ g++ main.cpp -o main \ -levent -levent_pthreads -lpthread \ -lturbojpeg -lglfw -lGLEW -lGL -lEGL -lGLESv2 ``` + +## References + +- https://www.youtube.com/watch?v=zFiubdrJqqI +- https://github.com/ConsistentlyInconsistentYT/Pixeltovoxelprojector/ diff --git a/chip_test_example/README.md b/chip_test_example/README.md index 7a86aa0..f4e5efa 100644 --- a/chip_test_example/README.md +++ b/chip_test_example/README.md @@ -61,7 +61,7 @@ make Run verbose first so you see exactly where it fails: ```sh -sudo ./lora_rx -v --433 +sudo ./lora_rx -v sudo ./imu_test -v ./gps_test -v ``` @@ -71,8 +71,8 @@ sudo ./imu_test -v ## LoRa debug ```sh -ls /dev/spidev0.0 # SPI enabled? -sudo ./lora_rx -v --433 # step labels show exactly which command hangs +ls /dev/spidev0.0 # SPI enabled? +sudo ./lora_rx -v # step labels show exactly which command hangs ``` If it hangs at `Calibrate` — the chip isn't responding over SPI at all. @@ -81,13 +81,6 @@ Check wiring, CS, and that SPI is enabled. The crystal needs no tuning. If TX/RX runs but packets never arrive — check that DIO5/DIO6 reach the RF switch on your module. Without the switch, the antenna path is disconnected. -To try 2.4 GHz instead (different antenna required): - -```sh -sudo ./lora_rx -v --24 -sudo ./lora_tx -v --24 -``` - If the chip is stuck in bootloader (fw < 0x02xx), escape with: ```sh diff --git a/chip_test_example/deploy.sh b/chip_test_example/deploy.sh index 43adff8..b6d9b9d 100755 --- a/chip_test_example/deploy.sh +++ b/chip_test_example/deploy.sh @@ -39,10 +39,10 @@ deploy_and_build() { return $BUILD_STATUS } -deploy_and_build 10.91.51.166 & +deploy_and_build 10.91.51.183 & PID1=$! -deploy_and_build 10.91.51.165 & +deploy_and_build 10.91.51.166 & PID2=$! wait $PID1 @@ -52,7 +52,7 @@ wait $PID2 STATUS2=$? echo "----------------------------------------" -echo "10.91.51.165 status: $STATUS1" +echo "10.91.51.183 status: $STATUS1" echo "10.91.51.166 status: $STATUS2" if [ $STATUS1 -ne 0 ] || [ $STATUS2 -ne 0 ]; then diff --git a/chip_test_example/lr1121_malnus_api.md b/chip_test_example/lr1121_malnus_api.md new file mode 100644 index 0000000..852905c --- /dev/null +++ b/chip_test_example/lr1121_malnus_api.md @@ -0,0 +1,76 @@ +# lr1121_malnus.hpp — API reference + +```cpp +#include "lr1121_malnus.hpp" // namespace lr1121 +``` + +## Setup + +```cpp +lr1121::Config cfg; // all fields have sensible defaults +cfg.freq_hz = lr1121::FREQ_433; // FREQ_433 / FREQ_868 / FREQ_2400 +cfg.sf = 7; // spreading factor 6–12 +cfg.bw = 0x04; // 0x03=62.5 kHz 0x04=125 kHz 0x05=250 kHz +cfg.cr = 0x01; // 0x01=4/5 0x02=4/6 0x03=4/7 0x04=4/8 +cfg.tx_dbm = 10; +cfg.pa_sel = lr1121::PA_LP; // PA_LP (0–14 dBm) PA_HP (0–22 dBm) + +lr1121::Radio radio; +if (!radio.begin(cfg)) + fprintf(stderr, "init failed: %s\n", lr1121::Radio::errorString(radio.lastError())); +``` + +## TX / RX + +```cpp +bool ok = radio.send(data, len); // blocks until TX_DONE or error +// returns: true=ok false=error (check lastError) + +lr1121::RxInfo info; + +// one-shot: arm, wait timeout_ms, chip returns to standby +int n = radio.receive(buf, sizeof(buf), 1000, &info); + +// continuous: arm once, chip stays in RX between packets +radio.startListening(); +for (;;) { + int n = radio.receive(buf, sizeof(buf), 0, &info); // 0 = wait forever per call + if (n > 0) { /* handle */ } +} +radio.stopListening(); // returns chip to standby + +// receive() returns: n>=0 bytes -1=timeout/error -2=crc error +// info.rssi_dbm info.snr_db info.signal_rssi_dbm +``` + +## Runtime tuning *(call between packets, chip stays in standby)* + +```cpp +radio.setFrequency(lr1121::FREQ_868); +radio.setTxPower(20, lr1121::PA_HP); +radio.setModulation(9, 0x04, 0x01); // sf, bw, cr +``` + +## Diagnostics + +```cpp +lr1121::ChipVersion v = radio.chipVersion(); // v.hw v.type v.fw_hi v.fw_lo +float vbat = radio.vbatVolts(); +uint16_t errs = radio.chipErrors(); // chip-side error flags +lr1121::Error e = radio.lastError(); +const char *msg = lr1121::Radio::errorString(e); +``` + +## Errors + +`Ok` `NotReady` `SpiOpen` `SpiIo` `GpioOpen` `BusyTimeout` `BadChip` `TxTimeout` `TxLbd` `RxTimeout` `RxCrc` + +## Other + +```cpp +radio.softResetSettings(); // re-apply Config without hard reset +radio.reboot(false); // reboot chip (true = stay in bootloader) +radio.end(); // close SPI + GPIO fds +const lr1121::Config &c = radio.config(); // current live config +``` +