PX4固件通过UART连接串口读取超声波,和树莓派3通信(似乎讲了怎么添加驱动程序,添加自定义msg,还有uORB消息订阅,佩服,感觉做了我想做的!)

本文主要是介绍PX4固件通过UART连接串口读取超声波,和树莓派3通信(似乎讲了怎么添加驱动程序,添加自定义msg,还有uORB消息订阅,佩服,感觉做了我想做的!),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:https://blog.csdn.net/qq_28773183/article/details/78137434

PX4固件通过UART连接串口读取超声波树莓派3通信

勤奋比天赋更重要 2017-09-29 21:12:08 2686 收藏 12

分类专栏: PX4研究笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接本声明。

本文链接:https://blog.csdn.net/qq_28773183/article/details/78137434

版权

PX4研究笔记 专栏收录该内容

13 篇文章 0 订阅

订阅专栏

添加串口读取程序

首先在Firmware/msg文件夹下添加rw_uart.msg

char[5] datastr
int16 data
#TOPICS rw_uart

记住在这一文件夹下的CMakeLists.txt下注册这个msg,添加rw_uart.msg即可。
这里写图片描述
上面的文件make之后会自动产生rw_uart.h头文件,里面会有结构体rw_uart_s,存取了我们刚才定义的datadatastr。然后在Firmware/src/module文件夹下新建文件夹rw_uart,在里面添加CMakeLists.txtrw_uart.c。
CMakeLists.txt内容如下:

set(MODULE_CFLAGS)
px4_add_module(MODULE modules__rw_uartMAIN rw_uartCOMPILE_FLAGS-OsSRCSrw_uart.cDEPENDSplatforms__common)

读取程序rw_uart.c如下:

