Pixhawk固件PX4之串口通讯

2023-05-16

1、目的

为进一步扩展pixhawk的接口及功能,通过pixhawk现有接口(串口、I2C等)连接外部设备来实现,本节内容主要介绍串口通讯方式。

2、测试平台

硬件:pixhawk 2.4.8

px4固件版本:1.9.0

pixhawk串口采用SERIAL4: /dev/ttyS6,连接图如下:

3、功能实现

主要实现pixhawk从STM32串口端读取数据,并将数据发给PC,通过串口调试助手查看。

pixhawk端代码参考网上pixhawk串口通讯代码,具体如下:

/**
 * @file px4_uorb_subs.c

 */

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <drivers/drv_hrt.h>
#include <systemlib/err.h>
#include <fcntl.h>
#include <systemlib/mavlink_log.h>

#include <px4_defines.h>
#include <px4_config.h>
#include <px4_posix.h>
#include <px4_shutdown.h>
#include <px4_tasks.h>
#include <px4_time.h>

static bool thread_should_exit = false;		/**< px4_uorb_subs exit flag */
static bool thread_running = false;		/**< px4_uorb_subs status flag */
static int rw_uart_task;				/**< Handle of px4_uorb_subs task / thread */

static int uart_init(char * uart_name);
static int set_uart_baudrate(const int fd, unsigned int baud);


/**
 * daemon management function.
 */
__EXPORT int rw_uart_main(int argc, char *argv[]);

/**
 * Mainloop of daemon.
 */
int rw_uart_thread_main(int argc, char *argv[]);

/**
 * Print the correct usage.
 */
static void usage(const char *reason);

static void
usage(const char *reason)
{
	if (reason) {
		warnx("%s\n", reason);
	}

	warnx("usage: px4_uorb_adver {start|stop|status} [-p <additional params>]\n\n");
}

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;

	/* 以新的配置填充结构体 */
	/* 设置某个选项,那么就使用"|="运算,
	 * 如果关闭某个选项就使用"&="和"~"运算
	 * */
	tcgetattr(fd, &uart_config); // 获取终端参数

	/* clear ONLCR flag (which appends a CR for every LF) */
	uart_config.c_oflag &= ~ONLCR;// 将NL转换成CR(回车)-NL后输出。

	/* 无偶校验,一个停止位 */
	uart_config.c_cflag &= ~(CSTOPB | PARENB);// CSTOPB 使用两个停止位,PARENB 表示偶校验

	 /* 设置波特率 */
	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;
	}
	// 设置与终端相关的参数,TCSANOW 立即改变参数
	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);
	/*Linux中,万物皆文件,打开串口设备和打开普通文件一样,使用的是open()系统调用*/
	// 选项 O_NOCTTY 表示不能把本串口当成控制终端,否则用户的键盘输入信息将影响程序的执行
	if (serial_fd < 0) {
		err(1, "failed to open port: %s", uart_name);
		printf("failed to open port: %s\n", uart_name);
		return false;
	}
	printf("Open the %s\n",serial_fd);
	return serial_fd;
}


/**
消息发布进程,会不断的接收自定义消息
 */
int rw_uart_main(int argc, char *argv[])
{
	if (argc < 2) {
		usage("missing command");
		return 1;
	}

	if (!strcmp(argv[1], "start")) {

		if (thread_running) {
			warnx("px4_uorb_subs already running\n");
			/* this is not an error */
			return 0;
		}

		thread_should_exit = false;//定义一个守护进程
		rw_uart_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("\trunning\n");

		}
		else {
			warnx("\tnot started\n");
		}

		return 0;
	}

	usage("unrecognized command");
	return 1;
}

