树莓派4B+Ubuntu24.04 电应普超声波传感器串口输出 保姆级教程
现在看到我这个结果是每100ms可以读到一个数据,实际上最开始用的时候,是差不多300ms才有一个数据,我觉得这个间隔有点大,就问厂家,厂家建议将输出方式从轮询(缺省)输出改为同时输出,可以用串口发送指令。我的程序的大框架是有一个50ms的任务,我的相关控制都在这50ms任务里完成。所以,我写一个超声波测距的独立的函数,放到50ms任务里就行了。我的机器人上要用到超声波测距,因此就选了电应普的1拖
1. 背景
我的机器人上要用到超声波测距,因此就选了电应普的1拖4的超声波测距模块。用的是UART受控输出。这个模块的使用很简单,这里做一个笔记,也是对大家的一个参考。
2. 保姆级教程
刚刚说了,这东西很简单,就是一个串口的编程。但是在时间上,有一点点要注意。
我的程序的大框架是有一个50ms的任务,我的相关控制都在这50ms任务里完成。所以,我写一个超声波测距的独立的函数,放到50ms任务里就行了。这个独立的函数,会每50ms被执行一次。
2.1 函数的头文件
#ifndef _DIS_SENSOR_H_
#define _DIS_SENSOR_H_
#include "main.h"
#include <wiringPi.h>
#include <wiringSerial.h>
typedef struct {
uint16_t dis1;
uint16_t dis2;
uint16_t dis3;
uint16_t dis4;
} dis_sensor_data_t;
uint8_t dis_sensor_init(void);
void dis_sensor_run_50ms(void);
#endif // _DIS_SENSOR_H_
2.2 函数的实现文件
#include "main.h"
#include "dis_sensor.h"
/* 超声波测距的同时工作的反应时间是70多ms */
/* 每50ms 发一次触发命令,在100ms处能读到结果,也就是每100ms读到一次结果 */
uint8_t dis_sensor_init(void)
{
const char* dis_sensor_addr = "/dev/ttyAMA2"; // use uart2
dis_sensor_data1.dis1 = 0;
dis_sensor_data1.dis2 = 0;
dis_sensor_data1.dis3 = 0;
dis_sensor_data1.dis4 = 0;
fd_dis_sensor = serialOpen(dis_sensor_addr, 9600);
if(fd_dis_sensor < 0)
{
printf("dis sensor initialize fail\n");
return 0;
}
printf("dis sensor initialize success, fd_dis_sensor=%d\n", fd_dis_sensor);
return 1;
}
void dis_sensor_run_50ms(void)
{
uint8_t trigger_command = 0x55;
uint8_t tmp_dis[10] = {0};
int data_len = 0;
int checksum = 0;
// send trigger command
serialPutchar(fd_dis_sensor, trigger_command);
// read data
data_len = serialDataAvail(fd_dis_sensor);
printf("dis sensor data length = %d\n", data_len);
if(data_len>0)
{
for(int i=0; i<10; i++)
{
tmp_dis[i] = serialGetchar(fd_dis_sensor);
printf("dis sensor data: %d, %02x\n", i, tmp_dis[i]);
}
// check checksum
for(int i=0; i<9; i++)
{
checksum += tmp_dis[i];
}
checksum = checksum & 0xFF;
if(checksum == tmp_dis[9])
{
printf("dis sensor checksum OK\n");
}
else
{
printf("dis sensor checksum error, checksum=%d, tmp_dis[9]=%d\n", checksum, tmp_dis[9]);
}
// save data
dis_sensor_data1.dis1 = tmp_dis[1]*256+tmp_dis[2];
dis_sensor_data1.dis2 = tmp_dis[3]*256+tmp_dis[4];
dis_sensor_data1.dis3 = tmp_dis[5]*256+tmp_dis[6];
dis_sensor_data1.dis4 = tmp_dis[7]*256+tmp_dis[8];
printf("dis sensor data: %dmm, %dmm, %dmm, %dmm\n", dis_sensor_data1.dis1, dis_sensor_data1.dis2, dis_sensor_data1.dis3, dis_sensor_data1.dis4);
}
}
2.3 函数的调用
void task_50ms_hook(int a ) // int a, a no used parameter
{
// for time display
printf("======task start======");
print_current_time();
// for distance sensor
dis_sensor_run_50ms();
// for time display
printf("======task end======");
print_current_time();
}
3. 结果检验


可以看到,读到距离传感器数据的间隔是100ms。
也就是1秒钟可以得到10个数据。基本可以满足机器人的判断使用。
4. 使用中的探讨
现在看到我这个结果是每100ms可以读到一个数据,实际上最开始用的时候,是差不多300ms才有一个数据,我觉得这个间隔有点大,就问厂家,厂家建议将输出方式从轮询(缺省)输出改为同时输出,可以用串口发送指令
01 06 02 16 00 01 + ModbusCRC16校验码
来进行修改。可以用sscom来修改,也可以用电应普的调试助手来修改。
5. 好了,大功告成,亲个嘴儿。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)