Notifications
Clear all

Tf luna lidar with servo motor

24 Posts
6 Users
7 Likes
633 Views
ss
 ss
(@ss)
Active Member
Joined: 11 months ago
Posts: 14
Topic starter  

I am trying to use lidar tf luna along with servo motor but sometimes one of them or both stops working. I have been trying to do unit testing and it works fine but I am unable to use both of them together. The Servo motor is powered through external power. I would be grateful for any help, please.

 

#include <SoftwareSerial.h> //header file of software serial port
#include <Servo.h>
Servo servo;
SoftwareSerial Serial1(2,3); //define software serial port name as Serial1 and define pin2 as RX and pin3

int dist, dist2, dist3; //actual distance measurements of LiDAR
int strength; //signal strength of LiDAR
float temprature;
int check; //save check value
int i;
int uart[9]; //save data measured by LiDAR
const int HEADER=0x59; //frame header of data package

void setup() {
 Serial.begin(9600); //set bit rate of serial port connecting Arduino with computer
 Serial1.begin(115200); //set bit rate of serial port connecting LiDAR with Arduino
 servo.attach(12);
servo.write(0);
}

void loop() {
  
 if (Serial1.available()) { //check if serial port has data input
     if(Serial1.read() == HEADER) { //assess data package frame header 0x59
        uart[0]=HEADER;
        if (Serial1.read() == HEADER) { //assess data package frame header 0x59
 uart[1] = HEADER;
 for (i = 2; i < 9; i++) { //save data in array
 uart[i] = Serial1.read();
 }
 check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
 if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
 dist = uart[2] + uart[3] * 256; //calculate distance value

 Serial.print("dist1 = ");
 Serial.println(dist); //output measure distance value of LiDAR


 if(dist < 100){
  
  //Serial.println("the distance is less than 100");

  servo.write(115); // resets to initial position
  delay(1000);

  if (Serial1.available()) { //check if serial port has data input
    if(Serial1.read() == HEADER) { //assess data package frame header 0x59
      uart[0]=HEADER;
      if (Serial1.read() == HEADER) { //assess data package frame header 0x59
        uart[1] = HEADER;
        for (i = 2; i < 9; i++) { //save data in array
            uart[i] = Serial1.read();
        }
        check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
        if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
          dist2 = uart[2] + uart[3] * 256; //calculate distance value
          Serial.print("dist2: ");
          Serial.println(dist2);
          
          if(dist2 - dist < 20){
            servo.write(140); // resets to initial position
            delay(1000);
            if (Serial1.available()) { //check if serial port has data input
             if(Serial1.read() == HEADER) { //assess data package frame header 0x59
              uart[0]=HEADER;
              if (Serial1.read() == HEADER) { //assess data package frame header 0x59
                uart[1] = HEADER;
                for (i = 2; i < 9; i++) { //save data in array
                  uart[i] = Serial1.read();
                }
                check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
                if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
                  dist3 = uart[2] + uart[3] * 256; //calculate distance value
                  Serial.print("dist3 = ");
                  Serial.println(dist3);

                  if(dist3- dist2 < 20){
                    Serial.println("Staircase detected");
                  }
                  
                }
              }
             }
          }
        }
          
        }
      }
    }
  }
  
 }
 if(dist > 50){
//  Serial.print(dist);
  Serial.println("the distance is more than 50");
 }
 delay(1000);
 
 }
 }
 }
 }
 servo.write(0); // resets to initial position
 delay(1000);
}

   
Quote
Will
 Will
(@will)
Noble Member
Joined: 1 year ago
Posts: 2112
 

@maheen

It's very difficult to answer your question because it's not clear what you mean by "stops working". That is, does it freeze in place, stop reading distances, stop moving the servo, moving the servo to the wrong place or some or all of the above.

Since you've chosen to write your code as a single block of nested if statements, the failure of any test will simply drop out of the loop and could appear to make it look like it "stops working". You should insert "else" statements for each test to specify what specific part of the process broke. Then you can start to analyze what's going on.

I would also recommend that you extract all of the code which reads the data from the LIDAR to a separate function. Since you don't seem to be using anything but the distance reading, perhaps something like (untested code follows)

 

//
//      Use LIDAR to determine distance to object
//
int readLIDAR()
{
    int distance=-1, uart[9];                               // Distance and LIDAR buffer
    //
    if (!Serial1.available()) {
        Serial.println("LIDAR not available");              // No data avaialble
        return distance;
    }
    //
    if (Serial1.read() != HEADER) {
        Serial.println("  LIDAR buffer first character is not HEADER");
        return distance;
    }
    uart[0] = HEADER;
    //
    if (Serial1.read() != HEADER) {
        Serial.println("  LIDAR buffer second character is not HEADER");
        return distance;
    }
    uart[1] = HEADER;
    //
    //      Read rest of buffer
    //
    for (int i = 2; i < 9; i++)
        uart[i] = Serial1.read();
    //
    //      Form and verify check byte
    //
    int check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
    if (uart[8] != (check & 0xff)) { //verify the received data as per protocol
        Serial.println("  LIDAR buffer check does not match");
        return distance;
    }
    //
    //      Everything is OK, calculate and return the distance
    //
    distance = uart[2] + uart[3] * 256; //calculate distance value
    Serial.print("  distance = ");
    Serial.println(distance);
    //
    return distance;
}

 

 This function, when called, will read the LIDAR device and return the distance calculated. Note that if there is no LIDAR data or any fault occurs during the read, then the value returned will be -1 (obviously a bogus value) so you'll be able to tell if the operation succeeded. Also this function explains why a distance could not be evaluated in case of failure.

