PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题

2023-05-16

PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题

本次小项目是通过PX4读取STM32F4发过来的数据,之前博客介绍了我做的STM32端项目,再稍微啰嗦一下:解析AIRMAR和测深仪数据,该数据采用NEMA0183协议传输的。PX4接收到数据会通过mavlink消息发布出去,通过433MHz来进行无线传输,然后在岸边读取内河中的气象信息。
本项目会通过几篇博客去介绍,本次主要介绍PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题,本次帖子主要是参考网络上一些大神方法进行编写,希望对大家有用,欢迎各位朋友及时提出问题。
在Firmware/msg目录下新建read_uart_sensor.msg文件并添加到CMakeLists.txt中,编译后自动生成uORB/topics/read_uart_sensor.h头文件
在这里插入图片描述

char[10] jingdustr
char[10] weidustr
char[10] hangsustr
char[10] hangxiangstr
char[10] fengsustr
char[10] fengxiangstr
char[10] wendustr
char[10] shendustr

float32 longitude
float32 latitude
float32 hang_su
float32 hang_xiang
float32 feng_su
float32 feng_xiang
float32 wen_du
float32 shen_du

# TOPICS read_uart_sensor

在Firmware/src/modules目录下新建文件夹read_uart_sensor。添加文件read_uart_sensor.c
在这里插入图片描述
PX4接收串口接收代码