#include <px4_config.h>
#include <px4_tasks.h>
#include <px4_posix.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <uORB/uORB.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <drivers/drv_hrt.h>
#include <string.h>
#include <systemlib/err.h>
#include <systemlib/systemlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <uORB/topics/rw_uart.h>static bool thread_should_exit = false;
static bool thread_running = false;
static int daemon_task;__EXPORT int rw_uart_main(int argc, char *argv[]);
int rw_uart_thread_main(int argc, char *argv[]);static int uart_init(const char * uart_name);
static int set_uart_baudrate(const int fd, unsigned int baud);
static void usage(const char *reason);int set_uart_baudrate(const int fd, unsigned int baud)//自动选取波特率
{int speed;switch (baud) {case 9600:   speed = B9600;   break;case 19200:  speed = B19200;  break;case 38400:  speed = B38400;  break;case 57600:  speed = B57600;  break;case 115200: speed = B115200; break;default:warnx("ERR: baudrate: %d\n", baud);return -EINVAL;}struct termios uart_config;/**
/*termios 函数族提供了一个常规的终端接口,用于控制非同步通信端口。 这个结构包含了至少下列成员:
/*tcflag_t c_iflag;      /* 输入模式 */
/*tcflag_t c_oflag;      /* 输出模式 */
/*tcflag_t c_cflag;      /* 控制模式 */
/*tcflag_t c_lflag;      /* 本地模式 */
/*cc_t c_cc[NCCS];       /* 控制字符 */
*/int termios_state;/* fill the struct for the new configuration */tcgetattr(fd, &uart_config);/* clear ONLCR flag (which appends a CR for every LF) */uart_config.c_oflag &= ~ONLCR;/* no parity, one stop bit */uart_config.c_cflag &= ~(CSTOPB | PARENB);/* set baud rate */if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) {warnx("ERR: %d (cfsetispeed)\n", termios_state);return false;}if ((termios_state = cfsetospeed(&uart_config, speed)) < 0) {warnx("ERR: %d (cfsetospeed)\n", termios_state);return false;}if ((termios_state = tcsetattr(fd, TCSANOW, &uart_config)) < 0) {warnx("ERR: %d (tcsetattr)\n", termios_state);return false;}return true;
}int uart_init(const char * uart_name)
{int serial_fd = open(uart_name, O_RDWR | O_NOCTTY);if (serial_fd < 0) {err(1, "failed to open port: %s", uart_name);return false;}return serial_fd;
}static void usage(const char *reason)
{if (reason) {fprintf(stderr, "%s\n", reason);}fprintf(stderr, "usage: position_estimator_inav {start|stop|status} [param]\n\n");exit(1);
}int rw_uart_main(int argc, char *argv[])
{if (argc < 2) {usage("[FC]missing command");}if (!strcmp(argv[1], "start")) {if (thread_running) {warnx("[FC]already running\n");exit(0);}thread_should_exit = false;daemon_task = px4_task_spawn_cmd("rw_uart",//任务接口句柄SCHED_DEFAULT,SCHED_PRIORITY_MAX - 5,2000,rw_uart_thread_main,(argv) ? (char * const *)&argv[2] : (char * const *)NULL);exit(0);}if (!strcmp(argv[1], "stop")) {thread_should_exit = true;exit(0);}if (!strcmp(argv[1], "status")) {if (thread_running) {warnx("[FC]running");} else {warnx("[FC]stopped");}exit(0);}usage("unrecognized command");exit(1);
}int rw_uart_thread_main(int argc, char *argv[])
{if (argc < 2) {errx(1, "[FC]need a serial port name as argument");usage("eg:");}const char *uart_name = argv[1];warnx("[FC]opening port %s", uart_name);char data = '0';char buffer[5] = "";/** TELEM1 : /dev/ttyS1* TELEM2 : /dev/ttyS2* GPS    : /dev/ttyS3* NSH    : /dev/ttyS5* SERIAL4: /dev/ttyS6* N/A    : /dev/ttyS4* IO DEBUG (RX only):/dev/ttyS0*/int uart_read = uart_init(uart_name);if(false == uart_read)return -1;if(false == set_uart_baudrate(uart_read,9600)){printf("[FC]set_uart_baudrate is failed\n");return -1;}printf("[FC]uart init is successful\n");thread_running = true;/*初始化数据结构体 */struct rw_uart_s sonardata;memset(&sonardata, 0, sizeof(sonardata));/* 公告主题 */orb_advert_t rw_uart_pub = orb_advertise(ORB_ID(rw_uart), &sonardata);while(!thread_should_exit){read(uart_read,&data,1);if(data == 'R'){//这个地方是模拟树莓派发送的R1100数据,在超声波处注释掉这个if条件语句,直接读取for(int i = 0;i <4;++i){read(uart_read,&data,1);buffer[i] = data;//data = '0';}// printf("%s\n",buffer);strncpy(sonardata.datastr,buffer,4);sonardata.data = atoi(sonardata.datastr);// printf("[YCM]sonar.data=%s\n",sonardata.datastr);orb_publish(ORB_ID(rw_uart), rw_uart_pub, &sonardata);}}warnx("[FC]exiting");thread_running = false;close(uart_read);fflush(stdout);return 0;
}

超声波px4的硬件连接

首先说一下,这里用的是pixhawk的TELEM2口,TELEM1接口给的是数传。TELEM1TELEM2接口是一样的,分布如下:
这里写图片描述
对于UART主要是TX,RX,VCC,GND这四个接口,这里面我用的是HC-SRO4超声波传感器,这个传感器给的是触发信号,并没有直接给出距离,需要自己通过计时器来获得距离,这个找度娘就可以了,这里验证的是能读到数据。TELEM2超声波的连接方式:VCC-VCC,TX-RX,RX-TX,GND-GND,这里我的超声波的连接是:TX-Trigger,RX-Echo。最后的结果如下:
这里写图片描述
这里我使用的是数据订阅的方式——uORB通信机制
在Firmware/src/examples/px4_simple_app文件夹下,修改px4_simple_app.c如下:

/******************************************************************************   Copyright (c) 2012-2015 PX4 Development Team. All rights reserved.** 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.* 3. Neither the name PX4 nor the names of its contributors may be*    used to endorse or promote products derived from this software*    without specific prior written permission.** 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 OWNER 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.*****************************************************************************//*** @file px4_simple_app.c* Minimal application example for PX4 autopilot** @author Example User <mail@example.com>*/#include <px4_config.h>
#include <px4_tasks.h>
#include <px4_posix.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <math.h>#include <uORB/uORB.h>
#include <uORB/topics/rw_uart.h>__EXPORT int px4_simple_app_main(int argc, char *argv[]);int px4_simple_app_main(int argc, char *argv[])
{printf("Hello Sky!\n");/* subscribe to rw_uart_sonar topic */int sonar_sub_fd = orb_subscribe(ORB_ID(rw_uart));/*设置以一秒钟接收一次,并打印出数据*/orb_set_interval(sonar_sub_fd, 1000);// bool updated;struct rw_uart_s sonar;/*接收数据方式一:start*//*while(true){orb_check(sonar_sub_fd, &updated);if (updated) {orb_copy(ORB_ID(rw_uart_sonar), sonar_sub_fd, &sonar);printf("[YCM]sonar.data=%d\n",sonar.data);}//else printf("[YCM]No soanar data update\n");}*//*接收数据方式一:end*//*接收数据方式二:start*//* one could wait for multiple topics with this technique, just using one here */struct pollfd fds[] = {{ .fd = sonar_sub_fd,   .events = POLLIN },/* there could be more file descriptors here, in the form like:* { .fd = other_sub_fd,   .events = POLLIN },*/};int error_counter = 0;for (int i = 0; ; i++) {/* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */int poll_ret = poll(fds, 1, 1000);/* handle the poll result */if (poll_ret == 0) {/* this means none of our providers is giving us data */printf("[px4_simple_app] Got no data within a second\n");} else if (poll_ret < 0) {/* this is seriously bad - should be an emergency */if (error_counter < 10 || error_counter % 50 == 0) {/* use a counter to prevent flooding (and slowing us down) */printf("[px4_simple_app] ERROR return value from poll(): %d\n", poll_ret);}error_counter++;} else {if (fds[0].revents & POLLIN) {/* obtained data for the first file descriptor *///struct rw_uart_s sonar;/* copy sensors raw data into local buffer */orb_copy(ORB_ID(rw_uart), sonar_sub_fd, &sonar);printf("[px4_simple_app] Sonar data:\t%s\t%d\n",sonar.datastr,sonar.data);}/* there could be more file descriptors here, in the form like:* if (fds[1..n].revents & POLLIN) {}*/}}/*接收数据方式二:end*/return 0;
}

树莓派3pixhawk通信

树莓派pixhawk的连接如下:
这里写图片描述
这里切记不要把VCCGND的GPIO口接反了,很容易把树莓派的CPU 烧了(我就烧了一次),如果都供电了,建议就不要连接两者之间的VCC。树莓派的发送程序如下:

#include <stdio.h> 
#include <wiringPi.h>
#include <wiringSerial.h> 
int main() 
{ 
int fd; 
char data[5]=“R1100”; 
int flag=1;
if(wiringPiSetup()<0)return 1; 
if((fd=serialOpen("/dev/ttyAMA0",9600))<0) return 1;
printf("serial test start ...\n");
serialPrintf(fd,"Hello world!\n"); 
while(flag) { serialPrintf(fd,data);//向串口设备发送data数据 delay(300);while(serialDataAvail(fd)) { printf("->%3d\n",serialGetchar(fd));flag=0; fflush(stdout); } } 
serialFlush(fd); 
serialClose(fd); 
return 0;} 

首先需要说一下,这个串口发送程序需要安装wiringPi库,编译运行命令如下:

gcc –Wall uart.c –o uart –lwiringPi
sudo ./uart

这几天坑埋完了,上各种博客链接:
树莓派pixhawk连接
struct termios结构体详解
树莓派串口发送数据
PX4原生固件添加串口读取传感器

这篇关于PX4固件通过UART连接串口读取超声波,和树莓派3通信(似乎讲了怎么添加驱动程序,添加自定义msg,还有uORB消息订阅,佩服,感觉做了我想做的!)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/506858

相关文章

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

Spring Boot实现多数据源连接和切换的解决方案

《SpringBoot实现多数据源连接和切换的解决方案》文章介绍了在SpringBoot中实现多数据源连接和切换的几种方案,并详细描述了一个使用AbstractRoutingDataSource的实... 目录前言一、多数据源配置与切换方案二、实现步骤总结前言在 Spring Boot 中实现多数据源连接

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,