jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.49k stars 376 forks source link

SX1262 - two way communication issue #1196

Closed HeadBoffin closed 3 days ago

HeadBoffin commented 2 weeks ago

Discussed in https://github.com/jgromes/RadioLib/discussions/1195

Originally posted by **Nandhini-271** August 26, 2024 I am using the Core1262-868M module (from [Waveshare](https://www.waveshare.com/core1262-868m.htm)) with an ESP32 controller. I have successfully completed long-range LoRa testing at 1km using the `RadioLib` library in a one-way communication setup, utilizing basic transmitter and receiver code. However, when attempting two-way communication using the "PingPong" example, the transmitter sends the data packet and then switches to receiver mode after 3 seconds, while the receiver remains in listening mode. Despite not altering the LoRa key parameters or antenna position, I am unable to achieve two-way communication. Could you please provide a solution for this issue?
HeadBoffin commented 2 weeks ago

@Nandhini-271, please could you provide the serial output from both ends with a timestamp that shows seconds when they are just a few meters apart. If that's working, we can then look at the range.

Can you also confirm that you have DIO1 wired to the ESP32.

jgromes commented 2 weeks ago

I would also be very interested to see the code - especially the part that concerns the RF switching, seeing as the linked module seems to have an externally controlled switch, judging by the RXEN and TXEN pins.

HeadBoffin commented 2 weeks ago

I think we can assume that this detail bypassed the OP as well as myself - but then I didn't actually look at the module! This is a unusual for WaveShare to do something so dumb with implementation.

@Nandhini-271, it looks like you'll have to manage the switching of the radio via two more IO pins (or one with some electronics).

Nandhini-271 commented 2 weeks ago
SX1262-WaveShare Module

I'm using the module mentioned above. Could you provide information on how to utilize RF switching with the TXEN and RXEN pins? When using these pins, I am utilizing the DIO2 pin instead of DIO1. If you have any related resources or documentation, please share them. Here is my current code:

// include the library
#include <RadioLib.h>

// uncomment the following only on one
// of the nodes to initiate the pings
#define INITIATING_NODE

SX1262 radio = new Module(33, 4, 32, 13);   // NSS pin:2  DIO1 pin:12   NRST pin:35  BUSY pin:13  CLK:18  MISO:19 MOSI:23

// save transmission states between loops
int transmissionState = RADIOLIB_ERR_NONE;

// flag to indicate transmission or reception state
bool transmitFlag = false;

// flag to indicate that a packet was sent or received
volatile bool operationDone = false;

// this function is called when a complete packet
// is transmitted or received by the module
// IMPORTANT: this function MUST be 'void' type
//            and MUST NOT have any arguments!
#if defined(ESP8266) || defined(ESP32)
  ICACHE_RAM_ATTR
#endif
void setFlag(void) {
  // we sent or received a packet, set the flag
  operationDone = true;
}

void setup() {
  Serial.begin(115200);

  // initialize SX1262 with default settings
  Serial.print(F("[SX1262] Initializing ... "));
  int state = radio.begin();
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true);
  }

  // set the function that will be called
  // when new packet is received
  radio.setDio1Action(setFlag);

  #if defined(INITIATING_NODE)
    // send the first packet on this node
    Serial.print(F("[SX1262] Sending first packet ... "));
    transmissionState = radio.startTransmit("Hello World!");
    transmitFlag = true;
  #else
    // start listening for LoRa packets on this node
    Serial.print(F("[SX1262] Starting to listen ... "));
    state = radio.startReceive();
    if (state == RADIOLIB_ERR_NONE) {
      Serial.println(F("success!"));
    } else {
      Serial.print(F("failed, code "));
      Serial.println(state);
      while (true);
    }
  #endif
}

void loop() {
  // check if the previous operation finished
  if(operationDone) {
    // reset flag
    operationDone = false;

    if(transmitFlag) {
      // the previous operation was transmission, listen for response
      // print the result
      if (transmissionState == RADIOLIB_ERR_NONE) {
        // packet was successfully sent
        Serial.println(F("transmission finished!"));

      } else {
        Serial.print(F("failed, code "));
        Serial.println(transmissionState);

      }
      delay(3000);
      // listen for response
      radio.startReceive();
      transmitFlag = false;

    } else {
      // the previous operation was reception
      // print data and send another packet
      String str;
      int state = radio.readData(str);

      if (state == RADIOLIB_ERR_NONE) {
        // packet was successfully received
        Serial.println(F("[SX1262] Received packet!"));

        // print data of the packet
        Serial.print(F("[SX1262] Data:\t\t"));
        Serial.println(str);

        // print RSSI (Received Signal Strength Indicator)
        Serial.print(F("[SX1262] RSSI:\t\t"));
        Serial.print(radio.getRSSI());
        Serial.println(F(" dBm"));

        // print SNR (Signal-to-Noise Ratio)
        Serial.print(F("[SX1262] SNR:\t\t"));
        Serial.print(radio.getSNR());
        Serial.println(F(" dB"));

      }

      // wait a second before transmitting again
      delay(3000);

      // send another one
      Serial.print(F("[SX1262] Sending another packet ... "));
      transmissionState = radio.startTransmit("Hello World!");
      transmitFlag = true;
    }
  }
}

Reformatted with code <> tags for readability

HeadBoffin commented 2 weeks ago

You say you have wired DIO2 but you haven't changed the code to reflect that with the radio.setDio1Action(setFlag); line. Given what you've said so far, changing the library to suit seems unlikely to happen - so the simplest thing to do is to wire to DIO1. And consider that these things need to happen for a reason & look at the consequences - changing physical pins usually needs to be reflected in code as well!

The WaveShare wiki for the product has "RXEN, TXEN are RF single-pole switch (SPDT) pins, RXEN low level, TXE high level, SX1262 is in receiving mode, RXEN high level, TXEN low level, SX1262 is in transmitting mode.". You can use digitalWrite commands to set pins appropriately at the right points.

jgromes commented 2 weeks ago

@Nandhini-271 couple of points:

Could you provide information on how to utilize RF switching with the TXEN and RXEN pins?

Certainly - all the basic examples (e.g. SX126x_Transmit_Blocking) contain this block of text:

// some modules have an external RF switch
  // controlled via two pins (RX enable, TX enable)
  // to enable automatic control of the switch,
  // call the following method
  // RX enable:   4
  // TX enable:   5
  /*
    radio.setRfSwitchPins(4, 5);
  */

Have you tried doing this?

I am utilizing the DIO2 pin instead of DIO1

You cannot do that, and at no point the examples or the documentation of this library show that to be an option. You have to use DIO1.

jgromes commented 3 days ago

Closing due to inactivity.