ESP32 Point to Point With LoRa Network

hello, i want to ask. i use 2 esp, esp a (Antares LR-ESP201)+ rf96 and esp b (LYNX-32)+ rf96. esp a serves to send sensor data to esp b using LoRa. when the distance is 10m, it shows RSSI -85 dbm. i use a frequency of 920 MHz and Spreading Factor = 8.

well when I try to do testing to send data from esp a to esp b at a distance of 200 meters. there is no data received at esp b. what should I do? pls help

esp a :

#include <SPI.h>
#include <RH_RF95.h>

#define RFM95_CS 2
#define RFM95_INT 14
#define RF95_FREQ 920.0

RH_RF95 rf95(RFM95_CS, RFM95_INT);

HardwareSerial mySerial(1);  // RX=16, TX=17 (sesuaikan)

unsigned long previousMillisSend = 0;
const unsigned long sendInterval = 60000;  // Kirim data tiap 1 menit

unsigned long previousMillisRead = 0;
const unsigned long readInterval = 2000;  // Baca data setiap 100 ms (baca data secara cepat)

String latestData = ""; // Menyimpan data terbaru yang dibaca

// Fungsi untuk set Spreading Factor (SF) di RH_RF95
void setSpreadingFactor(uint8_t sf) {
  if (sf < 6) sf = 6;
  else if (sf > 12) sf = 12;

  uint8_t modemConfig1 = rf95.spiRead(RH_RF95_REG_1D_MODEM_CONFIG1);
  uint8_t modemConfig2 = rf95.spiRead(RH_RF95_REG_1E_MODEM_CONFIG2);

  // Clear bit SF lama (bit 4-7)
  modemConfig2 &= 0x0F;
  // Set SF baru (bit 4-7)
  modemConfig2 |= (sf << 4);

  rf95.spiWrite(RH_RF95_REG_1E_MODEM_CONFIG2, modemConfig2);

  Serial.print("Spreading Factor set to SF");
  Serial.println(sf);
}

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600, SERIAL_8N1, 16, 17);
  Serial.println("LoRa Bridge ESP A Starting...");

  if (!rf95.init()) {
    Serial.println("LoRa init failed");
    while (1);
  }
  Serial.println("LoRa init OK");

  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Frequency set to: ");
  Serial.println(RF95_FREQ);

  rf95.setTxPower(20, false);

  // Set SF8
  setSpreadingFactor(8);
}

void loop() {
  unsigned long currentMillis = millis();

  // 1. Langsung baca data setiap kali ada data yang masuk
  if (mySerial.available()) {
    String data = mySerial.readStringUntil('\n');
    data.trim();

    if (data.length() > 0) {
      latestData = data;  // Simpan data terbaru
      Serial.println("Data from Arduino:");
      Serial.println(data);
    }
  }

  // 2. Kirim data ke ESP B setiap 1 menit sekali
  if (currentMillis - previousMillisSend >= sendInterval) {
    previousMillisSend = currentMillis;

    if (latestData.length() > 0) {
      // Kirim data via LoRa
      rf95.send((uint8_t *)latestData.c_str(), latestData.length());
      rf95.waitPacketSent();

      Serial.println("Data sending via LoRa :");
      Serial.println(latestData); // Tampilkan data yang dikirim
    }
  }
}

esp b

#include <SPI.h>
#include <RH_RF95.h>
#include <WiFi.h>
#include <HTTPClient.h>

#define RFM95_CS 5    // Pin CS LoRa ESP B
#define RFM95_INT 27  // Pin interrupt LoRa ESP B
#define RF95_FREQ 920.0  // Frekuensi LoRa

const char *ssid = "HUAWEI-2.4G-FTTR";       // Ganti SSID WiFi kamu
const char *password = "Telkom123";   // Ganti password WiFi kamu

const char* http_server = "http://192.168.3.129:3000/data";  // URL server backend

RH_RF95 rf95(RFM95_CS, RFM95_INT);

String latestData = "";

