How to achieve full duplex transmission using esp32 and ebyte e34-2g4d20d

So I recently got a full duplex transceiver(ebyte e34-2g4d20d) but the manufacturer seem to not have an active library available for this specific device however, they do have libraries for it earlier half duplex variants. So my team and I decided to work on a library for it using it's datasheet(link to datasheet ) and libraries for it's earlier half duplex variant. we were able to get the device work with the library in half duplex mode but we are having a bit of a challenge making the device work in full duplex mode.

as per the datasheet, we have been able to set the device to full duplex mode using ESP-32, we have further tried to utilize the core feature of the esp32 by assigning Tx function of the library to execute on core 0 of and Rx to core 1 of esp32. however, when we upload and test the library and implementation code on esp 32, we observe that the transmission and reception process happening on both cores of the esp32 aren't concurrent, they seem to be interfering with each other as tx seemed to halt for rx operation and vice versa.

please note that we decided to utilize the dual core feature of the esp32 because we expect that it would be the best way to implement the utilization of a full duplex radio.

below is my code implementing the library:

#include "EBYTEZyeconnect.h"

#define PIN_RX 16   // Serial2 RX (connect this to the EBYTE Tx pin)
#define PIN_TX 17   // Serial2 TX pin (connect this to the EBYTE Rx pin)

#define PIN_M0 19    // D19 on the board (possibly pin 19)
#define PIN_M1 18   // D18 on the board (possibly called pin 18)
#define PIN_AX 5   // D5 on the board (possibly called pin 5)


// i recommend putting this code in a .h file and including it
// from both the receiver and sender modules
struct DATA {
  unsigned long Count;
  int Bits;
  float Volts;
  float Amps;
};

// these are just dummy variables, replace with your own
int Chan;
DATA MyData;
unsigned long Last;

// create the transceiver object, passing in the serial and pins
EBYTEZyeconnect Transceiver(&Serial2, PIN_M0, PIN_M1, PIN_AX);

int count=0;
void send() {
    // measure some data and save to the structure
  MyData.Count++;
  MyData.Bits = analogRead(A0);
  MyData.Volts = 3.33;
  //MyData.Volts = MyData.Bits * ( 5.0 / 1024.0 );

  // i highly suggest you send data using structures and not
  // a parsed data--i've always had a hard time getting reliable data using
  // a parsing method
  Transceiver.SendStruct(&MyData, sizeof(MyData));

    // note, you only really need this library to program these EBYTE units
    // you can call write directly on the EBYTE Serial object
    // Serial2.write((uint8_t*) &Data, PacketSize );

  // let the use know something was sent
  count++;
  Serial.print(count);
  Serial.print("===");
  Serial.print("Sending: ");
  Serial.println(MyData.Count);
  delay(8);
}


void receive() {
  // if the transceiver serial is available, proces incoming data
  // you can also use Transceiver.available()


  if (Serial2.available()) {

    // i highly suggest you send data using structures and not
    // a parsed data--i've always had a hard time getting reliable data using
    // a parsing method

    Transceiver.GetStruct(&MyData, sizeof(MyData));

    // note, you only really need this library to program these EBYTE units
    // you can call readBytes directly on the EBYTE Serial object
    // Serial2.readBytes((uint8_t*)& MyData, (uint8_t) sizeof(MyData));


    // dump out what was just received
    Serial.print("Count: "); Serial.println(MyData.Count);
    Serial.print("Bits: "); Serial.println(MyData.Bits);
    Serial.print("Volts: "); Serial.println(MyData.Volts);
    // if you got data, update the checker
    Last = millis();

  }
  else {
    // if the time checker is over some prescribed amount
    // let the user know there is no incoming data
    if ((millis() - Last) > 1000) {
      Serial.println("Searching: ");
      Last = millis();
    }
  }  
}

void codeForTask1( void * parameter ) {
  for (;;) {
    send();
  }
}

void codeForTask2( void * parameter ) {
  for (;;) {
    receive();
  }
}

TaskHandle_t Task1, Task2;

// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);
  Transceiver.init();   
  Transceiver.SetUARTBaudRate(UDR_57600);   
  Transceiver.SaveParameters(PERMANENT);
  Transceiver.PrintParameters();   


  xTaskCreatePinnedToCore(codeForTask1,"Send",5000,NULL,2,&Task1,0);
  //delay(500);  // needed to start-up task1
  xTaskCreatePinnedToCore(codeForTask2,"Receive",5000,NULL,2,&Task2,1);
}
void loop() {
}

We believe we are having this issue because of the way we designed the library or the way we we implemented it in the esp32. Any push in the right direction, maybe in recommending a full duplex transceiver library written in c would very much help.

Below is the section of our library used to set radio operating mode according to datasheet:

/*
method to set the mode (program, normal, etc.)
*/

void EBYTEZyeconnect::SetMode(uint8_t mode) {
    
    

    delay(PIN_RECOVER);
    
    if (mode == MODE_1_FULL_DUPLEX) {

        digitalWrite(_M0, HIGH);
        digitalWrite(_M1, LOW);
    }
    else if (mode == MODE_0_HALF_DUPLEX) {

        digitalWrite(_M0, LOW);
        digitalWrite(_M1, LOW);

    }
    else if (mode == MODE_2_RESERVATION_MODE) {
        digitalWrite(_M0, LOW);
        digitalWrite(_M1, HIGH);
    }
    else if (mode == MODE_3_SETTING_MODE) {
        digitalWrite(_M0, HIGH);
        digitalWrite(_M1, HIGH);
    }

    delay(PIN_RECOVER);

    ClearBuffer();

    // wait until aux pin goes back low
    CompleteTask(4000);
    
}

