Pixhawk原生固件PX4之串口添加读取传感器实现

PX4-串口通讯 本文为了记录最近开发PX4的串口通讯的一些心得。 阅读详情

本博客承接前一篇,对FreeApe的串口添加超声波传感器博文后半部分进行学习。

为什么叫前奏呢,因为用了伪传感器,把单片机用串口发送的有规律的数据当作了传感器读取到的数据。但是无碍的。

开发环境:Ubuntu Firmware 1.4.1

在无人机运行时,首先是要将应用随系统启动时就启动起来的,且将获得的超声波数据不断的发布出去,从而让其他应用得以订阅使用。这里也使用Pixhawk里面的通用模式,即主线程,检测app命令输入,创建一个线程来不断的发布数据。

定义主题和发布主题

  • 在Firmware/msg目录下新建read_uart_sensor.msg文件。传送门
char[4] datastr
int16 data

#TOPICS read_uart_sensor

 
  • 1
  • 2
  • 3
  • 4
  • 5

并添加到CMakeLists.txt中,编译后自动生成uORB/topics/read_uart_sensor.h头文件

串口读取例程

在Firmware/src/modules目录下新建文件夹read_uart_sensor

/*
 * read_uart_sensor.c
 * 
 * read sensor through uart
 */

#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/read_uart_sensor.h>

__EXPORT int read_uart_sensor_main(int argc, char *argv[]);


static bool thread_should_exit = false; /*Ddemon exit flag*/
static bool thread_running = false;  /*Daemon status flag*/
static int daemon_task;

/**
 * Main loop
 */
int read_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;

    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: read_uart_sensor {start|stop|status} [param]\n\n");
    exit(1);
}

int read_uart_sensor_main(int argc, char *argv[])
{
    if (argc < 2) {
        usage("[Fantasy]missing command");
    }

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

        thread_should_exit = false;
        daemon_task = px4_task_spawn_cmd("read_uart_sensor",
                         SCHED_DEFAULT,
                         SCHED_PRIORITY_MAX - 5,
                         2000,
                         read_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("[Fantasy]running");
            return 0;

        } else {
            warnx("[Fantasy]stopped");
            return 1;
        }

        return 0;
    }

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

int read_uart_thread_main(int argc, char *argv[])
{

    if (argc < 2) {
        errx(1, "[Fantasy]need a serial port name as argument");
        usage("eg:");
    }

    const char *uart_name = argv[1];

    warnx("[Fantasy]opening port %s", uart_name);
    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(uart_name);
    if(false == uart_read)return -1;
    if(false == set_uart_baudrate(uart_read,9600)){
        printf("[Fantasy]set_uart_baudrate is failed\n");
        return -1;
    }
    printf("[Fantasy]uart init is successful\n");

    thread_running = true;

    /*初始化数据结构体 */
    struct read_uart_sensor_s sensordata;
    memset(&sensordata, 0, sizeof(sensordata));
    /* 公告主题 */
    orb_advert_t read_uart_sensor_pub = orb_advertise(ORB_ID(read_uart_sensor), &sensordata);

    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;
                data = '0';
            }
            strncpy(sensordata.datastr,buffer,4);// 复制字符串Buffer中前4个数字到Datastr中
            sensordata.data = atoi(sensordata.datastr);//将字符串转换成整形数据
            //printf("[Fantasy]sensor.data=%d\n",sensordata.data);
            orb_publish(ORB_ID(read_uart_sensor), read_uart_sensor_pub, &sensordata);
        }
    }

    warnx("[Fantasy]exiting");
    thread_running = false;
    close(uart_read);

    fflush(stdout);
    return 0;
}

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 添加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 : 

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 在Firmware/cmake/configs/nuttx/nuttx_px4fmu-v2_default.cmake中注册该模块

测试发布的主题

  • 测试可以随便一个启动的app中进行主题订阅,然后将订阅的数据打印出来,看是否是超声波的数据。这里新建一个应用px4_test进行测试。

px4_test.c

/*
 * px4_test.c
 *  
 * test the uart sensor app
 */
#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/read_uart_sensor.h>

__EXPORT int px4_test_main(int argc, char *argv[]);

int px4_test_main(int argc, char *argv[])
{
    PX4_INFO("Hello Sky!\n");

    /* subscribe to rw_uart_sensor topic */
    int sensor_sub_fd = orb_subscribe(ORB_ID(read_uart_sensor));

    /*limit the update rate to 20 Hz */
    orb_set_interval(sensor_sub_fd, 50);


    /* one could wait for multiple topics with this technique, just using one here */
    px4_pollfd_struct_t fds[] = {
        { .fd = sensor_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++) { // infinite loop
        /* 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_test] 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_test] 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 read_uart_sensor_s raw;
                /* copy sensors raw data into local buffer */
                orb_copy(ORB_ID(read_uart_sensor), sensor_sub_fd, &raw);
                PX4_INFO("[px4_test] sensor data:\t%s\t%d\n",
                       raw.datastr,
                       raw.data);
            }

            /* there could be more file descriptors here, in the form like:
             * if (fds[1..n].revents & POLLIN) {}
             */
        }
    }

    PX4_INFO("exiting");

    return 0;
}

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 编译并上传固件

    • make px4fmu-v2_default upload
  • 在NSH中测试

    • read_uart_sensor start /dev/ttyS2
    • px4_test