int rw_uart_thread_main(int argc, char *argv[])
{
	char data = '0';
	//char out_buf[5]="endl";
	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("/dev/ttyS6");
	if (false == uart_read)
		return -1;
	if (false == set_uart_baudrate(uart_read, 9600)) {
		printf("[JXF]set_uart_baudrate is failed\n");
		return -1;
	}
	printf("[JXF]uart init is successful\n");
	//warnx("[rw_uart] starting\n");
	
	thread_running = true;
	//write(uart_read, &out_buf[0],4);

	while (!thread_should_exit) {
		read(uart_read, &data, 1);
		if (data == 'R') {
			for (int i = 0; i < 4; ++i) {
				read(uart_read, &data, 1);
				buffer[i] = data;
				write(uart_read, &buffer[i], sizeof(buffer[i]));
				data = '0';
				usleep(5000);//5ms pause
			}
			printf("%s\n", buffer);
		}
		
		printf("rw_uart TX-test:running!\n");
		
		usleep(1000000);
	}
	//write(uart_read, &out_buf[0],4);
	warnx("[rw_uart] exiting.\n");
	thread_running = false;
	int fd=close(uart_read);
	printf("close stauts: %d\n",fd);
	return 0;
}

4、实验结果

QGC端的Mavlink Console端输出结果:

PC串口调试助手:

结果与期望的功能一致。

5、问题

网上搜索的pixhawk串口通讯基本上实现的是读取功能,为实现发送功能,采用write函数。

参考网上例程,串口采用TELEM2(USART3),发送数据时,存在只能在了进程启动后发送一段时间数据的问题。

后来更改为SERIAL4: /dev/ttyS6,程序正常,故初步判断TELEM2(USART3)串口发送数据可能其他进程也在调用,导致存在冲突。

 

最后附上参考的博客链接

 

Pixhawk---通过串口方式添加一个自定义传感器(超声波为例)

