Notifications
Clear all

Tf luna lidar with servo motor

24 Posts
6 Users
7 Likes
1,614 Views
 ss
(@ss)
Member
Joined: 2 years 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)
Member
Joined: 3 years ago
Posts: 2508
 

Anything seems possible when you don't know what you're talking about.


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

@will

Thank you so much, Sir. 

 


   
ReplyQuote
 ss
(@ss)
Member
Joined: 2 years 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)
Member
Joined: 3 years ago
Posts: 2508
 

@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.

Anything seems possible when you don't know what you're talking about.


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6907
 

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

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 
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, WiFi 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)
Member
Joined: 2 years 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)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6907
 

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

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

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
 ss
(@ss)
Member
Joined: 2 years 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 2 years ago by ss

   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 6907
 

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

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 

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, WiFi 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)
Member
Joined: 3 years ago
Posts: 2508
 
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.

Anything seems possible when you don't know what you're talking about.


   
Ron reacted
ReplyQuote
 ss
(@ss)
Member
Joined: 2 years 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 2 years ago by ss

   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@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