KrisKasprzak / EBYTE

Libraries to program and use UART-based EBYTE wireless data transceivers
239 stars 75 forks source link

Multiple transmitters sending data to a single receiver #60

Closed OrlandoMoDo closed 1 year ago

OrlandoMoDo commented 1 year ago

Hi @KrisKasprzak,

I'm trying to connect multiple transmitters sending data to a single receiver, but the receiver only read a single transmitters. I use esp-32 with e32-900t20d. If you could help me that would be amazing, thanks for the work in the library.

KrisKasprzak commented 1 year ago

Hard to answer with this level of detail. Are transmitters constantly sending data? How many transmitters?

I have setup where I have 4 sensors and a single base. All are on the same channel and address. My base sends a request that all transmitters hear. The message has an ID and if the ID matches the transmitter, the transmitter sends a message back. Base receives, then sends another message with the next ID. This works for me as I'm polling sensors every few minutes.

I have another setup where 3 transmitters are sending data constantly (58 bytes every second). Here the transmitters are on different channels. The bases sets itself to the first transmitters channel, listens, process data, then sets itself to the next channel, listens/processes and so on. While data is coming in constantly, the listen/process takes a second to so, meaning "instant" updates from each transmitter is not possible.

If you are wanting to read data constantly from different transmitters and have instant updates from all, i'm not sure this is possible. Maybe add a few more modules to the base and have each listen for incoming data?

Again, i'm guessing at a suggestion.

OrlandoMoDo commented 1 year ago

I follow your second idea and I put the transmitters in different high channel and didn't work.

I put the code here, if you or somebody can help me.

include "EBYTE.h"

//Pines E32

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 4 // D4 on the board (possibly pin 24)

define PIN_M1 22 // D2 on the board (possibly called pin 22)

define PIN_AX 21 // D15 on the board (possibly called pin 21)

struct DATA { String cadena; };

int Chan; DATA MyData;

EBYTE Transceiver(&Serial2, PIN_M0, PIN_M1, PIN_AX);

