乐鱼app苹果手机下载

基于RTT驱动“舵机转向小车”的实现过程

时间: 2024-06-20 11:32:49 |   作者: 内燃叉车


  的学生提供一个方便使用的控制素材,我设计了一个轮式驱动单元,其最大特点是将驱动和码盘反馈集成到一起,用几个TTL电平线就可以驱动,和舵机的驱动类似,这样使用时能够准确的通过喜好、需要随意选择核心板驱动

  可以用它构建不同驱动方式的小车底盘,最简单的一种驱动方式是使用一个轮式驱动单元加一个舵机实现的“单轮驱动舵机转向小车”,它的运动方式和现实世界中的电动叉车类似

  因这种驱动方式小车的转向和行走两个主要控制元素相互独立,从学习编程角度考虑,相对于两轮差分驱动方式更简单、容易。

  当时目标是降低学习门槛,故选了Arduino作为控制器。为便于接线,选择了市场上的一种 Nano 扩展板,其外形和UNO一样,只是将每个IO都配了一个地线和电源端,用杜邦线连接十分方便

  后来觉得Arduino Nano控制器资源太少,考虑改用主流的STM32F103C8T6核心板,但Nano扩展板的构思不错,边参考它自己设计了一块 STM32F103C8核心板的扩展板

  由于大环境影响,国产OS被重视,在RTOS领域,RT-Thread无疑是国产系统中的佼佼者。故萌生了在小车平台上尝试一下的念头,既然有可以方便使用的STM32F103C8扩展板,又有和STM32F103C8核心板兼容的STM32F411CE核心板,小车的控制也应该提升一下,跑跑我们自己的RTOS。

  下面将完整地记录实施过程,期望能对想选用 RT-Thread 开发产品的朋友有帮助,因为小车控制相对实时性要求比较高,有真实的多任务需求,不同于HMI(人机界面)类应用,用事件驱动即可,没那么强的实时性、并发性要求。

  按实时多任务的思路,基于 RT-Thread,完成小车驱动,并能够最终靠串口(蓝牙透传)操纵小车运动。

  因为RT-Thread 的特色是有丰富的组件和软件包可以扩展,但要享用这些,必须是标准版;如果用Nano版,和FreeRTOS区别不大。故选择RT-Thread标准版。

  我做项目通常是先构思程序框架,将所需完成的功能合理拆解,根据功能确定框架。

  选用成熟的RTOS,只是有了多任务实现的手段和工具,程序框架还要自己设计。

  对于基于RTOS的程序而言,首先要设计的就是任务(在RT-Thread中为线程),根据RTOS所提供的工具,结合自己想要实现的功能,合理划分任务,创建相应的线程,并确定线程之间的交互方式及内容,从而完成一个基于RTOS的多任务控制程序。

  任务划分的首要目标是相对独立,即所构建的任务是完整的,有清晰的输入消息和输出结果,其工作只是对输入进行相应处理,给出输出,中间过程不受其它因素所牵制。

  其次是任务可一次完成,中间没有长时间的等待操作,任务通常是处在等待输入的状态,收到输入后,即刻完成对输入的处理,输出结果,之后再次回到等待输入状态。

  这样设计主要是因为:所谓多任务操作,表面上看每个任务都在连续执行,实质上MCU还是分时处理各个任务,只是通过RTOS在后台切换。

  RTOS调度的方式决定了各个任务的分配时间和响应速度,各家RTOS的调度方式虽有不同,但都遵循一个原则:即处于等待状态的任务不分配运行时间,这样才可以使程序达到最佳效率。

  使用RTOS的等候消息函数,就是告知OS,我目前“没事”,在等新的消息。

  基于这样的形式构建任务除了保证程序的执行效率和实时性外,还便于调试。可人为注入消息触发任务执行,观察输出结果是不是满足设计即可。还能够用多模块方式,一个任务一个模块,由多人分别编写、合作完成。

  基于RTOS编程,考虑到其多任务的特点,通常是先做一个基础框架,再根据不同的场景设计相应的任务。

  所谓“基础框架”,就是结合单片机应用的特点,将一些通用需求纳入,这样在每次做新的项目时以此为基础,增加新的功能即可。

  1)串口命令接收:作为人机交互通道,代替以往通过按键实现的程序操控手段。操作命令的产生可以用PC、手机之类有丰富交互手段的设备,比实体按键更为灵活、直观、丰富。

  2)串口数据发送:作为人机交互通道,代替以往通过显示器实现的信息输出,一样能用PC、手机之类的设备接收后显示,界面设计远比显示屏灵活、丰富、随心所欲。之所以将收、发分开,是考虑到输出信息需要服务于所有任务,以便功能设计更为合理。

  3)调试信息输出任务:在没有或不可以使用IDE调试手段时,需要在程序中输出相应的调试信息,以实现 Debug ;不过,RT-Thread 内置Finsh 十分完善,故选用RT-Thread则不再要设计此任务,这是 RT-Thread 优点之一。

  4)看护任务:利用RTOS的信息交互机制,周期性地与各任务交换信息,当出现不应答时,说明对应的任务工作异常,可以做相应的操作。这样处理无需复位,导致其它任务被非正常中断,增加了程序的可靠性。即便不处理,也能利用调试信息输出及时有效地发现是哪个任务异常,以便消除隐患。

  5)主应用任务:前面几个任务属于框架的基础任务,未涉及程序需要执行的实际功能,主应用任务就是实现具体功能的核心。设计主应用任务是考虑到一般来说,程序均有一个核心的部分,用于管理、协调一些子功能,使得程序运行有序;它相当于一个管理者。这个在抽象的框架设计时只完成了信息交互,在具体到特定的需求时再完善设计。

  6)其它任务:相当于执行者,完成特定的功能。同上,这个任务在框架设计时只是完成和主应用任务的信息交互,具体实施时再详细设计。

  1、接受串口操作命令,解析并执行。具体而言就是2个命令:按指定速度前进或后退指定距离、转向角度。

  据此,考虑设置两个执行任务:电机驱动、舵机驱动,以及一个主应用任务,负责接受、解析操作命令,将相应操作信息发送给相应的执行任务。

  舵机的操作方式按道理无需单设为一个任务,因为它自身闭环,无需程序去处理反馈和修正。但考虑到逻辑上的独立性,以及未来用多个舵机和轮式驱动单元构成的全向小车驱动,舵机转向构建为一个独立的任务有助于程序的可维护性和可扩展性。

  1)主应用任务:解析所设计的操作命令,将命令参数提取后发送给相应的执行任务,并应答。

  2)电机驱动:接收执行参数实现PWM电机驱动,并根据码盘反馈实现调速和行走距离控制,反馈当前运作时的状态给主应用任务。

  3)舵机驱动:接收执行参数,执行舵机操作;基于舵机特性,反馈舵机当前状态(正在运行、已到位)。

  一个任务常常需要接收多个消息,而且是来自不同的任务;为实现将这些消息通过一个等待函数获取,RTOS提供了一个方便的手段:事件组;即将若干消息汇总在一起,一个消息对事件的一位;而且等待的方式也很灵活,可以是“与”的关系,即所关注的各个消息都出现才触发;也可以是“或”的关系,即出现任意一个消息就触发。

  事件组虽然解决了等待多个消息的问题,但所传递的内容往往不够,一个消息有时包含许多参数,如通讯命令的内容。

  邮箱只传送一个字(4字节),很多时候也不够,我习惯于用邮箱传递存放数据的指针,将要传送的消息定义为一个数据结构,通过指针传送,这样比较灵活。

  曾经用过队列传输,但需要预先确定队列项长度,很难一次规划到位,后期修改挺麻烦,故改用邮箱。

  串口是作为单片机的操作输入通道,取代传统模式下的按键操作。通过串口命令操作单片机远比设计实体按键灵活方便,而且

  硬件资源占用也少。此任务要实现对串口命令的接收和初步解析,将命令内容转发给主应用任务处理。

  通讯协议的定义也是串口命令的重点,要考虑的简洁性和可扩展性的平衡,同时要兼顾应用场景的需求。

  ROS)中的ROS Serial 协议设计的。因为小车有无线通讯的需求,故在协议中有相应的通讯地址,以便在一个通道上实现多机通讯。串口通讯协议如下:

  0xFF 0xFE(2字节帧同步字) 帧长L 帧长H 帧长校验和 目标地址 源地址 帧数据区 帧校验和

  帧长 —— 帧数据区数据字节数,不含帧校验和、目标地址和源地址;先低后高,最大支持65535字节,实际不一定需要,但有可能超过256字节,所以用2字节。

  帧长校验和 —— 2字节帧长算数和取反,取最低字节。借鉴ROS Serial协议

  帧校验和 —— 数据区所有字节的算数和取反,取最低字节。如果数据长度为0,则CS为0xFF。

  至于 Val的数据如何定义,取决于 Key,可以定义为结构、数据、或者更复杂的数据,也可以简单的定义为字节、字、整形。

  由于上述协议定义的是变长帧,无法对整个数据帧进行滑窗比较,只能基于协议,找到帧头的特征后,再对整个数据帧接收,之后再通过校验判断此帧是否正确。

  目的是为了在小车运行过程中检测特定变量的值,从而发现程序出现的问题,类似于在IDE环境下设置断点,停下程序后检查内存变量值。

  将需要监测的变量设计为全局变量或静态变量,在编译产生的 map 文件中可以查到相应的地址,通过读内存操作可随时观察变量的变化。

  RAMROM、硬件工作寄存器均在一个地址空间,因此还能够最终靠读内存功能监测MCU相应硬件的工作状态(读取相应寄存器值),以确定初始化是不是正常,运行是不是正确。这个功能作为调试信息输出的补充,可以使调试手段更为丰富。调试信息输出需要预先嵌入一段代码,而读内存操作可以每时每刻使用,只要对象不是动态变量。

  te,L-H)读字节数(1byte)读取从数据地址开始的N字节数据,用于调试及故障远程诊断。

  从数据地址开始写 N 字节数据,用于调试,及临时性的参数设置,需要保护,以免引起程序崩溃。

  如果写失败(所写地址不在允许范围内容,或长度超过设定),则实际写字节数为 0。

  LED数码管作为信息输出手段;但目前多数单片机系统已不需要这样设计,通过串口输出信息,使用PC、手机这类显示功能完善的设备作为单片机系统信息输出的呈现手段,比、LCD屏更为直观、灵活、美观,而且占用硬件资源极少。因程序框架是多任务方式,理论上各个任务都有输出信息的需求,故将串口发送功能独立设计为一个任务,可以服务于所有任务。

  为减少内存消耗,发送数据传递消息只传输存放指针,发送任务依据数据结构定义,取出要发送的数据。串口发送速度和内存操作相比慢很多,要发送的数据放置在各自任务中,在每次需要发送前,需要确定上次数据是不是取走,以避免数据覆盖,导致发送数据错误。

  看护任务的设计目前只是示意性的,没有实质的恢复处理。因为恢复处理应该要依据具体功能确定,没有统一的方法。

  多数单片机系统虽无需显示器,但工作状态指示通常都有,可直观的反映系统是否在正常运行,一般是通过LED的闪烁变化呈现。

  此处参考FreeRTOS的异常指示方式设计了LED显示功能,正常时,LED等间隔闪烁,当发现某个任务异常时,按任务顺序会出现间断闪烁。具体方式为:

  如果是1号任务异常,则一个周期闪烁1次,其余9次对应暗状态;如果是2号,一个周期闪2次、暗8次,以此类推,最多能支持9个任务的异常指示。

  1)解析串口接收任务发来的操作命令,根据命令将参数发给电机驱动和舵机驱动任务。

  0x03 0x09 0x00 电机工作参数(2字节)电机运作时的状态(2字节)电机

  供电电压(1字节)电机供电电流(2字节)舵机操作角度(1字节)舵机当前状态(1字节)电机工作参数:PWM值或速度值

  0x06 0x05 0x00 工作速度(2字节) 运行时间(2字节) 舵机角度(1字节)

  电机速度: 2 字节有符号数,单位:mm/s,正数前进,负数倒退,0 - 惰行,32767 - 刹车,-32768 - 无效速度,不操作

  0x06 0x05 0x00 工作速度(2字节) 运行距离(2字节) 舵机角度(1字节)

  读状态命令则由主任务完成,为提高响应速度,两个驱动任务定时将自身的工作状态反馈给主任务,主任务接收并保存,以便随时响应读状态命令。

  主任务等待的消息为:串口任务发来的命令、电机驱动及舵机驱动反馈的状态、看护任务发来的询问。

  输出的信息为:发给电机驱动及舵机驱动的解析后命令参数,发给串口发送任务的应答信息。

  信号后,电机驱动H桥使电机线圈处于开路状态,电机转子会由于惯性,继续转动到机械阻力使其停止。刹车 —— 是指在停止PWM信号后,电机驱动H桥使电机线圈处于短路状态,电机转子由于惯性转动产生的感应电势形成电流,产生阻力,和机械阻力共同作用使其停止。

  基于正常转动的特征:相邻两个脉冲的周期不会突变(排除干扰造成的脉冲丢失、抖动等异常状况)。

  在测速周期内,一方面对脉冲计数,得到完整脉冲的计数值。同时测量每个脉冲的周期,保存上一个脉冲的周期值(也可以保留前几个脉冲的平均值,以提高可靠性),为计算非完整脉冲做准备。

  当测速周期到时,读取当前脉冲周期测量“已计量的时间“,除保存的“前一脉冲周期值”,即可得到非完整脉冲值 0. XX ,来提升分辨率。

  舵机驱动最简单,输出周期为20ms的脉冲信号,脉冲宽度从1.5 ~ 2.5ms可调。

  C++模式,以便用类的方式简化后续的编程,增加程序的可维护性、可扩展性。在 RT-Thread Studio 环境下,用C++编程,除了在RT-Thread Setting中选择C++外,如果用多文件编程,需将应用的C程序后缀改为cpp,否则编译出错。

  之前在两轮差分小车驱动上尝试过使用 RT-Thread,这次以那个程序为基础修改。

  ADC1,通道1原来程序是驱动差分小车的,控制两个电机,分别对应左、右两侧。为便于日后将程序扩展应用到多轮驱动小车,将电机变量标识从左右侧改为1、2……。目前只有一个电机,故定义为“1”。

  定时器实现。基于STM32F411CE的芯片引脚分配,考虑到后期在大多数情况下要驱动三轮全向小车,选择Timer2作为舵机驱动用定时器,仍然使用PWM模式。

  之前首次尝试 RT-Thread 是做了一个两轮差分驱动的小车程序,在上面完成了电机驱动、测速、调速,以及一直想实现的PID自整定;控制效果不错,基本达到了预期。

  因为后面还想尝试使用 RT-Thread 驱动3轮全向小车,所以保留了电机驱动用类的方式,同时将舵机驱动也做成类,这样后面做三轮小车就很方便了。

  方向。该车采用的方案是主控是STC89C52RC,首先通过手机app与HC—05模块通信,然后通过lL298N模块

  ,以 keil5为开发环境,利用基于 MT9V03X的总钻风数字摄像头作为传感器

  都是基于轮式的,在某宝上面卖的最多的,各位在学生时代拿来应付课程设计和毕业设计用的各种

  程序分享 /

  DA16600 超低功耗 Wi-Fi + 蓝牙低功耗模块开发套件数据手册

  龙芯2K0300蜂鸟板支持OpenHarmony 4.0 Release版本操作系统