如何用ESP32连通RPLidar激光雷达?

电子说

1.3w人已加入

描述

实验效果

凌顺实验室(lingshunlab.com)本次分享如何用ESP32连通RPLidar激光雷达(RPLidar A1 A1M8),并且通过串口输出全部角度和输出指定角度的距离两种方式,观察测量的前方障碍物的距离。

本次实验,使用ESP32,RPLidar A1 连接ESP32的串口2(Serial2),数据在串口(Serial)中输出,这样就可以方便观察数据变化。

元件说明

最大测量范围(m) 最大测量频率(Hz) 360°扫描测距 适用场景 适用电压 俯仰角度
12 8000 支持 室内 5V

RPLIDAR A1采用激光三角测距技术,配合自主研发的高速的视觉采集处理机构, 可进行每秒8000次以上的测距动作。

RPLIDAR A1 的测距核心顺时针旋转,可实现对周围环境的360度全方位扫描测距检测, 从而获得周围环境的轮廓图。

全面改进了内部光学和算法系统, 采样频率高达8000次/秒,让机器人能更快速、精确的建图。

传统的非固态激光雷达多采用滑环传输能量和数据信息,但由于存在机械磨损,其连续工作时仅有数千小时寿命。综合无线供电和光通信技术,独创性的设计了光磁融合技术彻底解决了因物理接触磨损导致电气连接失效、激光雷达寿命短的问题

可通过电机PWM信号控制雷达扫描频率

注意:型号为A1M8

引脚说明

ESP32

引脚 说明
TX RPLIDAR 测距核心串口输出
RX RPLIDAR 测距核心串口输入
VCC_5V RPLIDAR 测距核心供电
GND RPLIDAR 测距核心地线
GND_MOTO RPLIDAR 扫描电机地线
CTRL_MOTO RPLIDAR 扫描电机使能/PWM 控制信号(高电平有效)
5V_MOTO RPLIDAR 扫描电机供电

BOM表

名称 数量
ESP32 x1
RPLidar A1 360 激光扫描测距雷达 x1
面包板 x1
跳线(杜邦线) 若干

接线方式

ESP32

ESP32 引脚 <-> RPLidar A1 引脚
16 <-> TX
17 <-> RX
5V <-> VCC_5V
GND <-> GND
GND <-> GND_MOTO
14 <-> CTRL_MOTO
5V <-> 5V_MOTO

程序提点

首先,需要安装RoboPeak开发的RPlidar的Arduino库,由于在Arduino IDE的库管理中没有,所以需要手动安装。

解压后,把「RPLidarDriver」文件夹,放在Arduino IDE 的安装目录下的「libraries」文件夹中,就可以使用RPLiadar的库,如果提示找不到,请重新检查是否安装正确。

然后就可以开始编程了

加载刚安装的RPLidar库

 

// 加载RPLidar库
#include 

 

创建实例:

 

// 创建一个名为lidar的雷达驱动实例 
RPLidar lidar;

 

定义控制电机的PWM引脚:

 

#define RPLIDAR_MOTOR 3

 

绑定指定串口:

 

lidar.begin(Serial1);

 

设置控制电机的引脚为输出模式

 

pinMode(RPLIDAR_MOTOR, OUTPUT);

 

这里ESP32和Arduino 不一样,ESP32的PWM控制需要多几行代码进行定义和使用,在这次示例中,简化了这个电机的控制速度,为HIGH,LOW控制。需要ESP32 PWM控制的,可以查看相关例子,然后自己进行修改。

使用以下判断可以返回lidar是否正常工作的值

 

