148 lines
3.8 KiB
C++
148 lines
3.8 KiB
C++
|
|
// 20260212 ChatGPT
|
||
|
|
// $Id$
|
||
|
|
// $HeadURL$
|
||
|
|
|
||
|
|
#include <Arduino.h>
|
||
|
|
#include <SPI.h>
|
||
|
|
#include <RadioLib.h>
|
||
|
|
|
||
|
|
// --- Compile-time label ---
|
||
|
|
#ifndef NODE_LABEL
|
||
|
|
#define NODE_LABEL "?"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// --- Pins injected via platformio.ini build_flags ---
|
||
|
|
#ifndef LORA_CS
|
||
|
|
#error "LORA_CS not defined"
|
||
|
|
#endif
|
||
|
|
#ifndef LORA_DIO1
|
||
|
|
#error "LORA_DIO1 not defined"
|
||
|
|
#endif
|
||
|
|
#ifndef LORA_RESET
|
||
|
|
#error "LORA_RESET not defined"
|
||
|
|
#endif
|
||
|
|
#ifndef LORA_BUSY
|
||
|
|
#error "LORA_BUSY not defined"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// SX1262 on T-Beam Supreme (tbeam-s3-core pinout)
|
||
|
|
SX1262 radio = new Module(LORA_CS, LORA_DIO1, LORA_RESET, LORA_BUSY);
|
||
|
|
|
||
|
|
static volatile bool g_rx_flag = false;
|
||
|
|
|
||
|
|
|
||
|
|
static void onDio1Rise() {
|
||
|
|
g_rx_flag = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void print_config() {
|
||
|
|
Serial.printf("Node=%s\n", NODE_LABEL);
|
||
|
|
Serial.printf("Pins: CS=%d DIO1=%d RST=%d BUSY=%d SCK=%d MISO=%d MOSI=%d\r\n",
|
||
|
|
(int)LORA_CS, (int)LORA_DIO1, (int)LORA_RESET, (int)LORA_BUSY,
|
||
|
|
(int)LORA_SCK, (int)LORA_MISO, (int)LORA_MOSI);
|
||
|
|
Serial.printf("LoRa: freq=915.0 BW=125 SF=7 CR=5 txp=14\r\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
void setup() {
|
||
|
|
Serial.begin(115200);
|
||
|
|
delay(250);
|
||
|
|
Serial.println();
|
||
|
|
Serial.println("Exercise 01: LoRa ASCII ping-pong (serial only)");
|
||
|
|
|
||
|
|
// Ensure SPI pins match the variant
|
||
|
|
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||
|
|
|
||
|
|
int state = radio.begin(915.0 /* MHz */, 125.0 /* kHz */, 7 /* SF */, 5 /* CR */, 0x12 /* sync */, 14 /* dBm */);
|
||
|
|
if (state != RADIOLIB_ERR_NONE) {
|
||
|
|
Serial.printf("ERROR: radio.begin failed, code=%d\r\n", state);
|
||
|
|
while (true) delay(1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Match Meshtastic-like wiring assumptions for SX1262 modules:
|
||
|
|
// - DIO2 used as RF switch
|
||
|
|
// - TCXO at 1.8V
|
||
|
|
//OLD radio.setDio2AsRfSwitch(true);
|
||
|
|
//OLD radio.setTcxoVoltage((float)LORA_TCXO_VOLTAGE);
|
||
|
|
// below is replacement for above 2 lines:
|
||
|
|
|
||
|
|
//maybe_setDio2AsRfSwitch(radio, true);
|
||
|
|
//maybe_setTcxoVoltage(radio, (float)LORA_TCXO_VOLTAGE);
|
||
|
|
|
||
|
|
// end of replacement
|
||
|
|
|
||
|
|
// Set up RX interrupt
|
||
|
|
radio.setDio1Action(onDio1Rise);
|
||
|
|
|
||
|
|
// Start receiving
|
||
|
|
state = radio.startReceive();
|
||
|
|
if (state != RADIOLIB_ERR_NONE) {
|
||
|
|
Serial.printf("ERROR: startReceive failed, code=%d\r\n", state);
|
||
|
|
while (true) delay(1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
print_config();
|
||
|
|
}
|
||
|
|
|
||
|
|
void loop() {
|
||
|
|
// Periodic TX (with a label-based offset to reduce collisions)
|
||
|
|
static uint32_t next_tx_ms = 0;
|
||
|
|
static uint32_t iter = 0;
|
||
|
|
uint32_t now = millis();
|
||
|
|
|
||
|
|
if (next_tx_ms == 0) {
|
||
|
|
// Offset A and B so they don't always collide
|
||
|
|
uint32_t offset = (NODE_LABEL[0] == 'A') ? 500 : 1500;
|
||
|
|
next_tx_ms = now + offset;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((int32_t)(now - next_tx_ms) >= 0) {
|
||
|
|
next_tx_ms = now + 2000; // 2 seconds for this smoke test
|
||
|
|
|
||
|
|
// String msg = String("I am ") + NODE_LABEL + " iter=" + String(iter++);
|
||
|
|
String msg = String(" ") + NODE_LABEL + " sends greetings. iter=" + String(iter++);
|
||
|
|
Serial.printf("TX: %s\r\n", msg.c_str());
|
||
|
|
|
||
|
|
//int tx = radio.transmit(msg);
|
||
|
|
//if (tx != RADIOLIB_ERR_NONE) {
|
||
|
|
// Serial.printf("TX ERROR code=%d\r\n", tx);
|
||
|
|
// }
|
||
|
|
|
||
|
|
// After transmit, resume RX
|
||
|
|
//radio.startReceive();
|
||
|
|
// DIO1 triggers on TX-done as well as RX-done.
|
||
|
|
// If left armed, TX completion looks like RX.
|
||
|
|
g_rx_flag = false;
|
||
|
|
radio.clearDio1Action();
|
||
|
|
|
||
|
|
int tx = radio.transmit(msg);
|
||
|
|
if (tx != RADIOLIB_ERR_NONE) {
|
||
|
|
Serial.printf("TX ERROR code=%d\r\n", tx);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Re-arm RX interrupt and resume RX
|
||
|
|
g_rx_flag = false;
|
||
|
|
radio.setDio1Action(onDio1Rise);
|
||
|
|
radio.startReceive();
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// RX handling
|
||
|
|
if (g_rx_flag) {
|
||
|
|
g_rx_flag = false;
|
||
|
|
|
||
|
|
String rx;
|
||
|
|
int state = radio.readData(rx);
|
||
|
|
if (state == RADIOLIB_ERR_NONE) {
|
||
|
|
Serial.printf("RX: %s | RSSI=%.1f SNR=%.1f\r\n",
|
||
|
|
rx.c_str(), radio.getRSSI(), radio.getSNR());
|
||
|
|
} else {
|
||
|
|
Serial.printf("RX ERROR code=%d\r\n", state);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Keep receiving
|
||
|
|
radio.startReceive();
|
||
|
|
}
|
||
|
|
|
||
|
|
delay(5);
|
||
|
|
}
|
||
|
|
|