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); }
@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.
Anything seems possible when you don't know what you're talking about.
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); } } } } }
@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.
@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, 360, fairly knowledge in PC plus numerous MPU's & 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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
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.
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
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; }
@maheen My quick look at it sees nothing obvious, but did you see and take action on
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, 360, fairly knowledge in PC plus numerous MPU's & 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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
@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, 360, fairly knowledge in PC plus numerous MPU's & 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.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
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
@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.
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 😣
@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?