I can't comment on the operation of the sketch because I don't understand what it's doing, but I hope this may give you a start on fixing it.

 

 

I was kidnapped by mimes.
They did unspeakable things to me.


   
Ron, Inst-Tech and Inq reacted
ReplyQuote
ss
 ss
(@ss)
Active Member
Joined: 11 months ago
Posts: 14
Topic starter  

@will

Thank you so much, Sir. 

 


   
ReplyQuote
ss
 ss
(@ss)
Active Member
Joined: 11 months ago
Posts: 14
Topic starter  

When I try to implement it along with the servo motor, I do not get updated distance values; same values keep on repeating for a long time. What do you think might be the problem?

 

void loop() {
  
  lidar();
  
  servo.write(0);
  delay(1000);
  
  servo.write(90); // resets to initial position
  delay(1000);
  
  servo.write(180); // resets to initial position
  delay(1000);
  
  // Serial.0print(dist);
  servo.write(90); // resets to initial position
  delay(1000);
  
}


void lidar(){
  if (Serial1.available()) { //check if serial port has data input
     if(Serial1.read() == HEADER) { //assess data package frame header 0x59
      uart[0]=HEADER;
      if (Serial1.read() == HEADER) { //assess data package frame header 0x59
        uart[1] = HEADER;
        for (i = 2; i < 9; i++) { //save data in array
          uart[i] = Serial1.read();
        }
      check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
      if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
        dist = uart[2] + uart[3] * 256; //calculate distance value

        Serial.print("dist = ");
        Serial.print(dist);       

      }
      }
    }
  }

}

   
ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 1 year ago
Posts: 2112
 

@maheen 

You issue multiple tests to decide if you have a viable result from the lidar sensor. And you just drop out of your distance function if any of them fail.

My guess is that one or more of your tests fails and so the function drops out silently, the distance is never updated and, since you don't report any errors, you fail to see why it failed.

I was kidnapped by mimes.
They did unspeakable things to me.


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3403
 

@maheen Your code is missing things and is incomplete. Maybe try posting the sketch that you have successfully compiled.

"Don't tell people how to do things. Tell them what to do and let them surprise you with their results.” - G.S. Patton, Gen. USA
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon


   
ReplyQuote
Inq
 Inq
(@inq)
Noble Member
Joined: 8 months ago
Posts: 959
 
Posted by: @maheen

When I try to implement it along with the servo motor, I do not get updated distance values; same values keep on repeating for a long time. What do you think might be the problem?

I'm using a Time of Flight sensor that uses infrared like Lidar.  I did some testing and it behaved just as you described when I had a halogen or incandescent light on in the room.  Check this post out.  It has a video at the bottom showing the behavior I experienced.  It works fine in a dark or if the room was lit with LED's.  I suspect it would also work with fluorescent lighting.  But I'd bet sunlight would completely make it misbehave.  See if this might be your problem.  

https://forum.dronebotworkshop.com/user-robot-projects/inqling-junior-robot-mapping-vision-autonomy/paged/3/#post-31051

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, Access Point Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
ss
 ss
(@ss)
Active Member
Joined: 11 months ago
Posts: 14
Topic starter  

@zander

Here is the updated code:

#include <Servo.h>
Servo servo;
#include <SoftwareSerial.h> //header file of software serial port
SoftwareSerial Serial1(2,3); //define software serial port name as Serial1 and define pin2 as RX and pin3
int sound = 250;
String message = "";
String output1;
int distanceR;
int distanceL;
int distance, dist;
int buzzer = 10;
long duration;
int i;
int uart[9]; //save data measured by LiDAR
const int HEADER=0x59; //frame header of data package
int check, dist1;

void setup() {

  Serial.begin (9600);
  Serial1.begin(115200); //set bit rate of serial port connecting LiDAR with Arduino
  servo.attach(12);
}


void loop() {
  

  dist1 = readLIDAR();
  Serial.print("dist1: ");
  Serial.println(dist1);

  
  servo.write(0);
  delay(1000);
  
  servo.write(90); // resets to initial position
  delay(1000);
  
  servo.write(180); // resets to initial position
  delay(1000);
  

  servo.write(90); // resets to initial position
  delay(1000);
  
}