/*
 * 串口读取函数
 * read_uart_sensor.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 <nuttx/config.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <poll.h>
#include <uORB/uORB.h>
#include <uORB/topics/sensor_combined.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/read_uart_sensor.h>
#include <px4_tasks.h>
__EXPORT int read_uart_sensor_main(int argc, char *argv[]);

static int daemon_task;
static bool thread_should_exit = true;
static bool thread_running = false;

int read_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);
int set_uart_baudrate(const int fd, unsigned int baud)
{
    int speed;
    switch (baud) {
    case 9600:   speed = 9600;   break;
    case 19200:  speed = 19200;  break;
    case 38400:  speed = 38400;  break;
    case 57600:  speed = 57600;  break;
    case 115200: speed = 115200; 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);
    if (serial_fd < 0)
    {
        err(1, "failed to open port: %s", uart_name);
        return false;
    }
    //    printf("Open the %s\n",serial_fd);
    return serial_fd;
}
static void usage(const char *reason)
{
    if (reason) {
        fprintf(stderr, "%s\n", reason);
    }

    fprintf(stderr, "usage: read_uart_sensor {start|stop|status} [param]\n\n");
    exit(1);
}
int read_uart_sensor_main(int argc, char *argv[])
{

    if (argc < 2)
    {
        usage("missing command");
    }

    if (!strcmp(argv[1], "start"))
    {
        if (thread_running)
        {
            warnx("already running\n");
            return 0;
        }

        thread_should_exit = false;
        daemon_task = px4_task_spawn_cmd("read_uart_sensor",
                                         SCHED_DEFAULT,
                                         SCHED_PRIORITY_DEFAULT,
                                         //SCHED_PRIORITY_MAX - 5,
                                         2000,
                                         read_uart_thread_main,
                                         (argv) ? (char * const *)&argv[2] : (char * const *)NULL);
        warnx("already running2222\n");
        return 0;
    }
    if (!strcmp(argv[1], "stop"))
    {
        thread_should_exit = true;
        return 0;
    }
    if (!strcmp(argv[1], "status"))
    {
        if (thread_running)
        {
            warnx("running");
            return 0;

        } else
        {
            warnx("stopped");
            return 1;
        }
        return 0;
    }
    usage("unrecognized command");
    return 1;
}

int read_uart_thread_main(int argc,char *argv[])
{
    //char *uart_name = argv[1];
    char data = '0';
    char jingdu[10] = "";
    char weidu[10]  = "";
    char hangsu[10]  = "";
    char hangxiang[10]  = "";
    char fengsu[10] = "";
    char fengxiang[10]  = "";
    char wendu[10]  = "";
    char shendu[10]  = "";
    int index=0;
    int jingdu_counter=0;
    int weidu_counter=0;
    int hangsu_counter=0;
    int hangxiang_counter=0;
    int fengsu_counter=0;
    int fengxiang_counter=0;
    int wendu_counter=0;
    int shendu_counter=0;
    int end=0;
    int uart_read = uart_init("/dev/ttyS6");
    if(false == uart_read)
        return -1;
    if(false == set_uart_baudrate(uart_read,9600))
    {
        printf("set_uart_baudrate is failed\n");
        return -1;
    }
    printf("uart init is successful\n");
    thread_running = true;
    struct read_uart_sensor_s orbtest;
    memset(&orbtest,0,sizeof(orbtest));
    orb_advert_t pub_fd=orb_advertise(ORB_ID(read_uart_sensor),&orbtest);   //公告,公告必须在发布之前,否则即使订阅也得不到任何数据
    while (!thread_should_exit)
    {
        read(uart_read,&data,1);
        warnx("already running3333\n");
        if(data=='$')
        {
           while(end==0)
           {
              read(uart_read,&data,1);
              if(data ==',')
   	      {
            	index++;
              }
              else
              {
                switch(index)
                {
                  case 1:jingdu[jingdu_counter++]=data;break;
              	  case 2:weidu[weidu_counter++]=data;break;
              	  case 3:hangsu[hangsu_counter++]=data;break;
                  case 4:hangxiang[hangxiang_counter++]=data;break;
                  case 5:fengsu[fengsu_counter++]=data;break;
                  case 6:fengxiang[fengxiang_counter++]=data;break;
                  case 7:wendu[wendu_counter++]=data;break;
                  case 8:shendu[shendu_counter++]=data;break;
                  case 9:end=1;break;
                }
              }
          }
       }
       if(end==1)
       {
          jingdu_counter=0;
	  weidu_counter=0;
          hangsu_counter=0;
	  hangxiang_counter=0;
	  fengsu_counter=0;
          fengxiang_counter=0;
          wendu_counter=0;
          shendu_counter=0;
          index=0;
          end=0;
          //printf("%s\n",jingdu);
          //printf("%s\n",weidu);
          //printf("%s\n",hangsu);
          //printf("%s\n",hangxiang);
          //printf("%s\n",fengsu);
          //printf("%s\n",fengxiang);
          //printf("%s\n",wendu);
          //printf("%s\n",shendu);
          warnx("already running4444\n");
          strncpy(orbtest.jingdustr,jingdu,10);// 复制字符串
          strncpy(orbtest.weidustr,weidu,10);
          strncpy(orbtest.hangsustr,hangsu,10);
          strncpy(orbtest.hangxiangstr,hangxiang,10);
          strncpy(orbtest.fengsustr,fengsu,10);
          strncpy(orbtest.fengxiangstr,fengxiang,10);
          strncpy(orbtest.wendustr,wendu,10);
          strncpy(orbtest.shendustr,shendu,10);
          orbtest.longitude= atof(orbtest.jingdustr);
          orbtest.latitude = atof(orbtest.weidustr);
          orbtest.hang_su  = atof(orbtest.hangsustr);
	  orbtest.hang_xiang= atof(orbtest.hangxiangstr);
	  orbtest.feng_su= atof(orbtest.fengsustr);
	  orbtest.feng_xiang= atof(orbtest.fengxiangstr);
	  orbtest.wen_du= atof(orbtest.wendustr);
	  orbtest.shen_du= atof(orbtest.shendustr);    
          orb_publish(ORB_ID(read_uart_sensor),pub_fd,&orbtest); 
          /*warnx("DATA:longitude=%f,latitude=%f,hang_su=%f,hang_xiang=%f",
                     (double) orbtest.longitude,
                     (double) orbtest.latitude,
                     (double) orbtest.hang_su,
                     (double) orbtest.hang_xiang);*/
          printf("success!\n");
          int sensor_sub_fd = orb_subscribe(ORB_ID(read_uart_sensor));//
          orb_set_interval(sensor_sub_fd, 1000);
          struct read_uart_sensor_s data_copy;
          orb_copy(ORB_ID(read_uart_sensor),sensor_sub_fd,&data_copy);
                    //PX4_INFO("DATA:%f\t%f",
                       //      (double)data_copy.lat,
                         //    (double)data_copy.lng);
         warnx("DATA:longitude=%f,latitude=%f,hang_su=%f,hang_xiang=%f",
                     (double) data_copy.longitude,
                     (double) data_copy.latitude,
                     (double) data_copy.hang_su,
                     (double) data_copy.hang_xiang);
      }
    }
    warnx("exiting");
    thread_running = false;
    close(uart_read);
    fflush(stdout);
    return 0;
}