result

这个大有搞头!

添加到脚本文件

在rcS中仿照mavlink的启动方式添加了上面的应用,使得与ttyS2连接的外设默认为启动状态

rcS

现在如果ttyS2上连接了设备,就是自动启动的,在nsh中可以直接调用px4_test应用就可以读取数据了,与使用px4_simple_app读取内部传感器的方式无异。

大致模型就是这样了,接下来就是具体的代码优化以及应用了。


                                          By Fantasy

PX4固件通过UART连接串口读取超声波,和树莓派3通信 添加串口读取程序首先在Firmware/msg文件夹下添加rw_uart.msgchar[5] datastr int16 data #TOPICS rw_uart记住在这一文件夹下的CMakeLists.txt下注册这个msg,添加rw_uart.msg即可。 上面的文件make之后会自动产生rw_uart.h头文件,里面会有结构体rw_uart_s,存取了我们刚才定义的data和datas 阅读详情

相关推荐

别再傻傻分不清了!Pixhawk、PX4、QGC到底谁是谁?给无人机新手的保姆级扫盲指南

本文为无人机新手详细解析Pixhawk、PX4和QGC三大核心组件的关系与功能。Pixhawk作为硬件飞控系统,PX4是开源飞控固件,QGC则是地面站控制软件,三者协同工作构成完整的无人机控制系统。文章提供硬件选型、软件配置和实战指南,帮助开发者快速入门无人机开发。

weixin_33686714的博客 632

Pixhawk之获取传感器数据并更新姿态

博主:llq_ARM 声明:尊重版权,转载请注明出处。 原文地址: 联系方式:595493514@qq.com 技术交流QQ:595493514       read_AHRS();是负责更新姿态函数,更新姿态要获取传感器数据进行姿态解算,我们先来分析下传感器是怎么读取的。read_AHRS();调用的是ahrs.update();ahrs是类AP_AHRS_NavEKF的一个实例

llq_ARM的专栏 6620

Pixhawk固件加载深度指南:从刷写到飞行的全链路解析

Pixhawk固件加载远非简单的固件烧录,而是嵌入式飞行控制系统的一次原子性重载,涉及硬件握手协议(如DFU/CDC)、固件架构(Bootloader→Application→Parameter)与平台适配(Board ID、传感器标定链)三重耦合。理解其底层原理,是保障无人机稳定悬停、精准定位与安全飞行的技术前提。该过程直接影响IMU温漂补偿、RC通道映射、EKF2状态估计等关键飞行性能,广泛应用于农业植保、穿越竞速、光流室内导航等场景。本文聚焦PX4固件在Pixhawk系列飞控上的加载机制、参数归零逻辑

chongyuwan4121的博客 418

pixhawk-px4之通过串口添加传感器应用

前言: 看到有博客通过串口添加自定义传感器,按照步骤做了一遍 博客:http://blog.youkuaiyun.com/msq19895070/article/details/52012190 一 串口选择 Pixhawk板上TELEM2接口的USART2,对应的Nuttx UART设备文件尾/dev/ttyS2 二 添加应用 step 1:在Firmware/src/mod

点滴记录 6268

无人机飞控技术解析:PX4、PIXHAWK与APM的关系与选型指南

飞行控制器是无人机、无人车等自主移动平台的核心大脑,负责处理传感器数据并执行控制算法。其技术栈通常涉及硬件平台、软件框架及操作系统等多个层面。在开源飞控领域,PIXHAWK作为一套广泛采用的硬件设计标准,提供了高性能的双处理器架构与丰富的传感器接口,成为承载飞控软件的通用硬件平台。而PX4则是一个专为自主飞行器设计的开源软件栈,它基于NuttX实时操作系统,采用模块化设计并通过uORB通信机制实现高效数据交换,为无人机控制提供了高可靠性与可扩展性。这两者共同构成了现代无人机开发的基础,广泛应用于教育研究、快

weixin_30294295的博客 434

PX4从放弃到精通(十九):串口驱动

文章目录前言一、创建进程二、编写驱动 前言 硬件: PIXHAWK4 USB转串口模块 软件: Ubuntu18.04 PX4 1.11.3固件 QGC地面站 串口助手 一、创建进程 参考:https://mbot1.blog.youkuaiyun.com/article/details/122587617 二、编写驱动 .........

