What went right: Successfully built the wired direct connection to the NEC Debian host and got the serial data pipeline nicely structured.
Where it went wrong: But wait—the Heltec V3 is refusing to cooperate properly, and after diving head-first into a pointless troubleshooting rabbit hole with AI, I am officially stuck in the mud and unable to move an inch!
Bailing out for today and calling it quits. Time to step away before things get worse!
Here are the details of my struggle with the Heltec V3 yesterday!
What went right: Building the wired direct connection to the NEC Debian host and structuring the serial data pipeline went completely smoothly.
Where it went wrong (The Rabbit Hole):
Tried flashing the Heltec V3 via esptool, but hit a version mismatch/missing stub JSON in the system Python environment.
Reinstalled esptool via pip, but then it started throwing device reports readiness to read but returned no data right after Connecting......
Tried manual BOOT button timing tricks, but after wrestling with the AI in circles, I officially hit a brick wall and waved the white flag to step away!
Current status: Taking a breather and checking out the RadioLib GitHub. Anyone else run into weird serial quirks with ESP32-S3 boards?
I initially ran into issues, but was able to fix these with help of AL. I have now updated the code with bug-fixes in my following post: However the most important part to Dynamically set frequency is missing. Also the frequency in this code i 433.1, which need to be modified to frequency of LoRa satellite passing over your city.
Host Machine: Linux (NEC machine running Python, MQTT broker, and Skyfield).
Connection: USB Serial (/dev/ttyUSB0 via CP210x, 115200 bps).
2. Key Hardware Gotchas & Fixes (for Heltec V3)
Getting the SX1262 on the Heltec V3 to initialize properly required a few specific configurations in RadioLib:
Power: Vext (GPIO 36) must be pulled LOW to supply power to the RF section.
TCXO: Voltage must be explicitly set to 1.8V.
RF Switch: DIO2 must be enabled as an RF switch (radio.setDio2AsRfSwitch(true)).
Explicit SPI Initialization:SPI.begin(9, 11, 10, 8); with module pins mapped to (8, 14, 12, 13).
3. Software Architecture
Orbit Calculation (sat_commander.py): Uses Skyfield with local TLE data (CelesTrak amateur group) to calculate pass events (Rise, Culmination, Set) for target satellites (e.g., NETSAT-1) based on observer location (Hirosaki, Japan).
MQTT & Serial Bridge (mqtt_serial_bridge.py): Listens to the heltec/control MQTT topic and translates target parameters into serial commands (SET,FREQ:<val>,BW:<val>,SF:<val>).
Firmware (sketch.ino): Parses incoming serial commands dynamically and applies real-time frequency adjustments (crucial for tracking Doppler shifts) using RadioLib while continuously monitoring for downlink packets with RSSI/SNR feedback.
4. Arduino Firmware Snippet
C++
#include <RadioLib.h>
SX1262 radio = new Module(8, 14, 12, 13);
void setup() {
Serial.begin(115200);
while(!Serial);
delay(1000);
// Power up Vext and initialize SPI
pinMode(36, OUTPUT);
digitalWrite(36, LOW);
delay(100);
SPI.begin(9, 11, 10, 8);
// Initialize RadioLib with 1.8V TCXO
int state = radio.begin(435.6, 125.0, 9, 5, 0x34, 10, 8, 1.8);
if (state == RADIOLIB_ERR_NONE) {
radio.setDio2AsRfSwitch(true);
radio.startReceive();
}
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil(10);
command.trim();
if (command.startsWith("SET")) {
// Parse and apply frequency/BW/SF dynamically for Doppler tracking
parseAndApplyCommand(command);
}
}
// Packet reception check
if (radio.getPacketLength() > 0) {
String recvStr = "";
if (radio.readData(recvStr) == RADIOLIB_ERR_NONE) {
// Log packet, RSSI, and SNR
}
radio.startReceive();
}
delay(10);
}
This setup bridges orbital calculation directly down to a low-cost embedded LoRa receiver, enabling smooth real-time parameter tuning for satellite passes. Feedback or suggestions are always welcome!
I hope to share a follow-up report once I successfully capture a pass!
73!
Current Status Note: Please note that this is an interim report. While I have successfully verified the hardware initialization, MQTT-to-serial bridging, and dynamic parameter tuning, I have not yet confirmed actual reception or decoding of live LoRa satellite downlinks in the field.
Managed to get the virtual environment and skyfield sorted out on the Linux host (Debian), and finally booted up both the MQTT-to-serial bridge and the orbit commander script!
As you can see in the terminal screenshot below, the bridge is successfully hooked up to /dev/ttyUSB0 listening on heltec/control, and the tracker has successfully pulled the TLE data, showing upcoming passes (like AO-7 starting around 16:55 JST).
Fingers crossed—I’m hoping to test out actual live tracking. To be honest, I’m a bit skeptical if that tiny stock antenna bundled with the kit can actually pull in a signal, but I’m excited to find out!
Any thoughts or advice as I step into the live test phase are always welcome. 73!
I have partial success, i.e. suceeded in flashing heltec so that
(1) It is tuned to receive 433.5 Mhz
(2) Conects to LAN on WiFi
(3) Can connects to MQTT server on Debian Server, either via USB C and tty/USB0 or through LAN
(4) Can connects MQTT server on RPi through WiFi
What it Lacks is automatic tuning and adjustment for Dopler effect through Skyfield. I am in total darkness as to how accomplish this.
Thanks for sharing your setup! To be honest, I’m still feeling my way through the dark myself, but that’s precisely what I’m working on right now!
My approach is using a Python script on the host PC with skyfield to calculate the orbit and Doppler shift, and then publishing frequency updates via MQTT (paho-mqtt) to the Heltec over /dev/ttyUSB0 (or Wi-Fi).
I’ve just updated my script into a persistent monitoring loop and am waiting for the next satellite pass to test it out live. Once I get it running smoothly, I’d be happy to share the python script and logic! 73!
Basically, I would think the way it’s done is: from the message preamble you get an estimate of the Doppler frequency error. Then when you get the message data you apply a frequency correction in the demodulation process. I think the tuning parameters are published for the particular satellite you are tracking.
Congratulations @abcd567! That simulation setup looks fantastic!
Thanks for sharing your progress. Here in my shack, I’m diving back in today to fine-tune my configuration and scripts with my AI collaborator (Gemini). Let’s keep making progress! 73!
I’ve now integrated it with an automated Linux server pipeline (using Skyfield for satellite pass calculation, an MQTT-serial bridge, and SQLite logging) running persistently via systemd. Everything is fully automated now—ready to track AO-7 passes without manual terminal intervention!
Thanks for all the inspiration, and good luck with your setups! 73!
Right now, I’m just using that tiny stock antenna attached to the unit… but I suppose this little guy won’t be enough to actually pull in satellite signals, right? What kind of antenna setup are you using?