FluxBench.AIShared project · read-only

LoRa Weather Link

ESP32 DevKit (WROOM-32)·Arduino C++·Updated Jul 27, 2026·by FluxBench TeamIncludes Lab + Schematic + PCB

Long-range wireless telemetry bench on a single ESP32: one RFM95 radio plays a remote weather station transmitting 4-byte binary packets (sequence, temperature, humidity) every 2 seconds, while a second RFM95 is the base station that receives and prints the readings with RSSI. Both radios share sync word 0xF3 — midway the remote is deliberately misconfigured to 0x34 so you can watch the link drop and recover, with the Lab simulator explaining the sync-word filtering. Bundled Lab bench, schematic and routed PCB included.

sketch.ino
// LoRa Weather Link — two RFM95 radios on one bench
// LoRaRemote (NSS=GPIO5) plays a remote weather station: every 2 s it
// transmits a 4-byte packet (sequence, temp whole, temp tenths, humidity).
// The global LoRa object (NSS=GPIO15) is the base station that receives
// and prints the readings. Both radios share sync word 0xF3 — halfway
// through, the remote briefly switches to 0x34 and the link drops (watch
// the Lab warning), then recovers when the sync word is restored.
// Both modules share VSPI: MISO=GPIO19, MOSI=GPIO23, SCK=GPIO18, 3V3, GND.

#include <SPI.h>
#include <LoRa.h>

LoRaClass LoRaRemote;   // remote weather node radio

int seq = 0;

void setup() {
  Serial.begin(115200);
  LoRa.setPins(15, 4, 2);        // base station: NSS=15, RST=4, DIO0=2
  LoRa.begin(915E6);
  LoRa.setSyncWord(0xF3);
  LoRaRemote.setPins(5, 21, 22); // remote node: NSS=5, RST=21, DIO0=22
  LoRaRemote.begin(915E6);
  LoRaRemote.setSyncWord(0xF3);
  Serial.println("Remote weather node online (NSS=5)");
  Serial.println("Base station online (NSS=15), shared sync word 0xF3");
}

void loop() {
  seq++;

  if (seq == 5) {
    LoRaRemote.setSyncWord(0x34);  // misconfigured remote: wrong sync word
    Serial.println("Remote misconfigured: sync word changed to 0x34");
  }
  if (seq == 6) {
    LoRaRemote.setSyncWord(0xF3);  // fixed
    Serial.println("Remote sync word restored to 0xF3");
  }

  // Remote node: transmit one binary weather reading
  int tempWhole = 21 + seq / 2;
  int tempFrac = (seq % 2) * 5;
  int hum = 40 + seq;
  LoRaRemote.beginPacket();
  LoRaRemote.write(seq);
  LoRaRemote.write(tempWhole);
  LoRaRemote.write(tempFrac);
  LoRaRemote.write(hum);
  LoRaRemote.endPacket();

  // Base station: poll for a packet
  int sz = LoRa.parsePacket();
  if (sz == 4) {
    int rseq = LoRa.read();
    int rw = LoRa.read();
    int rf = LoRa.read();
    int rhum = LoRa.read();
    Serial.print("BASE  pkt #");
    Serial.print(rseq);
    Serial.print("  temp ");
    Serial.print(rw);
    Serial.print(".");
    Serial.print(rf);
    Serial.print(" C  humidity ");
    Serial.print(rhum);
    Serial.print(" %  RSSI ");
    Serial.print(LoRa.packetRssi());
    Serial.println(" dBm");
  } else {
    Serial.println("BASE  no packet received (sync word mismatch drops the link)");
  }

  delay(2000);
}

Built with FluxBench.AI — the AI workbench for embedded projects.