That module apears to use a single LoRa transceiver.

A single LoRa tranceiver is simply not capable of full duplex mode, the LoRa device can only be configured to be in transmit OR receive mode.

1 Like

From the datasheet, it clearly indicates that it is capable of doing a full duplex transmission and page 10 of the datasheet shows how to configure it for full duplex mode

Please have a look at page 10 of the datasheet with the link below:
https://www.cdebyte.com/pdf-down.aspx?id=623

The 'module' might well be able to receive UART data on the RX pin at the same time as it is transmiting UART data on the TX pin, so the data sheet is likely correct there.

But that does not mean the LoRa module itself, that does the RF stuff, is capable of 'full duplex' mode.

1 Like

This is getting me a bit confused as the datasheet doesn't make any reference to the pins or UART for transmission. and it clearly indicates a mode for half and full duplex.

As can be seen in the screenshot from the datasheet above, is says and I quote "Module can receive data in the process of transmission. Also, module can transmit data in the process of receiving."

I am already past my delivery timeline for this area of the project; while I research into your reply to know why you think so, can you please suggest any double LoRa transceiver I can use to achieve full duplex over esp32?

If you had two RF devices each with a seperate antenna a good distance apart and frequencies that are also well apart and the receiver had a highly effective notch filter, that might work.

Maybe whoever gave you the project meant you to tell them that full duplex RF comms is not possible with a single LoRa device.

1 Like

I actually thought about implementing this approach using NRF24L01 PA LNA but that would mean introducing more fragmented parts and hence a larger overall hardware size. I just wanted a single transceiver housing to simplify everything.

can you recommend any of the full duplex module with or without LoRa

I dont know of any RF modules capable of true full duplex.

Actually, I happen to be the lead tech person for my team and I've had to research most of the transceiver hardware we're getting to use in this project. and we've tried a number of transceivers beginning from nrf24l01 to NRF24L01 PA LNA, Hamshield, Adalm pluto and now ebyte E34-2G4D20D. we only decided to try implement our project using ebyte E34-2G4D20D because it promised full duplex transmission as can be seen in the aforementioned pages of the datasheet.

@srnet I appreciate your responses to my queries so far. you said

That module apears to use a single LoRa transceiver.

Did you get this observation from the datasheet or from how the device looks as it still baffles me as to why a transceiver manufacturing company like ebyte would give a false specification in their datasheet.

Stop and think a bit.

One antenna !

With the transmitter putting quite a powerful signal out on the antenna how could the receiver pick up a very weak signal from the antenna at the same time ?

This is very basic RF stuff really ......................

They want to sell modules ?

As far as the connected ESP32 goes, it does appear that there is full duplex going on. But on the RF side there is not, the microcontroller inside the module is constanly switching the LoRa RF device between RX and TX modes.

What is the application ?

With the right software the LoRa SX128x 2.4Ghz module is capable of some high speed data transfers, using RF haplf duplex of course.

so I did a little further research based on your reply and I found this:

I am mailing ebyte concerning this!
I mean they dedicated a full section in their datasheet to configuration for full duplex transmission. I want to know what they meant by the full duplex section when their physical device looks like it doesn't support it.

my application is replicating live microphone feeds on two esp32 kept apart at least 1km apart.

Let me take a look at this. thank you very much @srnet.

I do not see any mention that each core has it's own UART. Are you using totally separate UARTS?

For something like an audio stream then 2.4Ghz is probably the required choice since there are few or no legal duty cycle limits in this band, whilst in the UHF bands you can be limited to duty cycles of 10% or even 1%, so very little actual continuous data transfer is possible.

Have you done much work with RF stuff before ?

When quoting distances its vital to know the environment and location of where that 1km actually is.

Provide the location, environment, positions and heights of antennas etc and I can give you an idea of the range you might get with the 2.4Ghz LoRa devices, I have done a fair bit of distance testing, more than most really.............

@srnet Ebyte just replied and they confirmed what you said concerning e34-2g4d20d. in their response, they said it could only do time division full duplex (TDD).

I already bought over 13 pieces of their transceiver believing it was full duplex enabled; since it's confirmed that it's not full duplex enabled, I wouldn't want to waste the remaining pieces and I'd like to still proceed with it on my us case. @srnet what is your opinion on using time division duplexing (TDD) for asynchronous voice communication?

Yes, I started working with NRF24L01 in 2019, and was able to accomplish voice stream via NRF24L01 but had to discontinue usage it because of it's short range and half duplex capacity. In the course of my work, I've had to work with Hamshield (mini and normal variant), Software defined radion like Adalm pluto(Couldn't really get it to do what I want) and now, ebyte. The environment would be much of residential and rural area. As per antenna, I would say the 2.4GHz 2.2dBi Duck Antenna would be just fine for our use case.

I suspect their definition also includes what all transceivers do right now. They just do not have a fixed time clock. Will be interesting to learn if they supply any further information and their own testing results. Please keep us up to date!