超维空间科技的博客 4597

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

串口读个数据都这么费劲…… orz

FantasyJXF的博客 1万+

Pixhawk飞控板PCB设计与技术资料大全

Pixhawk PCB资料包是开发者和工程师在进行自主飞行器设计时不可或缺的工具集。该资料包包括硬件设计文件、固件源码、开发文档以及用于调试和测试的工具。它为技术人员提供了一个起点,以深入理解Pixhawk硬件平台及其与PX4开源飞行堆栈的集成方式。数据融合是结合来自多个传感器的数据,以获得比单一传感器更加准确、可靠信息的过程。在无人机中,这通常涉及姿态估计、速度和位置的计算。数据融合的几种常见技术包括:加权平均法:对来自不同传感器的数据赋予不同的权重,然后计算加权平均值。

weixin_33363025的博客 1436

PIXHAWK源码分析之三---通过串口方式添加一个自定义传感器

关键是这个uORB 摘自:https://blog.youkuaiyun.com/msq19895070/article/details/52012190?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159684289919195264534597%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=1596842899191

自主无人机 PX4 ROS SLAM 路径规划 MVS等技术分享 882

Pixhawk 2.4.8硬件驱动全解析:从固件烧录到传感器校准

在无人机飞控系统中,硬件驱动是连接芯片与传感器的底层桥梁。飞控驱动并非简单的USB安装程序,而是涵盖板级外设驱动、通信协议与固件配置在内的一整套机制。理解驱动分层原理,有助于快速定位传感器数据异常、设备识别失败等问题。其技术价值在于:只有底层驱动正确加载并完成校准,上层姿态解算与飞行控制才具备可靠基础。从教学实验到算法验证,Pixhawk系列一直是学习飞控驱动的典型平台,其中Pixhawk 2.4.8因保有量大、资料丰富,成为入门首选。本文围绕Pixhawk 2.4.8硬件驱动,系统讲解固件烧录、传感器校准

weixin_29173777的博客 271

PX4驱动 解决Pixhawk/PX4在精简windows系统上驱动安装失败问题

PX4串口驱动 双击下载的px4_driver_installer_v10_win.exe驱动安装文件,按步骤一路next即可完成pixhawk驱动安装(默认安装目录为C:\px4_drivers)。如果是正版windows系统,连接pixhawk飞控板,在设备管理器的端口下会有PX4 FMU(COMX)出现。

PX4 Pixhawk Standard Autopilots:Pixhawk 标准飞控板卡全解析与选型指南

