树莓派与pixhawk串口通信

2023-05-16

一、Pixhawk部分

1.读取数据测试

步骤:
  • 在Firmware/src/modules中添加一个新的文件夹,命名为rw_uart
  • 在rw_uart文件夹中创建CMakeLists.txt文件,并输入以下内容:
px4_add_module(
	MODULE modules__rw_uart
	MAIN rw_uart
	COMPILE_FLAGS
	-Os
	SRCS
		rw_uart.c
	DEPENDS
		platforms__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的结构体变量rd

   orb_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 time

def 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/ttyUSB0
    if 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 串口读写实现

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

树莓派与pixhawk串口通信 的相关文章

  • labview串口打开之后visaclose不起作用关闭不了老是占用的问题

    labview串口打开之后visaclose不起作用关闭不了老是占用的问题 最近在做一个数据接收的上位机 用串口发送接收数据 之前有用过labview 整体操作相当简单 于是就打算用labview做一个 但是之前做labview的时候就有一
  • SPI协议代码

    软件模拟SPI程序代码 文章目录 SPI协议简介 SPI接口介绍 SPI数据传输方向 SPI传输模式 通过两个单片机模拟SPI来加深理解 硬件连接方式 SPI模式 程序思路 主机C代码 波形 从机C代码 波形 概述 通过两个MCU STM3
  • 基于FPGA的串口通讯设计与实现

    繁體 基于FPGA的串口通讯设计与实现 日期 2012 03 26 来源 作者 字体 大 中 小 随着多微机系统的应用和微机网络的发展 通信功能越来起重要 串行通信是在一根传输线上一位一位传送信息 这根线既作数据线又作联络线 串行通信作为一
  • Qt 串口发送0x00

    应用场景 大恒光电的平移台 GCD 040101M 先看看要发什么东西 这是串口监听软件截取的结果 绿色的字 串口协议主要包括三个部分 前面是固定的 后面是key 后面是 0x00 最后面是数据 错误版本1 bool MoveStage w
  • 一、利用AT指令配置esp8266——esp8266WIFI模块初探&STM32串口通信再探

    文章目录 一 esp8266初探 1 esp8266简介 2 esp8266使用方式 什么是AT指令 通过何种方式发送AT指令 二 STM32串口通信再探 1 printf 函数与串口中断函数 2 例子 小试牛刀 3 例子 再进一步 三 局
  • STM32串口溢出中断问题

    之前调试程序 遇到了串口溢出中断的问题 导致主程序被卡死 这里总结分享一下经验 希望对读者有用 对于STM32F103系列单片机 使能接收中断后 溢出中断就会自动被使能 那什么时候会发生溢出中断呢 在RXNE 1 的的条件下 也就是上次数据
  • c++实现串口通讯踩坑(argument of type “char *“ is incompatible with parameter of type “LPCWSTR“)

    在C下 可以使用outportb和inportb进行串口通讯 C 没有这两个函数 那就使用createfile吧 通过网上搜到读取打开串口的例子 如下 include
  • USART_FLAG_TC与 USART_FLAG_TXE之间的区别,各自的用途 - 附举例代码及说明

    USART FLAG TC与 USART FLAG TXE之间的联系 各自的用途 名词解释 STM32固件库使用手册 USART FLAG TXE 发送数据寄存器空标志位 USART FLAG TC 发送移位寄存器发送完成标志位 串口发送数
  • 关于STM32串口接收中断中只能接收一个字节()

    最近调试STM32的串口接收时发现例程中只能接收一个字节 例程如下 1 初始化串口1 2 void uart init u32 bound 3 GPIO端口设置 4 GPIO InitTypeDef GPIO InitStructure 5
  • 什么是节点光端机?总线型光端机有哪些优势?

    节点式光端机又称总线型光端机 其准确的定义是采用单 双纤链路式组网形式的图像传输系统 也被称为链路式光端机 那么 节点式光端机具体是什么呢 总线型光端机又有哪些优势呢 接下来我们就跟随飞畅科技的小编一起来详细了解下吧 什么是节点光端机 节点
  • 硬件设计——外围电路(晶振电路)

    硬件设计之晶振电路 为什么要用晶振 晶振电路由何组成 晶振电路中其电容的作用 在日常的电路设计中 我们经常会用到晶振电路 所以我们就要首先先提一下什么是晶振 这样才能理解晶振电路 为什么要用晶振 晶振的作用是为系统提供基本的时钟信号 通常一
  • STM32串口配置实验

    STM32 串口简介 串口作为 MCU 的重要外部接口 同时也是软件开发重要的调试手段 其重要性不言而喻 现在基本上所有的 MCU 都会带有串口 STM32 自然也不例外 STM32 的串口资源相当丰富的 功能也相当强劲 ALIENTEK
  • CSerialPort教程4.3.x (6) - CSerialPort作为第三方库的使用

    CSerialPort教程4 3 x 6 CSerialPort作为第三方库的使用 环境 系统 windows 10 CentOS 7 cmake 3 22 1 前言 CSerialPort项目是一个基于C C 的轻量级开源跨平台串口类库
  • 小记stm32实现串口接收的四种方法(hal库)

    开发环境 STM32CUBMX 正点原子STM32F407ZGT6探索者开发板 MDK ARM 5 31 第一种方式 直接接收 配置外部时钟源 2 配置时钟树 3 配置串口一 生产代码后进入工程 重定向printf到串口1 建议在usart
  • 【嵌入式基础】串口通信

    目录 1 前言 2 基本概念 2 1 波特率 2 2 起始位 2 3 数据位 2 4 校验位 2 5 停止位 2 6 空闲位 3 工作模式 3 1 单工模式 3 2 半双工模式 3 3 全双工模式 4 同步通信和异步通信 4 1 同步通信
  • 玩转ESP8266-01——AT指令集

    该指令集是接上一个 链接 初识AT指令 全部是根据本人在使用esp8266过程中用过的指令 可能有不全 有错误 还请理解指正 一起学习 AT指令集 一 基础指令 1 测试指令 2 复位指令 重启 二 设置指令 1 设置波特率 2 设置工作模
  • Linux系统下使用socat将串口映射到TCP服务器端口

    首先需要安装socat 安装方法即是 apt get install socat 或 yum install socat 然后使用以下命令进行映射 socat TCP LISTEN 8899 fork reuseaddr FILE dev
  • STM32串口中断接收方式详细比较

    本例程通过PC机的串口调试助手将数据发送至STM32 接收数据后将所接收的数据又发送至PC机 具体下面详谈 实例一 void USART1 IRQHandler u8 GetData u8 BackData if USART GetITSt
  • 数字电路的时钟(1)-- 时钟抖动和分类

    时钟抖动通常分为时间间隔误差 Time Interval Error 简称TIE 又叫相位抖动 周期抖动 Period Jitter 和相邻周期抖动 cycle to cycle jitter 三种抖动 TIE又称为phase jitter
  • Android usb通信 实现app与arduino通信demo

    Android usb通信 一 前言 二 开始 1 AndroidManifest xml清单文件 2 创建权限广播接收者 3 枚举usb设备 4 获取usb接口以及输入 输出端点 5 打开设备 6 设置波特率 7 创建接收数据的线程 8

随机推荐

  • float型数据与4字节之间的转换

    文章目录 一 前言二 地址指针转换的方法三 共用体的方法 xff08 注意要定义全局变量数组s xff0c 即地址要分配为固定地址 xff09 一 前言 在与上位机之间进行数据收发 xff0c 要将float型数据转换成字节进行传输 xff
  • USB虚拟串口实现多字节数据接收,基于stm32h743

    文章目录 一 USB虚拟串口原理简介二 接收函数实现源码三 小结 一 USB虚拟串口原理简介 USB 虚拟串口 xff0c 简称 VCP xff0c 是 Virtual COM Port 的简写 xff0c 它是利用 USB 的 CDC 类
  • EC20/EC25 4G模块AT指令开发总结

    文章目录 一 EC25 20 4G模块简介二 AT指令总结1 通用AT指令2 建立TCP UDP连接相关AT指令 三 TCP传输数据流程四 UDP传输数据流程五 总结 一 EC25 20 4G模块简介 EC25 是一系列带分集接收功能的 L
  • C语言实现socket网络编程及多线程编程

    文章目录 一 概述二 TCP socket网络编程1 server端程序实现 xff08 tcp server cpp xff09 2 client端程序实现 xff08 tcp client cpp xff09 3 编译与执行 三 UDP
  • 基于openssl实现https双向身份认证及安全通信

    文章目录 一 概述二 代码设计2 1 ssl server c程序设计2 2 ssl client c程序设计 三 测试 一 概述 https基于SSL TLS提供安全的通信信道 xff0c 基于证书认证技术实现服务器和客户端之间的身份认证
  • ubuntu的不同版本

    ubuntu是现在最流行的Linux安装包 xff0c 本文介绍了ubuntu的各种版本 一 Ubuntu 每个ubuntu的版本都包含一个版本号 xff08 version number xff09 和一个代码名 xff08 code n
  • Linux下通过service服务管理用户进程

    文章目录 一 service配置介绍1 1 service配置文件1 2 配置文件的区块1 3 修改配置文件后重启1 4 服务管理 二 设计一个可执行程序三 设计一个service管理 home ubuntu test servicetes
  • c++中多态调用场景下基类析构函数的virtual声明

    文章目录 一 基类析构函数未加virtual声明的情况1 1 基础示例演示1 2 进阶示例演示 二 基类析构函数添加virtual声明的情况三 总结 一 基类析构函数未加virtual声明的情况 在多态场景中 xff0c 可通过基类的指针指
  • protobuf协议原理及实现,基于c++

    文章目录 一 protobuf协议简介1 1 protobuf协议简介1 2 数据交互xml json protobuf格式比较1 3 关于 ProtoBuf 的一些思考 二 protobuf库安装三 protobuf库使用第一步 xff0
  • OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

    本文介绍了对OLED的几种驱动方式 xff0c 8080并口 xff0c IIC xff0c SPI三种驱动方式 xff0c 采用的单片机是STM32F407 文章目录 一 OLED驱动原理介绍二 8080并口驱动方式三 IIC驱动方式四
  • ROS2学习笔记(1)ROS2+docker的配置方法

    ROS2学习笔记 xff08 1 xff09 ros2 43 docker的配置方法 1 前言2 安装docker2 1 docker的发展史2 2 什么是docker2 3 docker的思想2 3 1 集装箱2 3 2 标准化1 运输方
  • ubuntu之更改ubuntu和windows双系统启动顺序

    ubuntu之更改ubuntu和windows双系统启动顺序 背景方法 背景 安装好ubuntu和windows双系统后 xff0c 一般grub引导默认选择第一个为启动项 xff0c 在公司打工还好 xff0c 毕竟要进ubuntu挣钱
  • 【lightDM】组件理解

    前言 LightDM xff08 Light Display Manager xff09 是轻量级 Linux 桌面显示管理器 其目的是成为 X org 的 X Server 的标准显示管理器 LightDM 负责启动 X servers
  • 【机器人学中的状态估计】第一讲

    1 什么是状态估计 xff1f 通过获得传感器的观测值 xff0c 建立观测值到状态量的模型 xff0c 估计出状态量 2 概率密度函数 后验概率 p x y
  • VScode环境下使用git与github远程操作要点记录

    部分内容来源于网络 xff0c 外加了自己的实践 xff0c 记录了一下 文章目录 一 windows上使用git1 官网下载git https git scm com download win 2 创建本地仓库 二 git远程连接gith
  • 【千律】C++基础:TXT文件的创建、写入和读取

    include lt fstream gt include lt iostream gt using namespace std int main 初始化 ifstream iread txt 初始化输入流 ofstream write t
  • Matlab计算福利彩票的中奖概率

    Quez1 计算福彩双色球一等奖的中奖概率 福彩双色球的玩法如下 从编号1 33的红球里任选6个 另外在编号1 16的蓝球里再任选1个 如果选择的红球和蓝球和当期的开奖结果完全一致 顺序可不同 则中一等奖 Analysis 这是一个组合问题
  • 【千律】OpenCV基础:基于梯度的模板匹配

    环境 xff1a Python3 8 和 OpenCV 内容 xff1a 基于梯度的模板匹配 主要关注边缘信息 xff0c 能够较好的识别不同颜色的目标 实现步骤 xff1a 1 给定原图像I和模板T 2 指定差异度 xff08 相似度 x
  • golang使用SM2(SM2withSM3)签名、验签数据

    golang使用SM2签名 验签数据 场景标准密钥签名算法 Start依赖公钥转base64私钥转hex私钥生成公钥生成密钥对Hex私钥转私钥对象base64公钥转公钥对象签名验签 测试 场景 对接招行支付 标准 密钥 私钥 xff1a H
  • 树莓派与pixhawk串口通信

    一 Pixhawk部分 1 读取数据测试 步骤 xff1a 在Firmware src modules中添加一个新的文件夹 xff0c 命名为rw uart在rw uart文件夹中创建CMakeLists txt文件 xff0c 并输入以下