Using Multiple Serials - WaveShare RP2040 Zero - E22 Lora Module - Adafruit Ultimate GPS

Hello, I'm currently working for my model rocket project's avionic system. I've got a problem via communication with ground station. I've got Ebyte E220-900T30D LoRa module for transmit-recieve and I've got Adafruit Ultimate GPS for my positionining. When I try to use them both my LoRa module only transmits 1 data than stops. I think it is about using multiple UART comms but I don't knod the actual problem. I don't have any other problem but as I told you I need to use GPS and LoRa module at the same time.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <LoRa_E22.h>

#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)

uint16_t BNO055_SAMPLERATE_DELAY_MS = 100;
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &Wire1);
Adafruit_BMP280 bmp;
TinyGPSPlus gps;

SoftwareSerial loraSerial(9, 8);
SoftwareSerial gpsSerial(1, 0);

LoRa_E22 e22ttl(&loraSerial);


typedef struct {
  byte baslangic = 0xff;
  float enlem;
  float boylam;
  float irtifa;
  float gpsirtifa;
  float gyrox;
  float gyroy;
  float gyroz;
  float accelx;
  float accely;
  float accelz;
  float rotx;
  float roty;
  float rotz;
  byte CRC;
  byte paketNo;
  byte son = 0xff;
} veriPaketi;

veriPaketi paket;

float gyroX, gyroY, gyroZ, accelX, accelY, accelZ, rotX, rotY, rotZ;
float enleM, boylaM, gpsirtifA;
float baslangicBasinc, irtifA;

bool bnoCheck, bmpCheck;

void setup() {
  Serial.begin(115200);
  gpsSerial.begin(9600);
  delay(500);
  e22ttl.begin();
  delay(500);
  if (!bno.begin()) {
    bnoCheck = false;
  } else {
    bnoCheck = true;
  }
  if (!bmp.begin()) {
    bmpCheck = false;
  } else {
    bmpCheck = true;
  }

  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
  baslangicBasinc = bmp.readPressure() / 100;
}


void loop() {
  veriGuncelle();
  paketle();
  loraSerial.listen();
  ResponseStatus rs = e22ttl.sendFixedMessage(0, 31, 50, &paket, sizeof(veriPaketi));
  Serial.println(rs.getResponseDescription());
  smartDelay(1000);
}

void veriGuncelle() {
  imu::Vector<3> accel = bno.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
  imu::Vector<3> gyro = bno.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
  imu::Vector<3> orient = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  accelX = accel.x();
  accelY = accel.y();
  accelZ = accel.z();

  gyroX = gyro.x();
  gyroY = gyro.y();
  gyroZ = gyro.z();

  rotX = orient.x();
  rotY = orient.y();
  rotZ = orient.z();
  //////////////////////
  irtifA = bmp.readAltitude(baslangicBasinc);
  //////////////////////
  if (gps.altitude.isValid()) {
    gpsirtifA = gps.altitude.meters();
  } else {
    gpsirtifA = 0;
  }
  if (gps.location.isValid()) {
    enleM = gps.location.lat();   
    boylaM = gps.location.lng(); 
  } else {
    enleM = 0;
    boylaM = 0;
  }
}

void paketle() {
  paket.enlem = enleM;
  paket.boylam = boylaM;
  paket.gyrox = gyroX;
  paket.gyroy = gyroY;
  paket.gyroz = gyroZ;
  paket.accelx = accelX;
  paket.accely = accelY;
  paket.accelz = accelZ;
  paket.rotx = rotX;
  paket.roty = rotY;
  paket.rotz = rotZ;
  paket.gpsirtifa = gpsirtifA;
  paket.irtifa = irtifA;
}

static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  gpsSerial.listen();
  do {
    while (gpsSerial.available()) {
      gps.encode(gpsSerial.read());
    }
  } while (millis() - start < ms);
}

Thanks for anyone replies to this topic.
RP2040 Zero Connections.

Why are you using software serial ??????

How many hardware serial ports does the RP2040 have available ?

In theory there are 2 UART Pins (UART0 and UART1). But I'm not into it.

Then you need to get 'into it'

When I try to use HWSerial, compiler gives me this error:

Compilation error: no matching function for call to 'arduino::HardwareSerial::HardwareSerial(int)'

I dont get it why I get this error while RP2040 Zero board selected in IDE.

If you can give me some resources or examples I can get into it :).

Btw thanks for replying and helping

test for RP2040 Serial1

// Raspberry Pi Pico RP2040  Serial1 test - for loopback test connect pins Rx GP1 and Tx GP0