添加CMakeLists.txt文件,并编写里面内容。

set(MODULE_CFLAGS)
px4_add_module(
        MODULE modules_read_uart_sensor
        MAIN read_uart_sensor
    COMPILE_FLAGS
        -Os
    SRCS
                read_uart_sensor.c
    DEPENDS
        platforms__common
    )
# vim: set noet ft=cmake fenc=utf-8 ff=unix : 


对应位置如下:
在这里插入图片描述

在Firmware/cmake/configs/nuttx/nuttx_px4fmu-v2_default.cmake中注册该模块
在这里插入图片描述

以上就是对PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题的代码编写和环境配置,接下来最关心的事情便是查看结果正确性,具体操作如下:
显示在nsh终端上面
在这里插入图片描述

1、输入read_uart_sensor start 就会运行对应程序并运行打印程序打印在nsh终端上。
2、输入read_uart_sensor stop就会停止对程序运行
在这里插入图片描述

如上方法,如果可以看到如上图所示效果,则说明成功了,恭喜你可以开始后面自定义mavlink消息!

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

PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题 的相关文章

  • PX4 Bootloader下载及编译过程中的问题解决

    买来的雷迅的板子都是Bootloader已经烧进去了 xff0c Fireware也已经刷进去了 如果是自制的板子 xff0c 上位机根本没法识别板子 xff0c 必须先烧写下载Bootloader后编译好的bin文件 这篇记一下自己下载及
  • PX4模块设计之三:自定义uORB消息

    PX4模块设计之三 xff1a 自定义uORB消息 1 新增自定义uORB消息步骤2 应用ext hello world消息示例3 编译执行结果4 参考资料 基于PX4开源软件框架简明简介和PX4模块设计之二 xff1a uORB消息代理
  • 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模块设计之十三:WorkQueue设计

    PX4模块设计之十三 xff1a WorkQueue设计 1 WorkQueue启动2 WorkQueue接口2 1 基本接口2 2 辅助接口2 3 WorkQueue任务函数2 3 1 Flat Build2 3 2 Protected
  • PX4模块设计之十六:Hardfault模块

    PX4模块设计之十六 xff1a Hardfault模块 1 Hardfault模块初始化2 Hardfault模块主程序3 Hardfault命令3 1 hardfault check status3 2 hardfault rearm3
  • PX4模块设计之二十三:自定义FlightTask

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

    PX4模块设计之三十四 xff1a ControlAllocator模块 1 ControlAllocator模块简介2 模块入口函数2 1 主入口control allocator main2 2 自定义子命令custom command
  • PX4模块设计之三十九:Commander模块

    PX4模块设计之三十九 xff1a Commander模块 1 Commander模块简介2 模块入口函数2 1 主入口commander main2 2 自定义子命令custom command 3 Commander模块重要函数3 1
  • PX4模块设计之四十三:icm20689模块

    PX4模块设计之四十三 xff1a icm20689模块 1 icm20689模块简介2 模块入口函数2 1 主入口icm20689 main2 2 自定义子命令custom command2 3 模块状态print status 重载 3
  • mavros连接px4失败的usb-ttl原因

    问题描述 xff1a 最近在搞mavros xff0c 以方便协处理器和pixhawk通讯 xff0c 在按照官网教程安装mavros xff0c 设置px4 xff0c 连接硬件之后发现mavros卡在中间下不去 xff1a MAVROS
  • px4_simple_example和uorb机制

    px4 simple app PX4 Autopilot src exampes px4 simple app xff0c 这个程序是用c语言调用orb API和poll机制订阅和发布通讯数据 xff0c 但是这个例子并不是既有接收又有发送
  • px4无人机常识介绍(固件,px4等)

    专业名词解释 aircraft 任何可以飞或者可以携带物品还是搭载旅客的飞行器统称为飞机 航空器 uav 无人驾驶飞机 vehicle 飞行器 airplane plane aero plane 有机翼和一个或多个引擎的飞行器统称为飞机 D
  • STM32F4主板硬件设计与接口

    更多交流欢迎关注作者抖音号 xff1a 81849645041 本专栏的所有程序都在飞航科技 STM32 F407 开发板上测试通过 xff0c 本文介绍一下STM32 F407 开发板硬件设计与接口 xff0c 便于读者学习交流 STM3
  • STM32F4 使用SPI读取气压计MS5611的数据并转化为大气压强

    ms5611是同时支持I2C和SPI通信协议的气压计芯片 已经很普遍的被用在飞行器控制板上作为高度传感器 开发过stm32的朋友都知道它的硬件I2C是由bug的 xff0c 一般使用的都是自己编写的软件I2C通信协议 但是其硬件SPI通信却
  • px4下载指定版本的固件、git用法

    https hub fastgit org PX4 PX4 Autopilot git describe tag 查看当前版本号 git tag l 查看所有版本 xff0c 也就是打个tag git checkout v1 9 1 跳转到
  • PX4模块设计之二十七:LandDetector模块

    PX4模块设计之二十七 xff1a LandDetector模块 1 LandDetector模块简介2 模块入口函数2 1 主入口land detector main2 2 自定义子命令custom command 3 LandDetec
  • 步骤八:PX4使用cartographer与move_base进行自主建图导航

    首先老样子硬件如下 飞控 HOLYBRO PIXHAWK V4 PX4 机载电脑 jetson nano b01 激光雷达 思岚a2 前提 你已经完成了cartographer建图部分 能够正常输出map话题 前言 由于要参加中国机器人大赛
  • PX4之常用函数解读

    PX4Firmware 经常有人将Pixhawk PX4 APM还有ArduPilot弄混 这里首先还是简要说明一下 xff1a Pixhawk是飞控硬件平台 xff0c PX4和ArduPilot都是开源的可以烧写到Pixhawk飞控中的
  • 使用HAL库开发STM32:系统时间基础及进阶使用

    文章目录 目的 基础使用 进阶使用 总结 目的 HAL库默认提供了系统时间 系统时间默认情况下由SysTick定时器计数产生 系统时间一方面用于HAL库自身调用 另一方面用户也可以使用 为开发带来便利 本文提到的相关使用主要应用于未使用OS
  • STM32:从自定义引导加载程序跳转到应用程序时发生硬故障

    我正在开发带有自定义引导加载程序和应用程序的 STM32F401 MCU 编译器是GCC 5 2 1 没有运行优化 在以下跳转序列后的第一次中断后 我遇到了硬故障 引导加载程序 gt 应用程序 gt 引导加载程序 gt 应用程序 从引导加载

