Using multiple Lidar sensors at the same time

Hello, I'm working on a safety project and I've been tasked with using an arduino uno to make a speed radar system (similar to one you would see in a school zone). I am using two large 7 segment displays, a TF-MiniS, and a TF-Mini Plus lidar sensor. The goal is for the lidar sensor to detect vehicle movement inside a factory, and convert the distance measurements into speed (mph), and display the speed on the 7 segment displays. I have it working with one lidar sensor, (and both work separately) but the field of view is not wide enough on either one alone for it to observe the entire aisle vehicles move through. The issue is when I hook up both sensors at the same time, I only get an output of 0 regardless of if there is movement in front of the sensors or not. I will paste two codes below to show how I've been attempting to address the problem. (I am not a coding professional, please take that into account before attacking me lol) TIA

This is the code I used for the sensor individually that ideally I'll get to work on both

#include <SoftwareSerial.h>

SoftwareSerial tfminiSerial(2, 3); // RX, TX pins

#define LOOPTIME 300

int lastDistance = 0;
long lastReading = 0;

const int maxMPH_remember = 5000; // After this number of ms the system will forget the max speed
const float speedThreshold = 1.0;  // Threshold speed in mph

// GPIO declarations for 7-segment display
byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;

// Define segments for 7-segment display
#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

void setup() {
 Serial.begin(9600);         //set bit rate of serial port connecting Arduino with computer
 tfminiSerial.begin(115200); //set bit rate of serial port connecting TFMini with Arduino

 pinMode(segmentClock, OUTPUT);
 pinMode(segmentData, OUTPUT);
 pinMode(segmentLatch, OUTPUT);

 digitalWrite(segmentClock, LOW);
 digitalWrite(segmentData, LOW);
 digitalWrite(segmentLatch, LOW);
}

void loop() {
 if (tfminiSerial.available() >= 9) {
   if (tfminiSerial.read() == 0x59) {
     if (tfminiSerial.read() == 0x59) {
       int distance = tfminiSerial.read() + tfminiSerial.read() * 256; // Read distance data from TFMini
       int strength = tfminiSerial.read() + tfminiSerial.read() * 256; // Read signal strength data from TFMini
       int reserved = tfminiSerial.read() + tfminiSerial.read() * 256; // Read reserved data from TFMini

       if (distance != 0 && distance != 65535) { // Check if valid distance data
         unsigned long currentMillis = millis();

         if (currentMillis - lastReading >= LOOPTIME) {
           int deltaDistance = lastDistance - distance;
           if (abs(deltaDistance) <= 150) { // Check for jump less than or equal to 150 cm
             lastDistance = distance; // Update lastDistance if the jump is within the limit

             float timeSeconds = (float)LOOPTIME / 1000; // Convert LOOPTIME to seconds
             float velocity = (float)abs(deltaDistance) / timeSeconds; // Calculate velocity in cm/s

             // Convert velocity from cm/s to mph
             float speedMPH = velocity * 0.0223694;

             // Apply max speed limit
             if (speedMPH > 10.0) {
               speedMPH = 10.0;
             }

             // Round up speed to the next highest integer
             int roundedSpeed = (int)ceil(speedMPH);

             // Apply threshold check
             if (speedMPH < speedThreshold) {
               roundedSpeed = 0; // Set speed to zero if below threshold
             }

             // Output speed
             Serial.print("Velocity = ");
             Serial.print(roundedSpeed); // Output rounded speed
             Serial.println(" Miles Per Hour");

             // Display speed on 7-segment display
             showSpeedOnDisplay(roundedSpeed);

             lastReading = currentMillis; // Update lastReading
           } else {
             // Ignore the measurement and keep the new distance for future calculations
             lastDistance = distance;
           }
         }
       }
     }
   }
 }

 // Check if there are no new measurements for 5 seconds
 if (millis() - lastReading > maxMPH_remember) {
   lastDistance = 0;
 }
}


// Display speed on 7-segment display
void showSpeedOnDisplay(int speed) {
 int number = speed;

 for (byte x = 0 ; x < 2 ; x++) {
   int remainder = number % 10;
   // Flash dp segment if speed exceeds 7 mph
   bool flashDP = (speed > 5);
   postNumber(remainder, false, flashDP);
   number /= 10;
 }

 //Latch the current segment data
 digitalWrite(segmentLatch, LOW);
 digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

// Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal, bool flashDP) {
 byte segments;

 switch (number) {
   case 1: segments = b | c; break;
   case 2: segments = a | b | d | e | g; break;
   case 3: segments = a | b | c | d | g; break;
   case 4: segments = f | g | b | c; break;
   case 5: segments = a | f | g | c | d; break;
   case 6: segments = a | f | g | e | c | d; break;
   case 7: segments = a | b | c; break;
   case 8: segments = a | b | c | d | e | f | g; break;
   case 9: segments = a | b | c | d | f | g; break;
   case 0: segments = a | b | c | d | e | f; break;
   case ' ': segments = 0; break;
   case 'c': segments = g | e | d; break;
   case '-': segments = g; break;
 }

 if (decimal) segments |= dp;

 // Flash dp segment if required
 if (flashDP && number != '-' && number != ' ') {
   segments |= dp; // Set dp segment
 }

 //Clock these bits out to the drivers
 for (byte x = 0 ; x < 8 ; x++) {
   digitalWrite(segmentClock, LOW);
   digitalWrite(segmentData, segments & 1 << (7 - x));
   digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
 }
}