// Note 
// Serial is the USB serial for program loading and serial mointor
// there are two hardware serial ports UART0 and UART1
//  Serial1 is mapped to UART0 on Rx pin GP1 Tx pin GP0
//  Serial2 is mapped to UART1 on Rx pin GP5 Tx pin GP4

#include <Arduino.h>

void setup() {
  // initialize both serial ports:
  delay(5000);
    Serial.begin(115200);

  Serial1.begin(115200);
  Serial.println();
  Serial.println("\n\nRaspberry Pi Pico RP2040 Serial1  test Rx pin GP1 Tx pin GP0");
  Serial.write("   for loopback test connect pin 0 to pin 1\n");
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    //Serial.write('>');
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);
    Serial1.write(inByte);
  }
}

test with RP2040 connected to an ESP32

RPi Pico serial test
RPi GP1 to ESP32 GPIO17
RPi GP0 to ESP32 GPIO16

Raspberry Pi Pico RP2040 Serial1  test Rx pin GP1 Tx pin GP0
   for loopback test connect pin 0 to pin 1
hello from ESP32
ESP32 test 1234567890

ESP32 serial1  test Rx pin 16 Tx pin 17
   for loopback test connect pin 16 to pin 17
hello from RPi Pico
RPi pico test 1234567

and Serial2 test code

// Raspberry Pi Pico RP2040  Serial2 test - for loopback test connect pins Tx GP4 and Rx GP5
#include <Arduino.h>

// Note 
// Serial is the USB serial for program loading and serial mointor
// there are two hardware serial ports UART0 and UART1
//  Serial1 is mapped to UART0 on Rx pin GP1 Tx pin GP0
//  Serial2 is mapped to UART1 on Rx pin GP5 Tx pin GP4

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  delay(2000);
  // reassign pin numbers for Serial1
  Serial2.setTX(4);   // note cannot swap pins
  Serial2.setRX(5);
  Serial2.begin(115200);
  Serial.println("\n\nRaspberry Pi Pico RP2040 serial2  test Rx pin GP5 Tx pin GP4 ");
  Serial.write("   for loopback test connect pin GP4 to pin GP5\n");
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial2.available()) {
    int inByte = Serial2.read();
    Serial.write('>');
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);
    Serial2.write(inByte);
  }
}

test both using loopback test then try connecting to the external devices

I can send my data values over my LoRa module when I'm not moving the card. But when sensor value changes Data transmission stops.

I tried to Increase delay sizes but It didn't changed anything. This is the code that's working right now (I know it is a bad code :frowning: )

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <LoRa_E22.h>

#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)

uint16_t BNO055_SAMPLERATE_DELAY_MS = 100;
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28, &Wire1);
Adafruit_BMP280 bmp;
TinyGPSPlus gps;


typedef struct {
  byte baslangic = 0xff;
  float enlem;
  float boylam;
  float irtifa;
  float gpsirtifa;
  float gyrox;
  float gyroy;
  float gyroz;
  float accelx;
  float accely;
  float accelz;
  float rotx;
  float roty;
  float rotz;
  byte CRC;
  byte paketNo;
  byte son = 0xff;
} veriPaketi;

veriPaketi paket;

float gyroX, gyroY, gyroZ, accelX, accelY, accelZ, rotX, rotY, rotZ;
float enleM, boylaM, gpsirtifA;
float baslangicBasinc, irtifA;

bool bnoCheck, bmpCheck;

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

  Serial1.begin(9600);

  Serial2.setTX(8);
  Serial2.setRX(9);
  Serial2.begin(115200);

  if (!bno.begin()) {
    bnoCheck = false;
  } else {
    bnoCheck = true;
  }
  if (!bmp.begin()) {
    bmpCheck = false;
  } else {
    bmpCheck = true;
  }

  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
  baslangicBasinc = bmp.readPressure() / 100;
}


void loop() {
  veriGuncelle();
  paketle();
  Serial2.write((byte)0x00); //Alıcı Adresi HIGH
  Serial2.write(31);       //Alıcı Adresi LOW
  Serial2.write(50);       //Alıcı Kanalı =0x17=23    (410M+23=433 MHz)
  Serial2.write((byte *)&paket, sizeof(veriPaketi));
  smartDelay(300);
  delay(200);
}

