Hello Everyone I am using RpLidar A1M8 from SlamTec and I followed the tutorial from "https://www.instructables.com/How-to-Use-the-RPLIDAR-360-Laser-Scanner-With-Ardu/" to set up my arudino and lidar. From this video the value of the angle and distance are consistent and sensical. However mine returns arbitrary values here is a screenshot:
I have tried multiple different baudrates and changing wires but to no avail.
Here is my code running on arduino:
#include <RPLidar.h>
#include <Encoder.h>
RPLidar lidar;
// L298N control pins
const int LEFT_MOTOR_IN1 = 0; // Direction pin 1 for left motor
const int LEFT_MOTOR_IN2 = 0; // Direction pin 2 for left motor
const int RIGHT_MOTOR_IN3 = 5; // Direction pin 1 for right motor
const int RIGHT_MOTOR_IN4 = 4; // Direction pin 2 for right motor
const int PIN_ENCOD_A_MOTOR_LEFT = 43; // A channel for encoder of left motor
const int PIN_ENCOD_B_MOTOR_LEFT = 42; // B channel for encoder of left motor
const int PIN_ENCOD_A_MOTOR_RIGHT = 52; // A channel for encoder of right motor
const int PIN_ENCOD_B_MOTOR_RIGHT = 53; // B channel for encoder of right motor
long pos_left = 0; // Left motor encoder position
long pos_right = 0; // Right motor encoder position
Encoder leftEncoder(PIN_ENCOD_A_MOTOR_LEFT, PIN_ENCOD_B_MOTOR_LEFT);
Encoder rightEncoder(PIN_ENCOD_A_MOTOR_RIGHT, PIN_ENCOD_B_MOTOR_RIGHT);
void setup() {
Serial1.begin(19200);
lidar.begin(Serial1);
lidar.startScan();
// Set up motor control pins
pinMode(LEFT_MOTOR_IN1, OUTPUT);
pinMode(LEFT_MOTOR_IN2, OUTPUT);
pinMode(RIGHT_MOTOR_IN3, OUTPUT);
pinMode(RIGHT_MOTOR_IN4, OUTPUT);
Serial.begin(19200);
// Define the rotary encoder for left motor
pinMode(PIN_ENCOD_A_MOTOR_LEFT, INPUT_PULLUP);
pinMode(PIN_ENCOD_B_MOTOR_LEFT, INPUT_PULLUP);
// Define the rotary encoder for right motor
pinMode(PIN_ENCOD_A_MOTOR_RIGHT, INPUT);
pinMode(PIN_ENCOD_B_MOTOR_RIGHT, INPUT);
}
float minDist = 100000;
float angleAtMinDist = 0;
void loop() {
getLidarResults();
pos_right = rightEncoder.read();
pos_left = leftEncoder.read();
}
void getLidarResults() {
if (IS_OK(lidar.waitPoint())) {
float distance = lidar.getCurrentPoint().distance; // distance value in mm unit
float angle = lidar.getCurrentPoint().angle; // angle value in degree
if (lidar.getCurrentPoint().startBit) {
minDist = 100000;
angleAtMinDist = 0;
} else {
if (distance > 0 && distance < minDist) {
minDist = distance;
angleAtMinDist = angle;
}
}
// Print the current distance and angle
printData(distance, angle);
delay(500);
} else {
rplidar_response_device_info_t info;
if (IS_OK(lidar.getDeviceInfo(info, 100))) {
// detected...
lidar.startScan();
delay(1000);
}
}
}
void printData(float distance, float angle) {
Serial.print("dist (meters): ");
Serial.print(distance / 1000.0); // Convert mm to meters
Serial.print(" angle: ");
Serial.println(angle);
}
Test the lidar by itself, with simple example code, and make sure it is working properly before adding other code. Arduino device libraries usually include example code for testing.
/*
* RoboPeak RPLIDAR Arduino Example
* This example shows the easy and common way to fetch data from an RPLIDAR
*
* You may freely add your application code based on this template
*
* USAGE:
* ---------------------------------
* 1. Download this sketch code to your Arduino board
* 2. Connect the RPLIDAR's serial port (RX/TX/GND) to your Arduino board (Pin 0 and Pin1)
* 3. Connect the RPLIDAR's motor ctrl pin to the Arduino board pin 3
*/
/*
* Copyright (c) 2014, RoboPeak
* All rights reserved.
* RoboPeak.com
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// This sketch code is based on the RPLIDAR driver library provided by RoboPeak
#include <RPLidar.h>
// You need to create an driver instance
RPLidar lidar;
#define RPLIDAR_MOTOR 3 // The PWM pin for control the speed of RPLIDAR's motor.
// This pin should connected with the RPLIDAR's MOTOCTRL signal
void setup() {
// bind the RPLIDAR driver to the arduino hardware serial
Serial.begin(9600);
lidar.begin(Serial1);
// set pin modes
pinMode(RPLIDAR_MOTOR, OUTPUT);
}
void loop() {
if (IS_OK(lidar.waitPoint())) {
float distance = lidar.getCurrentPoint().distance; //distance value in mm unit
float angle = lidar.getCurrentPoint().angle; //anglue value in degree
bool startBit = lidar.getCurrentPoint().startBit; //whether this point is belong to a new scan
byte quality = lidar.getCurrentPoint().quality; //quality of the current measurement
//perform data processing here...
//Serial.print(distance);
Serial.println(angle);
} else {
analogWrite(RPLIDAR_MOTOR, 0); //stop the rplidar motor
// try to detect RPLIDAR...
rplidar_response_device_info_t info;
if (IS_OK(lidar.getDeviceInfo(info, 100))) {
// detected...
lidar.startScan();
// start motor rotating at max allowed speed
analogWrite(RPLIDAR_MOTOR, 255);
delay(1000);
}
}
}
I am getting absurd angle values : 511.73
255.98
497.52
254.98
383.98
497.98
503.92
510.23
Have you contacted SlamTec for support? The device is hardly ever mentioned on this forum, so it is unlikely that any of the regulars have hands on experience with it.
The randomness in angles might be from slow sampling due to low baud rates, and delays causing many of the 8000 samples/period to be skipped as the turntable spins.
I'd modify the sample code to increase the baud rate and show the times:
/*
RoboPeak RPLIDAR Arduino Example
This example shows the easy and common way to fetch data from an RPLIDAR
You may freely add your application code based on this template
USAGE:
---------------------------------
1. Download this sketch code to your Arduino board
2. Connect the RPLIDAR's serial port (RX/TX/GND) to your Arduino board (Pin 0 and Pin1)
3. Connect the RPLIDAR's motor ctrl pin to the Arduino board pin 3
*/
/*
Copyright (c) 2014, RoboPeak
All rights reserved.
RoboPeak.com
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This sketch code is based on the RPLIDAR driver library provided by RoboPeak
#include <RPLidar.h>
// You need to create an driver instance
RPLidar lidar;
#define RPLIDAR_MOTOR 3 // The PWM pin for control the speed of RPLIDAR's motor.
// This pin should connected with the RPLIDAR's MOTOCTRL signal
void setup() {
// bind the RPLIDAR driver to the arduino hardware serial
Serial.begin(115200);
lidar.begin(Serial1);
// set pin modes
pinMode(RPLIDAR_MOTOR, OUTPUT);
}
void loop() {
if (IS_OK(lidar.waitPoint())) {
float distance = lidar.getCurrentPoint().distance; //distance value in mm unit
float angle = lidar.getCurrentPoint().angle; //anglue value in degree
bool startBit = lidar.getCurrentPoint().startBit; //whether this point is belong to a new scan
byte quality = lidar.getCurrentPoint().quality; //quality of the current measurement
//perform data processing here...
Serial.print(millis());
Serial print(" ");
Serial.print(angle);
//Serial print(" ");
//Serial.print(distance);
//Serial print(" ");
//Serial.print(distance);
Serial.println();
} else {
analogWrite(RPLIDAR_MOTOR, 0); //stop the rplidar motor
// try to detect RPLIDAR...
rplidar_response_device_info_t info;
if (IS_OK(lidar.getDeviceInfo(info, 100))) {
// detected...
lidar.startScan();
// start motor rotating at max allowed speed
analogWrite(RPLIDAR_MOTOR, 255);
delay(1000);
}
}
}
I liked the concept, but most of the documentation looks like sales literature.
Their library is 10 years old and still on the initial commit. It doesn't seem to indicate how to change to the advertised 8000, 4000, or 2000 Hz sampling. It looks like the library receives 5 bytes/sample at 115200 baud, so by default, maybe it's effectively only 2000Hz.
Never been impressed with the quality of any coding project I've seen on Instructables. You're welcome to try my port of Slamtec's drivers. It requires an ESP32 board with PSRAM. It includes an example that I tested with an A1M8. https://github.com/gfvalvo/SlamtecLidarESP32
Yes, in my limited testing. I was able to produce a crude polar graph like that displayed by the SlamTech demo GUI. I'm not a Windows app developer, so I didn't try to create the polished product they did.
What sort of sampling rates did you get? SlamTech advertises 2000-8000 Hz, but their arduino library code examples look very slow and as if it would skip lots of points.
Truthfully, it's been a while since I ported SlamTech's SDK to ESP32 and I no long have the setup assembled. I'd encourage someone to try the code from GitHub.
Who is "their"? I'm not aware of an Arduino library from SlamTech. What's being discussed in this thread is from robopeak.
The code I have on GitHub is an ESP32 port of SlamTech's multi-threaded SDK.
So, out of curiosity, I reconnected my A1M8 setup and instrumented the code to gather some statistics. First, here are the available Scan Modes supported by my unit along with some other information it reports:
Firmware Ver: 1.29
Hardware Rev: 7
Resetting
SLAMTEC Lidar health status : 0
Motor Speed Control Support: None
Avaiable Scan Modes:
Mode ID: 0, Mode Name: Standard, uS Per Sample: 508.00, Max Distance: 12.00, Answer Type: 0x81
Mode ID: 1, Mode Name: Express, uS Per Sample: 254.00, Max Distance: 12.00, Answer Type: 0x82
Mode ID: 2, Mode Name: Boost, uS Per Sample: 127.00, Max Distance: 12.00, Answer Type: 0x84
Mode ID: 3, Mode Name: Sensitivity, uS Per Sample: 127.00, Max Distance: 12.00, Answer Type: 0x84
Mode ID: 4, Mode Name: Stability, uS Per Sample: 201.00, Max Distance: 12.00, Answer Type: 0x84
The values are pretty close to what is claimed. The Scan Rate is the same for all modes. The value of 7.6 complete scans per second corresponds to 456 RPM which seems plausible.