This is one of the codes I tried for both that was unsuccessful

#include <SoftwareSerial.h>

SoftwareSerial tfminiSerial(2, 3);        // RX, TX pins for TFMini
SoftwareSerial tfminiPlusSerial(10, 11);    // RX, TX pins for TFMini Plus

#define LOOPTIME 300

int lastDistance = 0;
int lastDistancePlus = 0;
long lastReading = 0;

const int maxMPH_remember = 5000; // After this number of ms the system will forget the max speed
const float speedThreshold = 1.0;  // Threshold speed in mph

// GPIO declarations for 7-segment display
byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;

// Define segments for 7-segment display
#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

void setup() {
  Serial.begin(9600);                 // Set bit rate of serial port connecting Arduino with computer
  tfminiSerial.begin(115200);         // Set bit rate of serial port connecting TFMini with Arduino
  tfminiPlusSerial.begin(115200);     // Set bit rate of serial port connecting TFMini Plus with Arduino

  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);
}

void loop() {
  readTFMini(tfminiSerial, lastDistance);
  readTFMini(tfminiPlusSerial, lastDistancePlus);

  // Calculate average distance
  int avgDistance = (lastDistance + lastDistancePlus) / 2;

  // Proceed only if both readings are valid
  if (lastDistance != 0 && lastDistance != 65535 && lastDistancePlus != 0 && lastDistancePlus != 65535) {
    unsigned long currentMillis = millis();

    if (currentMillis - lastReading >= LOOPTIME) {
      int deltaDistance = abs(lastDistance - lastDistancePlus);
      if (deltaDistance <= 150) { // Check for jump less than or equal to 150 cm

        float timeSeconds = (float)LOOPTIME / 1000; // Convert LOOPTIME to seconds
        float velocity = (float)deltaDistance / timeSeconds; // Calculate velocity in cm/s

        // Convert velocity from cm/s to mph
        float speedMPH = velocity * 0.0223694;

        // Apply max speed limit
        if (speedMPH > 10.0) {
          speedMPH = 10.0;
        }

        // Round up speed to the next highest integer
        int roundedSpeed = (int)ceil(speedMPH);

        // Apply threshold check
        if (speedMPH < speedThreshold) {
          roundedSpeed = 0; // Set speed to zero if below threshold
        }

        // Output speed
        Serial.print("Velocity = ");
        Serial.print(roundedSpeed); // Output rounded speed
        Serial.println(" Miles Per Hour");

        // Display speed on 7-segment display
        showSpeedOnDisplay(roundedSpeed);

        lastReading = currentMillis; // Update lastReading
      }
    }
  }

  // Check if there are no new measurements for 5 seconds
  if (millis() - lastReading > maxMPH_remember) {
    lastDistance = 0;
    lastDistancePlus = 0;
  }
}

// Read data from TFMini sensor
void readTFMini(SoftwareSerial& serial, int& lastDistance) {
  if (serial.available() >= 9) {
    if (serial.read() == 0x59) {
      if (serial.read() == 0x59) {
        int distance = serial.read() + serial.read() * 256; // Read distance data from TFMini
        int strength = serial.read() + serial.read() * 256; // Read signal strength data from TFMini
        int reserved = serial.read() + serial.read() * 256; // Read reserved data from TFMini

        if (distance != 0 && distance != 65535) { // Check if valid distance data
          lastDistance = distance; // Update lastDistance
        }
      }
    }
  }
}

// Display speed on 7-segment display
void showSpeedOnDisplay(int speed) {
  int number = speed;

  for (byte x = 0; x < 2; x++) {
    int remainder = number % 10;
    // Flash dp segment if speed exceeds 7 mph
    bool flashDP = (speed > 5);
    postNumber(remainder, false, flashDP);
    number /= 10;
  }

  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

// Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal, bool flashDP) {
  byte segments;

  switch (number) {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  // Flash dp segment if required
  if (flashDP && number != '-' && number != ' ') {
    segments |= dp; // Set dp segment
  }

  //Clock these bits out to the drivers
  for (byte x = 0; x < 8; x++) {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}

the SoftwareSerial documentation states

  1. If using multiple software serial ports, only one can receive data at a time.
  2. On Arduino or Genuino 101 boards the current maximum RX speed is 57600bps.

you are attempting to operate two SoftwareSerial instances at 115200baud concurrently

I suggest you move to a Microcontroller with multiple spare hardware serial ports, e.g. Arduino Mega, ESP32, etc

So could I have it alternate readings from each of them one at a time?
Or use one sensor with software serial and one sensor in the 0,1 ports since they're labeled rx and tx?
If I have to use a different microcontroller I can do that, but I'd rather try other ways for this to work before going another route.

If the fields of view overlap, I would imagine one would interfer with the other.

They're both so small I don't think they will, one is 2.3 degrees and the other is 3.6 degrees.

It isn't clear from the data sheet if the FOV was the same for both the transmiter and receiver but I guess you will find out.
If you read the documentation for software serial you will see how to alternately use 2 ports

Not if you intend to use Serial.print() for anything else.

Software Serial rarely works at 115200 Baud. If it has so far, you are quite lucky.

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