void setup() { Serial.begin(9600); Serial2.begin(9600); Serial.println("Starting Reader"); Transceiver.init();

Serial.println(Transceiver.GetAirDataRate()); Serial.println(Transceiver.GetChannel()); Serial.println(Transceiver.GetTransmissionMode()); Serial.println(Transceiver.GetTransmitPower());
Transceiver.SetAirDataRate(1); // Set Air Data Rate Transceiver.SetAddressH(62); // Set Address High Transceiver.SetAddressL(0); // Set Address Low Transceiver.SetSpeed(25); // Set Speed Chan = 45; Transceiver.SetChannel(Chan); // Set Channel ( 862 MHz + ( 1MHz * Channel #)) Transceiver.SetTransmitPower(0); // Transmit Power 0 for 20 dBm

Transceiver.SaveParameters(PERMANENT); // Permanately save parameters Transceiver.PrintParameters(); }

void loop() { for(int i=0;i<8;i++){ Transceiver.SetAddressH(62+i); Transceiver.SaveParameters(PERMANENT); if (Serial2.available()) { Transceiver.GetStruct(&MyData, sizeof(MyData)); Serial.println(MyData.cadena); } delay(1000); } }

KrisKasprzak commented 1 year ago
  1. regarding the channel, the datasheet say that unit will go to 0x45 you may want to use the proper syntax--maybe you do mean decimal 45
  2. In your loop, I don't see how this could ever work. You are changing the address every second, and not waiting for incoming data, then changing the address. Unless your sender sends data at the exact instant the address is changed (and addresses match), nothing will ever be read.

I really don't think these modules are intended to have multiple senders and one listener. From what I see in the data sheet they are intended to have 1 sender multiple listeners. One of my setups has 1 listener and multiple senders, but you must send a request to a sender to send data, listen to incoming data, then move on to the next sender. I don't mess with changing channels or addresses, everything is on the same. I manage senders by and ID, send all units the same request, if requested ID matches senders ID, then that sender will react.

However, if you are expecting to read constant streams of data from multiple senders, that will take some thinking.

OrlandoMoDo commented 1 year ago

Thanks for the feedback, i change the code using ID in the transmitters, and the transmitters receive the request, but the receiver don't receive the data. I will show the code and tell me if you see somenthing weird. Thanks for everything.

Receiver:

include "EBYTE.h"

//Pin E32

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 4 // D4 on the board (possibly pin 24)

define PIN_M1 22 // D2 on the board (possibly called pin 22)

define PIN_AX 21 // D15 on the board (possibly called pin 21)

struct DATA { String cadena; };

struct NUMBER { int numero; };

int Chan; DATA MyData; NUMBER MyNumber; unsigned long Last;

EBYTE Transceiver(&Serial2, PIN_M0, PIN_M1, PIN_AX);

void setup() { Serial.begin(9600); Serial2.begin(9600); Serial.println("Starting Reader"); Transceiver.init();

Serial.println(Transceiver.GetAirDataRate()); Serial.println(Transceiver.GetChannel()); Serial.println(Transceiver.GetTransmissionMode()); Serial.println(Transceiver.GetTransmitPower());
Transceiver.SetAirDataRate(1); // Set Air Data Rate Transceiver.SetAddressH(69); // Set Address High Transceiver.SetAddressL(0); // Set Address Low Transceiver.SetSpeed(25); // Set Speed Chan = 0x35; Transceiver.SetChannel(Chan); // Set Channel ( 862 MHz + ( 1MHz * Channel #)) Transceiver.SetTransmitPower(0); // Transmit Power 0 for 20 dBm

Transceiver.SaveParameters(PERMANENT); // Permanately save parameters Transceiver.PrintParameters(); }

void loop() { for(int i=1;i<9;i++){ MyNumber.numero=i; Transceiver.SendStruct(&MyNumber, sizeof(MyNumber)); Serial.println("Send: "+String(MyNumber.numero)); Last = millis(); while((millis() - Last) > 2000){ if (Serial2.available()) { Transceiver.GetStruct(&MyData, sizeof(MyData)); Serial.println(MyData.cadena); break; } } delay(1000); } }

Transmitters:

include "EBYTE.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 4 // D4 on the board (possibly pin 24)

define PIN_M1 22 // D2 on the board (possibly called pin 22)

define PIN_AX 21 // D15 on the board (possibly called pin 21)

struct DATA { String cadena; };

struct NUMBER { int numero; };

int Chan; DATA MyData; NUMBER MyNumber; int ID;

EBYTE Transceiver(&Serial2, PIN_M0, PIN_M1, PIN_AX);

void setup() { Serial.begin(9600); Serial2.begin(9600); Serial.println("Starting Reader"); Serial.println(Transceiver.init());

Transceiver.SetAirDataRate(1); // Set Air Data Rate Transceiver.SetAddressH(69); // Set Address High Transceiver.SetAddressL(0); // Set Address Low Transceiver.SetSpeed(25); // Set Speed Chan = 0x35; Transceiver.SetChannel(Chan); // Set Channel ( 862 MHz + ( 1MHz * Channel #)) Transceiver.SetTransmitPower(0); // Transmit Power 0 for 20 dBm Transceiver.SaveParameters(PERMANENT); // Permanately save parameters Transceiver.PrintParameters(); ID=1; }

void loop() { if (Serial2.available()) { Transceiver.GetStruct(&MyNumber, sizeof(MyNumber)); Serial.println(String(MyNumber.numero)); if(ID==MyNumber.numero){ MyData.cadena="hi: I'm coming"; Transceiver.SendStruct(&MyData, sizeof(MyData)); Serial.print("Sending: "); Serial.println(MyData.cadena);
} } }

KrisKasprzak commented 1 year ago

Before you proceed are you able to get one unit talking to one unit? At a glance here are more issues I'm seeing using strings, I'm not convinced an unknown length can be recieved no use of the #define constants Transceiver.SetAirDataRate(1); is probably OK but I'd suggest using the constants Transceiver.SetAirDataRate(ADR_1200); // #define ADR_1200 0b001 // 1200 baud Sending / receiving different structs may be acceptable

but again can you get 1unit to 1unit working?

OrlandoMoDo commented 1 year ago

Yes, I can communicate 1 unit to 1 unit, and I tested the distance up to 800 meters and all ok.

KrisKasprzak commented 1 year ago

Will this ever execute? Last = millis(); while ((millis() - Last) > 2000) {

initial try is if (0-0) > 2000 then remain in loop, since 0 is not greater that 2000, I don't think you ever enter the while search loop

OrlandoMoDo commented 1 year ago

ohhh thats correct, i will update the code and i will let you know the progress.

OrlandoMoDo commented 1 year ago

I try to fix the problem, but i stay in the same problem, because when the receiver send the ID the transmitters receive the ID and enter in the if (I know that because I see print me in the terminal the phrase that i put) and supposedly send the message, but the receiver dont show any message receiver.

Transmitters:

include "EBYTE.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 4 // D4 on the board (possibly pin 24)

define PIN_M1 22 // D2 on the board (possibly called pin 22)

define PIN_AX 21 // D15 on the board (possibly called pin 21)

define ADR_1200 0b001 // 1200 baud

struct DATA { String cadena; };

struct NUMBER { int numero; };

int Chan; DATA MyData; NUMBER MyNumber; int ID;

EBYTE Transceiver(&Serial2, PIN_M0, PIN_M1, PIN_AX);

void setup() { Serial.begin(9600); Serial2.begin(9600); Serial.println("Starting Reader"); Serial.println(Transceiver.init());

Transceiver.SetAirDataRate(ADR_1200); // Set Air Data Rate Transceiver.SetAddressH(69); // Set Address High Transceiver.SetAddressL(0); // Set Address Low Transceiver.SetSpeed(25); // Set Speed Chan = 0x35; Transceiver.SetChannel(Chan); // Set Channel ( 862 MHz + ( 1MHz * Channel #)) Transceiver.SetTransmitPower(0); // Transmit Power 0 for 20 dBm Transceiver.SaveParameters(PERMANENT); // Permanately save parameters Transceiver.PrintParameters(); ID=1; }

void loop() { if (Serial2.available()) { Transceiver.GetStruct(&MyNumber, sizeof(MyNumber)); Serial.println(String(MyNumber.numero)); if(ID==MyNumber.numero){ MyData.cadena="hi: I'm coming"; Transceiver.SendStruct(&MyData, sizeof(MyData)); Serial.print("Sending: "); Serial.println(MyData.cadena); } } }

Receiver:

include "EBYTE.h"

//Pin E32

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 4 // D4 on the board (possibly pin 24)

define PIN_M1 22 // D2 on the board (possibly called pin 22)

define PIN_AX 21 // D15 on the board (possibly called pin 21)

define ADR_1200 0b001 // 1200 baud

struct DATA { String cadena; };

struct NUMBER { int numero; };

int Chan; DATA MyData; NUMBER MyNumber; unsigned long Last;

EBYTE Transceiver(&Serial2, PIN_M0, PIN_M1, PIN_AX);

void setup() { Serial.begin(9600); Serial2.begin(9600); Serial.println("Starting Reader"); Transceiver.init();

Serial.println(Transceiver.GetAirDataRate()); Serial.println(Transceiver.GetChannel()); Serial.println(Transceiver.GetTransmissionMode()); Serial.println(Transceiver.GetTransmitPower());
Transceiver.SetAirDataRate(ADR_1200); // Set Air Data Rate Transceiver.SetAddressH(69); // Set Address High Transceiver.SetAddressL(0); // Set Address Low Transceiver.SetSpeed(25); // Set Speed Chan = 0x35; Transceiver.SetChannel(Chan); // Set Channel ( 862 MHz + ( 1MHz * Channel #)) Transceiver.SetTransmitPower(0); // Transmit Power 0 for 20 dBm

Transceiver.SaveParameters(PERMANENT); // Permanately save parameters Transceiver.PrintParameters(); }

void loop() { for(int i=1;i<3;i++){ MyNumber.numero=i; Transceiver.SendStruct(&MyNumber, sizeof(MyNumber)); Serial.println("Send: "+String(MyNumber.numero)); Last = millis(); while((millis() - Last) < 2000){ if (Serial2.available()) { Transceiver.GetStruct(&MyData, sizeof(MyData)); Serial.println(MyData.cadena); break; } } delay(1000); } }

OrlandoMoDo commented 1 year ago

Anyone who cares: the code works correctly, I just had to change the pin where the aux is located and put it on a VSPI pin like GPIO 5 (on my esp32).