Pixhawk原生固件PX4之串口读取信息

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pixhawk固件PX4之串口通讯 的相关文章

  • [pixhawk笔记]6-uORB流程及关键函数解析

    本文中将结合代码 文档及注释 xff0c 给出uORB执行流程及关键函数的解析 xff0c 由于uORB的机制实现较为复杂 xff0c 所以本文主要学习如何使用uORB的接口来实现通信 回到上一篇笔记中的代码 xff1a include l
  • PX4代码学习系列博客(6)——offboard模式位置控制代码分析

    分析offboard模式的代码需要用到以下几个模块 local position estimator mavlink mc pos control mc att control mixer 程序数据走向 mavlink 一般的offboar
  • px4源码编译指南

    px4源码编译指南 强烈推荐大家去看官网的英文文档 xff0c 国内的博客杂七杂八 xff0c 官网的中文也很久没有更新 xff0c 这几天自己踩了很多坑 xff0c 写个教程希望能帮助到大家 xff08 本文选用平台是pixhawk1 1
  • PX4源代码下载编译

    sudo git clone https github com PX4 PX4 Autopilot git recursivegit submodule update init recursivegit submodule update r
  • win7下 pixhawk (ardupilot) 的编译

    前几天都在搞pixhawk源码编译问题 xff0c 什么在window下用Console或者eclipse xff0c 还是在Ubuntu下 xff0c 都做了 xff0c 而且把 mk文件都看了 xff0c 结果还是有bug 总结一下三种
  • 从Simulink到PX4——Simulink-PX4插件安装与环境搭建

    从Simulink到PX4 Simulink PX4插件安装与环境搭建 前言0 准备工作1 安装WSL2 Setting up the PX4 Toolchain on Windows3 Setting up the PX4 Tool Ch
  • 教程:使用树莓派连接Pixhawk飞控

    教程 xff1a 使用树莓派连接Pixhawk飞控 树莓派可以与Pixhawk飞控相连 xff0c 读取飞控中的状态信息 xff0c 同时对飞控发送指令 树莓派作为一个更高性能的计算平台 xff0c 可以运行图像识别 机器学习 实时路径规划
  • DroneKit教程(三):连接Pixhawk飞控

    DroneKit教程 xff08 三 xff09 xff1a 连接Pixhawk飞控 DroneKit提供了非常简便的代码 xff0c 可通过多种方式与飞控连接 连接飞控 使用DroneKit中的connect函数 xff0c 可以方便地连
  • PX4模块设计之四:MAVLink简介

    PX4模块设计之四 xff1a MAVLink简介 1 MAVLink PX4 应用简介2 MAVLink v2 0新特性3 MAVLink协议版本4 MAVLink通信协议帧4 1 MAVLink v1 0 帧格式4 2 MAVLink
  • PX4模块设计之二十三:自定义FlightTask

    PX4模块设计之二十三 xff1a 自定义FlightTask Step1 创建飞行模式文件夹Step2 创建飞行模式源代码和CMakeLists txt文件Step3 更新CMakeLists txt文件Step4 更新FlightTas
  • PX4模块设计之三十三:Sensors模块

    PX4模块设计之三十三 xff1a Sensors模块 1 Sensors模块简介2 模块入口函数2 1 主入口sensors main2 2 自定义子命令custom command2 3 模块状态print status 重载 3 Se
  • PX4模块设计之三十四:ControlAllocator模块

    PX4模块设计之三十四 xff1a ControlAllocator模块 1 ControlAllocator模块简介2 模块入口函数2 1 主入口control allocator main2 2 自定义子命令custom command
  • 自己组装Pixhawk F450无人机的一些细节

    首先参考文档为 xff1a 1 https mp weixin qq com s VXKU kIB v i0AX3zgtLig 2 https mp weixin qq com s Qzzl dQ6Tz2pXNp7Oj0lTg 3 http
  • px4_simple_example和uorb机制

    px4 simple app PX4 Autopilot src exampes px4 simple app xff0c 这个程序是用c语言调用orb API和poll机制订阅和发布通讯数据 xff0c 但是这个例子并不是既有接收又有发送
  • Px4源码框架结构图

    此篇blog的目的是对px4工程有一个整体认识 xff0c 对各个信号的流向有个了解 xff0c 以及控制算法采用的控制框架 PX4自动驾驶仪软件 可分为三大部分 xff1a 实时操作系统 中间件和飞行控制栈 1 NuttX实时操作系统 提
  • PX4飞控的PPM接收机

    xff08 一 xff09 原理图 xff1a PX4飞控的PPM输入捕获由协处理器完成 xff0c 接在A8引脚 xff0c 对应Timer1的通道1 xff08 二 xff09 PPM协议 xff1a PPM的每一帧数据间隔为20ms
  • 步骤三:PX4,Mavros的下载安装及代码测试

    1 安装Mavros sudo apt install ros melodic mavros ros melodic mavros extras 2 安装Mavros相关的 geographiclib dataset 此处已经加了ghpro
  • 【PX4 飞控剖析】06 树莓派加载安装ROS,Mavros以及PX4固件

    PX4 飞控剖析 06 树莓派加载安装Mavros以及PX4固件 1 树莓派 刷镜像1 1 用Win32DiskImager刷入ubuntu mate 16 04 2 desktop armhf raspberry pi的镜像 1 2 开机
  • 无人机PX4使用动捕系统mocap的位置实现控制+MAVROS

    动捕系统Optitrack xff0c 有很高的定位精度 xff0c 能够给无人机提供比较精确的位置信息 xff0c 因此如果实验室有条件 xff0c 都可以买一套动捕系统 动捕系统的原理 xff1a 光学式动作捕捉依靠一整套精密而复杂的光
  • 四、无人机知识笔记(初级:基本运动原理)

    笔记来源于 沈阳无距科技 工业级无人机的中国名片 编程外星人 目录 一 多旋翼直升机 二 基本飞行姿态 三 多旋翼飞行原理 四 反扭力与偏航运动 五 螺旋桨 六 有刷电机和无刷电机 七 电调与PWM信号 八 动力电池 九 遥控器 十 机架设

随机推荐