随机推荐

  • CRS-1705: Found 1 configured voting files but 2 voting files are required

    背景 xff1a vmware虚拟机安装两节点19c rac xff0c 执行node1 root脚本时正常 xff0c 执行node2的root脚本时报错 报错如下 xff1a CRS 2672 Attempting to start 3
  • wwid和uuid的区别

    转载于 xff1a https blog csdn net zwjzqqb article details 80321348 1 wwid 每个SCSI磁盘都有一个WWID xff0c 类似于网卡的MAC地址 xff0c 是独一无二的 可以
  • Sm2记录介绍

    SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法 xff0c SM2采用的就是ECC 256位的一种 1 签名验签 SSWINAPI SGD UINT32 DEVAPI SKF ECCSignData SGD HDL
  • xshell之for循环

    转载于 xff1a shell while read line 与for循环的区别 冥想心灵 博客园 cnblogs com 例子 xff1a while read line 是一次性将文件信息读入并赋值给变量line xff0c whil
  • virtualbox安装虚拟增强功能

    1 分配光驱 xff0c 选择windows的光驱 2 会发现出现了CD驱动器VBoxGuestAdditions 双击进去 xff0c 发现目录如下 xff1a 3 双击执行VBoxGuestAdditions exe
  • #蓝桥杯嵌入式组#历年客观题解析

    文章目录 第八届初赛第八届决赛第九届初赛第九届决赛第十届初赛第十届决赛 第八届初赛 C D 线与功能 xff1a 两个或多个输出信号连接在一起可以实现逻辑 与 的功能 OC门 xff0c 即 集电极开路 xff0c 实际上只是一个NPN型三
  • Git在vscode中简单使用

    Git在vscode中简单使用 一 Git安装与配置 1 Git安装 xff08 官网地址 xff1a https git scm com xff09 2 Git配置 xff08 1 xff09 安装好后 xff0c 桌面右键 Git Ba
  • 小程序云开发入门

    文章目录 前言一 开通云开发二 使用云开发1 直接创建云开发项目2 修改配置文件引入云开发 三 云数据库1 介绍2 使用 四 云函数1 介绍2 使用 五 云存储1 介绍2 使用 总结 前言 一个小程序在开发时 xff0c 除了考虑界面功能逻
  • 小程序Mpx框架入门

    文章目录 简介一 Mpx的特点1 使用原因2 设计思路3 与其他框架的区别 二 安装使用1 相关命令2 项目创建演示 三 Mpx在vscode中的相关插件四 学习Mpx框架开发1 Mpx具有的功能特性2 学习的资源 总结 简介 Mpx是一款
  • 小程序云函数调用云函数

    文章目录 前言一 案例说明二 功能实现1 云函数1 xff1a getdata2 云函数2 xff1a deldata 总结 前言 小程序云开发提供了云函数 xff0c 云函数是运行在服务端的代码 xff0c 执行速度快 通常一些复杂的功能
  • Vue项目打包后不能正常显示页面

    项目场景 xff1a 通过 Vue CLI 创建的 vue 项目 xff0c 编写完项目后 xff0c 通过 npm run bulid 对项目进行打包 xff0c 再把打包得到的内容 xff08 dist文件夹 xff09 交给后端部署到
  • element-ui二次封装实现全局回到顶部组件

    文章目录 前言一 实现方法1 创建 BackTop 组件2 全局注册组件3 使用组件 二 组件效果总结 前言 在开发 vue 项目时 xff0c 我们都可能用到 element ui xff0c 但是有时 element ui 提供的组件太
  • element-ui二次封装实现普通登录组件

    文章目录 前言一 实现方法1 创建 AccountLogin 组件2 全局注册组件3 使用组件 二 组件效果总结 前言 在开发 vue 项目时 xff0c 我们都可能用到 element ui xff0c 但是有时 element ui 提
  • CFCA预置证书

    1 单一证书 2 导入数字证书流程 3 加密证书私钥结构
  • element-ui二次封装实现短信验证码登录组件

    文章目录 前言一 实现方法1 创建 PhoneLogin 组件2 全局注册组件3 使用组件 二 组件效果总结 前言 在开发 vue 项目时 xff0c 我们都可能用到 element ui xff0c 但是有时 element ui 提供的
  • C++之make、cmake和makefile的区别

    make cmake和makefile的区别 make 此工具类似于批处理工具 xff0c 可以对多个源文件进行批量地编译和链接makefile 是一个文本文件 xff0c 其中包含了make工具在执行时所要遵循的一系列规则Cmake xf
  • Ubuntu系统下搭建PX4环境

    Ubuntu系统下搭建PX4环境 首先我是从一个小白开始的 xff0c 完全不懂linux系统 xff0c 完全不懂PX4 xff0c PX4固件是Pixhawk飞行控制器的官方固件 xff0c Pixhawk官网也给出了Linux win
  • mavlink_generator生成器安装过程

    mavlink generator生成器安装过程 从官网下载mavlink xff08 git clonhttps github com mavlink mavlink git 然后进入mavlink 目录执行 git submodule
  • linux系统下QGC地面站和串口助手cutecom 安装教程

    linux系统下QGC地面站和串口助手cutecom 安装教程 解除权限 xff1a sudo usermod a G dialout USER sudo apt get remove modemmanager y sudo apt ins
  • PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题

    PX4中通过串口读取STM32F4串口发送过来消息并发布UORB主题 本次小项目是通过PX4读取STM32F4发过来的数据 xff0c 之前博客介绍了我做的STM32端项目 xff0c 再稍微啰嗦一下 xff1a 解析AIRMAR和测深仪数