IS_OK(lidar.waitPoint()

 

返回当前距离值,以毫米(mm)为单位

 

float distance = lidar.getCurrentPoint().distance;

 

返回当前角度度数

 

float angle    = lidar.getCurrentPoint().angle;

 

返回该点是否属于一个新的扫描点

 

bool  startBit = lidar.getCurrentPoint().startBit;

 

返回当前测量的质量

 

byte  quality  = lidar.getCurrentPoint().quality;

 

ESP32编译RPLidar库时出现的错误

选择使用ESP32开发板程序时,在编译过程中,可能会出现如下错误:

In member function 'bool RPLidar::begin(HardwareSerial&)'

warning: no return statement in function returning non-void [-Wreturn-type]

ESP32

大概意思是RPLidar::begin()这个函数定义了是bool的返回值,但在函数里面却没有返回值。

为什么在使用Arduino 系列开发板没有提示,而在ESP系列开发板会有提示?凌顺实验室(lingshunlab.com)大概认为是,语法要求ESP系列是比较严谨一些。

这时,我们要修改一下RPLidar库的两个文件,分别是RPlidar.hdivRPlidar.cpp,把RPLidar::begin()函数的定义bool>RPlidar.cpp,把RPLidar::begin()函数的定义bool>RPlidar.cpp,把RPLidar::begin()函数的定义bool 改成 void ,定义为无返回值即可,以下图片是修改参考:

ESP32

ESP32

再次编译,错误提示消失。

程序代码

以下是完整的代码,是在RPlidar的例程simple_connect为基础,进行修改的。

 

// lingshunlab.com
// https://lingshunlab.com/book/arduino/esp32-use-rplidar-a1

// This sketch code is based on the RPLIDAR driver library provided by RoboPeak
// include library // 加载库
#include 

// 创建一个名为lidar的雷达驱动实例 
RPLidar lidar;

#define RPLIDAR_MOTOR 14  // 用于控制 RPLIDAR 电机速度。因为ESP32的PWM设置较复杂,
                          // 现在只是简单使用HIGH,LOW进行控制
                          // 该引脚应与RPLIDAR的MOTOCTRL信号相连。

// welcome to lingshunlab.com
void setup() {
  Serial.begin(115200);
  // bind the RPLIDAR driver to the arduino hardware serial
  // 将RPLIDAR驱动与ESP32 的 Serial2 硬件串口绑定。
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
  while(lidar.begin(Serial2));
  // set pin modes
  // 设置引脚模式
  pinMode(RPLIDAR_MOTOR, OUTPUT);
  delay(1000);
  // 启动雷达转动
  digitalWrite(RPLIDAR_MOTOR, HIGH);
}

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
                                                        //当前测量的质量

    //在这里进行数据处理...
    // - 1 -
    // perform data processing here...
    // Output all data in the serial port  
    //在串口中输出所有数据

    //    for(int i = 0;i < 6 - String(angle).length(); i++){
    //      Serial.print(" ");
    //    }
    //    Serial.print(String(angle));
    //    Serial.print(" | ");
    //    for(int i = 0;i < 8 - String(distance).length(); i++){
    //      Serial.print(" ");
    //    }
    //    Serial.print(distance);
    //    Serial.print(" | ");
    //    Serial.print(startBit);
    //    Serial.print(" | ");
    //    for(int i = 0;i < 2 - String(quality).length(); i++){
    //      Serial.print(" ");
    //    }
    //    Serial.println(quality);

    // - 2 - 
    // Output the specified angle data
    // 输出指定角度
    if(angle > 0 and angle < 100 ){
      Serial.print(angle);
      Serial.print(" | ");
      Serial.println(distance);
    }
  } else {
    digitalWrite(RPLIDAR_MOTOR, LOW); //stop the rplidar motor
                                   //停止rplidar马达

    // try to detect RPLIDAR...
    // 尝试检测RPLIDAR... 
    rplidar_response_device_info_t info;
    if (IS_OK(lidar.getDeviceInfo(info, 100))) {
       // detected...
       // 检测到
       lidar.startScan();

       // start motor rotating at max allowed speed
       // 启动电机以最大允许速度旋转
       digitalWrite(RPLIDAR_MOTOR, HIGH);
       delay(1000);
    }
  }
}

 

上传完成后,可以看到指定角度输出的数据。






审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分