void veriGuncelle() {
  imu::Vector<3> accel = bno.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
  imu::Vector<3> gyro = bno.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
  imu::Vector<3> orient = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  accelX = accel.x();
  accelY = accel.y();
  accelZ = accel.z();

  gyroX = gyro.x();
  gyroY = gyro.y();
  gyroZ = gyro.z();

  rotX = orient.x();
  rotY = orient.y();
  rotZ = orient.z();
  //////////////////////
  irtifA = bmp.readAltitude(baslangicBasinc);
  //////////////////////
  if (gps.altitude.isValid()) {
    gpsirtifA = gps.altitude.meters();
  } else {
    gpsirtifA = 0;
  }
  if (gps.location.isValid()) {
    enleM = gps.location.lat();   
    boylaM = gps.location.lng(); 
  } else {
    enleM = 0;
    boylaM = 0;
  }
}

void paketle() {
  paket.enlem = enleM;
  paket.boylam = boylaM;
  paket.gyrox = gyroX;
  paket.gyroy = gyroY;
  paket.gyroz = gyroZ;
  paket.accelx = accelX;
  paket.accely = accelY;
  paket.accelz = accelZ;
  paket.rotx = rotX;
  paket.roty = rotY;
  paket.rotz = rotZ;
  paket.gpsirtifa = gpsirtifA;
  paket.irtifa = irtifA;
}

static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (Serial1.available()) {
      gps.encode(Serial1.read());
    }
  } while (millis() - start < ms);
}

I'm using RP2040 Zero for my microcontroller so It is not a problem to use 2 serials at the same time. I just want the transmission will not stop when Sensor values changed. (Serial1 = AdaFruit Ultimate GPS - Serial2 = E22-900T30D LoRa Module)

how do you power the LoRa module?

Via 5V input, module power is 30dBm and antenna is 6dBi.

from where? when transmitting the module likely requires up to 500mA

From my WaveShare RP2040 Zero Processor

come on - provide all the details without making this a fishing expedition...

Is your RP2040 powered trough USB ? (si likely getting 500mA total)?

While programming, yes I'm powering it from 5V IO pin (usb powered); but while using it normally, no. I'm using 8V battery - Regulator - Capacitor - 5V Output directly. I can't use 5V IO pin because while not using the usb RP2040 Zero needs to get his voltage from this pin and using 5V to power up the card

well it does not tell me if your module gets enough to power everything. I'll let you figure that out

You could try something simple to test your LoRa link

#include <LoRa_E22.h>

typedef struct {
  byte baslangic = 0xff;
  float enlem;
  float boylam;
  float irtifa;
  float gpsirtifa;
  float gyrox;
  float gyroy;
  float gyroz;
  float accelx;
  float accely;
  float accelz;
  float rotx;
  float roty;
  float rotz;
  byte CRC;
  byte paketNo;
  byte son = 0xff;
} veriPaketi;

veriPaketi paket;

void paketle() {
  paket.enlem = random(1000);
  paket.boylam = random(1000);
  paket.gyrox = random(1000);
  paket.gyroy = random(1000);
  paket.gyroz = random(1000);
  paket.accelx = random(1000);
  paket.accely = random(1000);
  paket.accelz = random(1000);
  paket.rotx = random(1000);
  paket.roty = random(1000);
  paket.rotz = random(1000);
  paket.gpsirtifa = random(1000);
  paket.irtifa = random(1000);
}

void setup() {
  Serial.begin(115200);
  Serial2.setTX(8);
  Serial2.setRX(9);
  Serial2.begin(115200);
}

void loop() {
  paketle();
  Serial2.write(0x00); //Alıcı Adresi HIGH
  Serial2.write(31);       //Alıcı Adresi LOW
  Serial2.write(50);       //Alıcı Kanalı =0x17=23    (410M+23=433 MHz)
  Serial2.write((byte *)&paket, sizeof(veriPaketi));
  delay(1000);
}

It sent for once, didn't went to loop. But I got the package

Where you trying to send LoRa too, the Moon ?

How far apart are the modules ?

In the needed use I need to use it for 7-8 km usage. It is needed to use for Model Rocket project's telemetry system. So as I told you I can use it in 22dBm for now but In practice I need to use it for 30dBm. The modules are close to each other now.

You do not need 30dBm to transmit 7-8km when you have line of sight to a rocket.

ISM band legal limits are often 10dBm for 434Mhz and 14dBm for 868Mhz.

Back in the early days of LoRa (2015) I had remote control of a tracker on a foil party balloon that was 240km away, using 10dBm.

And thats a significant limitation of the those LoRa modules with a power amplifier added, you cannot set them at legal power levels.

I can minimum use 21dBm in parameter program so I can try on 21dBm
My parameters for transmit-recieve are looking like this (Adresses are different ofc)


r

If you are talking about governmental legal limitations I'm legally authorized due to Competetion.