本文围绕 PX4-Autopilot 仓库中「Pixhawk Standard Autopilots」官方文档展开,系统梳理 Pixhawk 标准飞控的准入门槛、支持等级、当前在产/在售的 18 款标准板卡清单、FMU 版本演进脉络与 FMUv6 三档硬件规格对比,并结合 `boards/` 目录下的真实板卡工程(.px4board、firmware.prototype、board_config.

gitblog_00353的博客 1045

PX4Flow的I2C读取数据

px4flow光流传感器的iic读取数据注意事项,稍微懂些iic的就可以把光流数据读出来。

PX4串口驱动的三种方式:系统级操作、task/work_queue、类似PX4IO中断响应

因为项目需要,需在px4实现与stm32F407串口通信功能,以200Hz双工交互数据,所以探究了3种不同的串口驱动方式。三种方式概况参考了AcmeUavs公众号的文章:[PX4-6-串口设备驱动](https://mp.weixin.qq.com/s/YihvO2KFzPHBtfbm8StDLQ),本篇主要详细记录自己摸索3种方式的过程。

baidu_41704597的博客 2783

麒麟OS恢复出厂设置原理与实操:非重装的系统状态回滚

Linux操作系统中的‘恢复出厂设置’并非简单重装或镜像还原,而是一种基于状态快照、包管理与配置模板的可控回滚机制。其核心原理依赖LVM快照技术、RPM包签名验证和预置配置模板,兼顾系统稳定性与用户数据安全。该方案在政务、教育等国产化场景中具有显著技术价值——不格式化硬盘、不丢失/home文档、不重配驱动与授权,大幅降低运维复杂度。典型应用场景包括系统卡顿修复、软件冲突清理、桌面环境异常恢复等。本文深入解析银河麒麟V10的kylin-restore-cli工具链与麒麟管家集成逻辑,聚焦‘恢复出厂设置’这一高

weixin_30879169的博客 770

Visio 2013安装遇阻?手把手教你搞定注册表权限错误1402(附64位系统特殊处理)

本文详细解析了Visio 2013安装过程中常见的注册表权限错误1402问题,特别是在64位系统下的特殊处理方法。通过分步指导如何修改注册表权限、处理Wow6432Node分支以及使用高级工具如subinacl,帮助用户顺利完成安装并避免常见连带问题。

t8u9v0w1x的博客 541

百度网盘Mac版下载100KB/s怎么提速?BaiduNetdiskPlugin-macOS 完整安装与原理指南

凌晨一点开始备份,进度条却显示"剩余超过 1 天",这是百度网盘 Mac 客户端非会员的常态。开源项目 BaiduNetdiskPlugin-macOS 干的就是这件事:去掉客户端本地的下载速度限制,让账号在本地表现为 SVIP。 ## 30 秒看懂:它能动什么、动不了什么 **✅ 能** - 仅限 macOS,且只适配百度网盘 Mac 客户端 2.2.2 - 修改全部发生在本地:SVIP

gitblog_00354的博客 394

基于PlatformIO与CMSIS的STM32库函数开发实战:从环境搭建到外设驱动

本文详细介绍了基于PlatformIO与CMSIS的STM32库函数开发实战,从环境搭建到外设驱动实现。通过对比传统IDE,PlatformIO结合CMSIS框架在跨平台开发、代码可移植性和调试体验上更具优势。文章包含PlatformIO.ini配置详解、GPIO/USART驱动开发实例及常见问题解决方案,帮助开发者高效完成STM32项目开发。

weixin_29190169的博客 421

Holybro Pixhawk 5X 飞控详解:基于 FMUv5X 标准的 PX4 硬件平台、接口映射与固件构建

Pixhawk 5X 是 Holybro 与 PX4 团队合作推出的最新一代 Pixhawk 系列飞控,基于开源 FMUv5X 标准设计,预装 PX4 Autopilot 固件,具备三重冗余 IMU、双冗余气压计与隔离传感器域等特性。本文以 [docs/en/flight_controller/pixhawk5x.md](https://link.gitcode.com/i/d11807f43e5

gitblog_00296的博客 198

黑猫带你学eMMC协议第26篇:eMMC的硬件复位操作(H/W reset)

本文依据eMMC JEDEC5.1及个人工作经验整理而成,如有错误请留言。 文章为个人辛苦整理,付费内容,禁止私自转载。 文章所在专栏:《黑猫带你学:eMMC协议详解》 1 概述 什么是硬件复位? 硬件复位就是使用一个特殊硬件信号(这个信号在RST_n这根实实在在的物理线路上传输)将emmc复位到pre-idle state,而不需要使用cmd0或者power cycle讲emmc复位到pre-idle state。 如何进行硬件复位? 1、设置RST_n_FUNCTION [162]为1,使emm.

黑猫奥利奥的博客 6316

三菱MC协议(MC/TCP):避坑指南|C#实现三菱MC协议:软元件(X/Y/M/D)读写与帧格式解析

核心避坑逻辑:MC协议的坑80%集中在“PLC配置”“地址编码”“字节序”,先解决这三点,通信就成功了一半;实战优先级:新手优先用开源库(Mitsubishi.MCProtocol),避免手动拼接帧格式的复杂坑;进阶再研究帧格式解析;排坑技巧:先Ping通→用调试助手验证→写C#代码,分层排查,不要混在一起找问题。掌握这些避坑技巧后,你可以轻松实现C#与三菱全系列PLC的稳定通信,满足工业场景中数据采集、设备控制等核心需求。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2189

pixhawk PX4FMU和PX4IO最底层启动过程分析

首先,大体了解PX4IO 与PX4FMU各自的任务 PX4IO(STM32F100)为PIXHAWK 中专用于处理输入输出的部分,输入为支持的各类遥控器(PPM,SPKT/DSM,SBUS), 输出为电调的PWM 驱动信号, 它与PX4FMU(STM32F427)通过串口进行通信 PX4FMU :各种传感器数据读取、姿态解算、PWM控制量的计算、与PX4IO通信 进入主题 PX

czyv587的博客 2万+

“华为杯”研究生数学建模竞赛2017年-【华为杯】B题:面向下一代光通信的 VCSEL 激光器仿真模型

得出以下主要结论:在相同的偏置电流条件下,随着温度的升高,带宽的峰值向。在相同的温度下,随着电流的增大,带宽的峰值越小且曲线由波峰形状。方案,包括可能的数学公式,不同温度和偏置电流下的带宽响应曲线,并与问题。线,得出以下主要结论:在相同的偏置电流条件下,随着温度的升高,带宽的峰。在相同的温度下,随着电流的增大,带宽的峰值越小且曲线由波峰形状逐渐变得。得的激光器特性曲线和模型中仿真得到的特性曲线,之后,可以将两组曲线的差。说明的是,由于数值优化算法的成功与否很大程度上依赖于初始参数的猜测,参。

getusushu的博客 97
上一篇: float与double类型区别比较
下一篇: Windows / Ubuntu操作系统下Pixhawk原生固件PX4的编译方法
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值