// Fungsi untuk set Spreading Factor (SF) di RH_RF95
void setSpreadingFactor(uint8_t sf) {
  if (sf < 6) sf = 6;
  else if (sf > 12) sf = 12;

  uint8_t modemConfig1 = rf95.spiRead(RH_RF95_REG_1D_MODEM_CONFIG1);
  uint8_t modemConfig2 = rf95.spiRead(RH_RF95_REG_1E_MODEM_CONFIG2);

  // Clear bit SF lama (bit 4-7)
  modemConfig2 &= 0x0F;
  // Set SF baru (bit 4-7)
  modemConfig2 |= (sf << 4);

  rf95.spiWrite(RH_RF95_REG_1E_MODEM_CONFIG2, modemConfig2);

  Serial.print("Spreading Factor set to SF");
  Serial.println(sf);
}

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("LoRa Receiver + HTTP Client Starting...");

  // Setup LoRa
  if (!rf95.init()) {
    Serial.println("LoRa init failed");
    while (1);
  }
  Serial.println("LoRa init OK");

  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Frequency to: ");
  Serial.println(RF95_FREQ);

  rf95.setTxPower(20, false);

  // Set SF8
  setSpreadingFactor(8);

  // Connect to WiFi (Reconnection Loop)
  connectToWiFi();
}

void loop() {
  // Cek pesan LoRa yang masuk
  if (rf95.available()) {
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);

    if (rf95.recv(buf, &len)) {
      String pesan = "";
      for (int i = 0; i < len; i++) {
        pesan += (char)buf[i];
      }
      pesan.trim();

      Serial.println("Data received via LoRa:");
      Serial.println(pesan);

      // Menampilkan kekuatan sinyal (RSSI)
      int rssi = rf95.lastRssi();  // Mendapatkan nilai RSSI
      Serial.print("Signal Strength (RSSI): ");
      Serial.print(rssi);
      Serial.println(" dBm");

      // Simpan data terbaru dan waktu terima data
      latestData = pesan;

      // Kirim data ke backend HTTP segera setelah menerima data
      sendHTTP(latestData);

      // Update waktu terakhir menerima data setelah pengiriman HTTP berhasil
      // Tidak perlu lagi timeout, cukup update waktu setelah setiap pengiriman HTTP
    } else {
      Serial.println("Gagal menerima pesan");
    }
  }

  // Periksa status WiFi dan coba reconnect jika terputus
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi connection lost, attempting to reconnect...");
    connectToWiFi();  // Coba reconnect ke WiFi
  }
}

void connectToWiFi() {
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.println("Connected to WiFi");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

void sendHTTP(String payload) {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(http_server);
    http.addHeader("Content-Type", "application/json");

    Serial.println("Mengirim data ke server Node.js (HTTP):");
    Serial.println(payload);

    int httpResponseCode = http.POST(payload);

    if (httpResponseCode > 0) {
      String response = http.getString();
      Serial.print("Response Code: ");
      Serial.println(httpResponseCode);
      Serial.print("Response: ");
      Serial.println(response);
    } else {
      Serial.print("HTTP POST gagal, kode: ");
      Serial.println(httpResponseCode);
      if (httpResponseCode == -1) {
        Serial.println("Masalah dengan koneksi HTTP. Cek URL atau firewall.");
      }
    }
    http.end();
  } else {
    Serial.println("WiFi tidak terhubung.");
  }
}

Research how to increase range of Lora. I think the world record now is a few hundred or thousand kMs so 200M seems trivial.
I am fairly certain there are more than just the spreading factor tuning settings.
I know of a project that got that kind of range when the transmitter was in a steel box. Here is a link to that project https://dronebotworkshop.com/lora/

Where did the code come from, did you write it ?

It is very unusual to be directly manipulating the LoRa device registers, libraries normally have fairly straight forward ways of setting the LoRa settings.

Go back to basics, use a library that has basic send and receive examples to prove that your LoRa modules are working correctly.

Extreme short range for LoRa devices can be an indication of damaged modules and\or faulty antenna connections.