树莓派与pixhawk串口通信
一、Pixhawk部分
1.读取数据测试
步骤:
- 在Firmware/src/modules中添加一个新的文件夹,命名为rw_uart
- 在rw_uart文件夹中创建CMakeLists.txt文件,并输入以下内容:
px4_add_module(MODULE modules__rw_uartMAIN rw_uartCOMPILE_FLAGS-OsSRCSrw_uart.cDEPENDSplatforms__common
)
- 在rw_uart文件夹中创建rw_uart.c文件
#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>__EXPORT int rw_uart_main(int argc, char *argv[]);int set_uart_baudrate(const int fd, unsigned int baud);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;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 rw_uart_main(int argc, char *argv[])
{char data = '0';char buffer[4] = "";int uart_read = open("/dev/ttyS2", O_RDWR | O_NOCTTY);//打开串口设备if (uart_read < 0) {err(1, "failed to open port: %s", "/dev/ttyS2");return -1;}if(false == set_uart_baudrate(uart_read,9600)){printf("[YCM]set_uart_baudrate is failed\n");return -1;}printf("[YCM]uart init is successful\n");while(true){read(uart_read,&data,1);if(data == 'R'){for(int i = 0;i <4;++i){read(uart_read,&data,1);//读取串口数据buffer[i] = data;data = '0';}printf("%s\n",buffer);}}
return 0;
}
- 注册新添加的应用到NuttShell中。/src/Firmware/cmake/configs/nuttx_px4fmu-v2_default.cmake文件中添加如下内容:
modules/rw_uart
- 编译并刷固件
make clean
make px4fmu-v2_default
2.定义和发布主题
2.1 新建主题
- msg文件夹下新建rw_uart_raspberry_topic.msg文件
char[4] datastr0 uint8 data
- 在msg文件夹中的CMakeList文件中加入
rw_uart_raspberry_topic.msg
2.2 补充修改rw_uart.c文件
- rw_uart.c
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <drivers/drv_hrt.h>
#include <uORB/topics/rw_uart_raspberry_topic.h>
#include <uORB/uORB.h>
#include <string.h>
#include <systemlib/err.h>
#include <systemlib/systemlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <px4_tasks.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 void usage(const char *reason);
static int uart_init(char * uart_name);
static int set_uart_baudrate(const int fd, unsigned int baud);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 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;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(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;
}int rw_uart_main(int argc, char *argv[])
{if (argc < 2) {usage("[YCM]missing command");}if (!strcmp(argv[1], "start")) {if (thread_running) {warnx("[YCM]already running\n");return 0;}thread_should_exit = false;daemon_task = px4_task_spawn_cmd("rw_uart",SCHED_DEFAULT,SCHED_PRIORITY_DEFAULT,2000,rw_uart_thread_main,(argv) ? (char * const *)&argv[2] : (char * const *)NULL);return 0;}if (!strcmp(argv[1], "stop")) {thread_should_exit = true;return 0;}if (!strcmp(argv[1], "status")) {if (thread_running) {warnx("[YCM]running");} else {warnx("[YCM]stopped");}return 0;}usage("unrecognized command");return 1;
}
int rw_uart_thread_main(int argc, char *argv[])
{warnx("[daemon] starting\n");thread_running = true;char data = '0';char buffer[4] = "";/** 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("/dev/ttyS2");if(false == uart_read)return -1;if(false == set_uart_baudrate(uart_read,9600)){printf("[YCM]set_uart_baudrate is failed\n");return -1;}printf("[YCM]uart init is successful\n");struct rw_uart_raspberry_topic_s test_data; //定义类型为rw_uart_raspberry_topic_s的结构体变量rdorb_advert_t rw_uart_raspberry_topic_pub = orb_advertise(ORB_ID(rw_uart_raspberry_topic), &test_data);while(!thread_should_exit){read(uart_read,&data,1);if(data == 'R'){for(int i = 0;i <4;++i){read(uart_read,&data,1); //读取串口设备数据1个字节,放到data中buffer[i] = data;data = '0';}write(uart_read,&buffer,4);char * s;strncpy(test_data.datastr0,buffer,4);test_data.data = strtol(test_data.datastr0,&s,10);orb_publish(ORB_ID(rw_uart_raspberry_topic), rw_uart_raspberry_topic_pub, &test_data);int b=strtol(test_data.datastr0,&s,10);printf("\t%s\t%d\t%d\n",test_data.datastr0,test_data.data,b);}}warnx("[YCM]exiting");thread_running = false;close(uart_read);fflush(stdout);return 0;
}
2.3设置自启动
- 在ROMFS/px4fmu_common/init.d/rcS中添加自启动
rw_uart start
- 编译并刷固件
make clean
make px4fmu-v2_default
make px4fmu-v2_default_upload
二、Raspberry部分
- 循环发送’R1100’小程序(python)
# -*- coding: utf-8 -*-
import serial
import timedef port_send(send_date):if (serial.isOpen()):serial.write(send_date.encode('utf-8'))time.sleep(0.5)else:print("send failed")if __name__ == "__main__":serial = serial.Serial('/dev/ttyS2', 9600, timeout=0.5) # /dev/ttyUSB0if serial.isOpen():print("open success")else:print("open failed")while True:port_send("R1100")
三、Pixhawk与树莓派连接
- TX—RX
- RX—TX
- GND—GND
- TELEM2从左到右分别是VC TXD RXD 未知 未知 GND
测试结果:
四、编译过程中产生的问题
在编译的过程中碰到了很多问题,但是大部分都是可以百度谷歌到的。我主要将不能搜索到的问题摆出来,供大家在开发过程时参考。
- implicit declaration of function ‘px4_task_spawn_cmd’
问题原因及解决方案:
缺失相关的头文件,补充头文件:
#include <px4_tasks.h>
- compilation terminated due to -Wfatal -errors
问题原因及解决方案:
对应函数‘set_uart_baudrate’格式不对
删除对应函数,重新书写函数。
参考资料
Pixhawk与树莓派3的串口通信
Pixhawk—通过串口方式添加一个自定义传感器(超声波为例)
pixhawk串口读取传感器数据
Python 串口读写实现
树莓派与pixhawk串口通信相关推荐
- 电脑与树莓派与stm32f4串口通信
电脑与树莓派与stm32串口通信 stm32设置 树莓派代码 stm32设置 // 核心代码,不能运行 void M1_PID(float top); void upmada(void); typed ...
- 树莓派php minicom,用DHT11实践树莓派与Arduino串口通信 | 树莓派实验室
Arduino具有丰富的外部接口,与树莓派的IO口最大的不同在于Arduino具有模拟输入接口,可以测量IO口上的模拟值.Arduino与Raspberry通过串口(Serial)通信的方案一般有两种 ...
- (二)树莓派Linux环境串口通信编程--AT指令集的发送和接收
文章目录 一.前言 二.要了解的知识 2.1 termios结构体 2.2 tcflush() 2.3 cfsetispeed()与cfsetospeed() 三.流程图设计与代码实现 serial_ ...
- python树莓派串口通信实例_树莓派通过串口发送数据
可以通过串口登陆树莓派,也可以通过串口向其他主机发送数据.树莓派的串口接受数据科技爱好者博客已经写过,可以参考这篇文章:树莓派与arduino串口通信实践.这篇文章教大家如果通过树莓派的串口发送数据. ...
- 串口通信协议(基于面试),与及树莓派与电脑之间串口通信
一.首先来说一下基于面试的串口通信协议 树莓派wiringPi库详解 (1)串口通信是基于多机的通信 主要就是两根线:RXD和TXD 举例,语音识别模块与树莓派之间进行串口通信 语音模块的T连接树莓派 ...
- 语音模块LD3320模块的二次开发,并与树莓派进行串口通信
一.首先模块介绍 (1)参数详解 型号:YS-LDV7 名称:一体化语音识别模块 规格:43*29.7MM 供电电压:5V (内部工作电压 3.3V) 待机电流:30MA 识别时电流:45MA IO ...
- 32、树莓派的简单测试串口通信和超声波模块测距
基本思想:随手记录一下众灵科技树莓派的测试串口通信和超声波模块,其镜像还是很nice,基本的库都给你安装了,比较大 链接:https://pan.baidu.com/s/11tMdoRh3bHmcYz ...
- 树莓派串口通信 USB串口通信 常用串口命令
树莓派串口通信 USB串口通信 文章目录 树莓派串口通信 USB串口通信 准备 发送数据 接收数据 如果不知道树莓派怎么使用USB串口通信的,欢迎浏览我的另一篇博客文章: 树莓派使用USB串口通信 C ...
- android 串口调试工具_树莓派通用串口通信实验
一.介绍 对于树莓派 3B+来说,他的UART功能有三种:1.内部蓝牙使用:2.控制终端使用:3.与其他设备进行串口通信. 在树莓派USB TO TTL模块实验中学习了通过串口对树莓派进行控制台控制, ...
最新文章
- 面板panel与窗口frame的区别
- Spring——AOP配置时的jar包异常
- 一个IO的传奇一生(8) -- elevator子系统
- 【机器视觉】 for算子
- doctype声明、浏览器的标准、怪异等模式
- Windows与Linux下查看占用端口的进程
- 二维旋转矩阵公式推导
- 微信棋牌H5游戏开发教程以及如何有效防止被人恶意攻击
- 手机修改ntp服务器地址,手机修改ntp服务器ip地址
- pytorch 语⾔模型数据集(周杰伦专辑歌词)数据集 免费
- 你认为996是一种荣耀吗?
- php disable hugepage,禁用Transparent Huge Pages
- css 好看滚动条样式大全,CSS 个性化滚动条样式
- iOS开发之响应式编程RAC
- java url生成二维码
- 降维技术 (Dimensionality Reduction)
- 交换式多兆位数据服务(SMDS)--网络大典
- 微服务(Microservice)那点事
- 百度搜索接口api_百度站长平台上线落地页视频转存功能,确保专业问答视频资源的质量和稳定性...
- 【SoapUI】SoapUI工具简介及安装
热门文章
- 浏览器是怎样渲染网页的呢?
- 混泥土(地面+墙面)+ 山体裂缝数据集汇总(分类及目标检测)
- KPI,OKR互联网人的绩效指标
- Response对象以及从服务端下载文件(解决乱码问题)
- IOS学习笔记68 -- 开发的一些奇巧淫技
- 3.2.3 TableLayout(表格布局)
- 沙拉公主的困惑 cash
- mysql循环插入语句_MySQL实现循环插入功能
- Android studio连接海马玩
- 机器学习中的数学——距离定义(七):兰氏距离(Lance and Williams Distance)/堪培拉距离(Canberra Distance)