int readLIDAR()
{
    int distance=-1, uart[9];                               // Distance and LIDAR buffer
    //
    if (!Serial1.available()) {
        Serial.println("LIDAR not available");              // No data avaialble
        return distance;
    }
    //
    if (Serial1.read() != HEADER) {
        Serial.println("  LIDAR buffer first character is not HEADER");
        return distance;
    }
    uart[0] = HEADER;
    //
    if (Serial1.read() != HEADER) {
        Serial.println("  LIDAR buffer second character is not HEADER");
        return distance;
    }
    uart[1] = HEADER;
    //
    //      Read rest of buffer
    //
    for (int i = 2; i < 9; i++)
        uart[i] = Serial1.read();
    //
    //      Form and verify check byte
    //
    int check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
    if (uart[8] != (check & 0xff)) { //verify the received data as per protocol
        Serial.println("  LIDAR buffer check does not match");
        return distance;
    }
    //
    //      Everything is OK, calculate and return the distance
    //
    distance = uart[2] + uart[3] * 256; //calculate distance value
    Serial.print("  distance = ");
    Serial.println(distance);
    //
    return distance;
}

void lidar(){
  if (Serial1.available()) { //check if serial port has data input
     if(Serial1.read() == HEADER) { //assess data package frame header 0x59
      uart[0]=HEADER;
      if (Serial1.read() == HEADER) { //assess data package frame header 0x59
        uart[1] = HEADER;
        for (i = 2; i < 9; i++) { //save data in array
          uart[i] = Serial1.read();
        }
      check = uart[0] + uart[1] + uart[2] + uart[3] + uart[4] + uart[5] + uart[6] + uart[7];
      if (uart[8] == (check & 0xff)){ //verify the received data as per protocol
        dist = uart[2] + uart[3] * 256; //calculate distance value

        Serial.print("dist = ");
        Serial.println(dist); //output measure distance value of LiDAR
        //Serial.print('\t');

        //delay(100);
       // return dist;
      }
      }
    }
  }
  //return 0;
}

   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3403
 

@maheen My quick look at it sees nothing obvious, but did you see and take action on 

https://forum.dronebotworkshop.com/postid/31184/

"Don't tell people how to do things. Tell them what to do and let them surprise you with their results.” - G.S. Patton, Gen. USA
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon


   
ReplyQuote
ss
 ss
(@ss)
Active Member
Joined: 11 months ago
Posts: 14
Topic starter  

@inq @zander Only when I use it with the servo motor, I do get this issue. When the lidar sensor is used separately, the values get updated without a problem. I also tried turning off the light while experimenting

This post was modified 5 months ago by ss

   
ReplyQuote
Ron
 Ron
(@zander)
Famed Member
Joined: 2 years ago
Posts: 3403
 

@maheen I see you print the distance once in readLIDAR and once in the main loop. Are they the same value?

"Don't tell people how to do things. Tell them what to do and let them surprise you with their results.” - G.S. Patton, Gen. USA
"Never wrestle with a pig....the pig loves it and you end up covered in mud..." anon


   
ReplyQuote
Inq
 Inq
(@inq)
Noble Member
Joined: 8 months ago
Posts: 959
 

I didn't see where you mentioned what you're running on.  Some micros share hardware timers on certain groups of pins.  You can't do certain combinations of things that are trying to access the same timer.  IOW, your pin 12 being used for your servo may be sharing the same hardware timer as your software serial port you're using for the Lidar.  Both will be hitting the timer pretty hard.  The servo could very easily be starving the serial port as it has to send out pulses even when the servo is not being moved.

I primarily use ESP8266 and they have only two hardware timers.  My ToF sensor uses I2C, so I don't have any experience with Arduino and their timers or your serial interfaced sensor.

You'll need to verify your micro's capabilities.  

VBR,

Inq

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, Access Point Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 1 year ago
Posts: 2112
 
Posted by: @maheen

@inq @zander Only when I use it with the servo motor, I do get this issue. When the lidar sensor is used separately, the values get updated without a problem. I also tried turning off the light while experimenting

If you're driving the servo from the +5V of your microprocessor, it's possible that you're dragging the voltage low enough to interfere with the computer. Try using a separate 5V supply for the servo so that it's getting its power from a different source.

Remember that you'll need to have a common ground, so you'll need to connect the external GND to the Arduino GND.

I was kidnapped by mimes.
They did unspeakable things to me.


   
Ron reacted
ReplyQuote
ss
 ss
(@ss)
Active Member
Joined: 11 months ago
Posts: 14
Topic starter  

@will 

I am using external power for the servo motor and I am unable to come up with any solution 🙁

I am using a tf luna lidar in order to detect obstacles after each rotation of the servo motor

I tried the same thing with the ultrasonic sensor and it works fine with a servo motor.

Is it possible for anyone to test it on their side? It's a bit urgent 😣 

This post was modified 5 months ago by ss

   
ReplyQuote
robotBuilder
(@robotbuilder)
Noble Member
Joined: 3 years ago
Posts: 1554
 

@maheen 

Have you searched for answers else where? I have no LIDAR or experience with whatever you are trying to do so can't be any direct help. I read here that "using external power through breadboard for the servo motor" is "That's No, No, unless You want trouble."
https://forum.arduino.cc/t/tf-luna-lidar-with-servo-motor/1008721
Are you trying to do this?
https://courses.engr.illinois.edu/ece445/getfile.asp?id=18910

What is your source for the project?

 

 


   
ReplyQuote
Page 1 / 2