Problem combining LIDAR code with GPS

Hello,

I have a problem regarding combining the code for LIDAR and GPS. The name/type of components I am using is tf-Luna for LIDAR and a neo-6M GPS module. I've tested both of the codes individually with their respective component, and it works fine. Both of them could produce readings that I want onto the serial monitor. But when I tried combining the two codes, only the data from GPS comes up and not the distance reading from the LIDAR. I've read up about SoftwareSerial and the limitations of it is that only one can receive data at a time when using multiple software serial ports. I wonder if it is related to my problem but I got confused of it instead. Is there a way to get both readings from the LIDAR and GPS to show up on serial monitor?

Here is the code:

[code]
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

TinyGPSPlus tinyGPS; 

#define GPS_BAUD 9600 
#define gpsPort ssGPS  

#define ARDUINO_GPS_RX 4 
#define ARDUINO_GPS_TX 3 
#define ARDUINO_lidar_RX 10 
#define ARDUINO_lidar_TX 11 

SoftwareSerial ssGPS(ARDUINO_GPS_TX, ARDUINO_GPS_RX); 
SoftwareSerial ssLidar(ARDUINO_lidar_RX,ARDUINO_lidar_TX);

int dist; 
int check; 
int i;
int uart[9]; 
const int HEADER=0x59; 

void setup()
{
  Serial.begin(9600);
  ssLidar.begin(115200);
  gpsPort.begin(GPS_BAUD);
}

void loop()
{
   if (ssLidar.available()) { 
    if(ssLidar.read() == HEADER) { 
     uart[0]=HEADER;
      if (ssLidar.read() == HEADER) { 
       uart[1] = HEADER;
        for (i = 2; i < 9; i++) { 
          uart[i] = ssLidar.read();
            }
          check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
            if (uart[8] == (check & 0xff)){ 
              dist = uart[2] + uart[3] * 256; 
               Serial.print("Lidar distance = "); 
               Serial.println(dist);
        }
      }
    }
   }
  
  printGPSInfo();
  smartDelay(1000); 
}

void printGPSInfo()
{
  Serial.print("Lat: "); Serial.println(tinyGPS.location.lat(), 6);
  Serial.print("Long: "); Serial.println(tinyGPS.location.lng(), 6);
  Serial.print("Alt: "); Serial.println(tinyGPS.altitude.feet());
  Serial.print("Course: "); Serial.println(tinyGPS.course.deg());
  Serial.print("Speed: "); Serial.println(tinyGPS.speed.mph());
  Serial.print("Date: "); printDate();
  Serial.print("Time: "); printTime();
  Serial.print("Sats: "); Serial.println(tinyGPS.satellites.value());
  Serial.println();
}

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

void printDate()
{
  Serial.print(tinyGPS.date.day());
  Serial.print("/");
  Serial.print(tinyGPS.date.month());
  Serial.print("/");
  Serial.println(tinyGPS.date.year());
}

void printTime()
{
  Serial.print(tinyGPS.time.hour());
  Serial.print(":");
  if (tinyGPS.time.minute() < 10) Serial.print('0');
  Serial.print(tinyGPS.time.minute());
  Serial.print(":");
  if (tinyGPS.time.second() < 10) Serial.print('0');
  Serial.println(tinyGPS.time.second());
}

[/code]

Here is the reading from the serial Monitor. Lidar distance does not show up here:
Lat: 0.000000
Long: 0.000000
Alt: 0.00
Course: 0.00
Speed: 0.00
Date: 0/0/2000
Time: 0:00:00
Sats: 0

I would put my money on this...

Get a board with 2 or more Hardware Serial ports (a MEGA for example would do if you want to be in the AVR family)

If you investigate the Lidar read() function, you will probably find that it blocks execution while it's reading. So any GPS input would be missed. That could happen even with hardware serial, as well as software serial.

You might get lucky and find that if you use the hardware serial ports, the input buffer can keep stacking characters while the other port is busy.

Very unlikely to work like that.

You can use softwareserial for two ports, but only one can receive at a time, so when your reading the Lidar GPS characters will be missed, miss just one character from the GPS and you probably wont get a fix.

You could make it work by waiting for the complete Lidar message, flipping the software serial across to the GPS and then keep reading the GPS until a position fix is reported.

Then go back to the Lidar etc.

See here for details on switching software serial between ports;

Even if you can get two software serial instances working, 115200 is too fast to be reliable.

Currently, I'm working on the examples for multiple ports in the link given. If the examples doesn't work, I'll trying getting an Arduino Mega for the multiple serial ports function because it does seem that 115200 is too fast for it to work as said by @wildbill. I tried changing the baud rate to 9600, but it doesn't display the Lidar's reading onto the Serial Monitor.

Thanks to whoever replied though! I'll try to update my work as soon as possible. I

In some other application, I found that I could ignore the GPS stream for almost a second after a message, because they only come in once per second. So I set up a timer to alternate tasks so they didn't have to contend with each other for resources.

I did some testing on how long a 2560 could wait between reading data from a GPS module. I found that more than 70 ms sometime (not always) could cause strange output - like the number of satellites was 170 or more.

But that, as I understand it, is not what I did. Not "between readings" or at any successive interval except one second. That is how often my GPS updates. I can keep track of the millisecond time after every GPS clock tick (PPS out). After it, with my module Neo-6M immediately sends NMEA data. Then it's quiet for almost a whole second. That is when you can get other work done. Actually you could adapt that to any reasonable update rate like 10 or 20.

Maybe I do more testing on this issue this weekend :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.