双轮平衡车实现自平衡功能

news2024/10/7 16:19:06

1. 功能说明

在双轮小车上安装一个六轴陀螺仪传感器,本文示例将实现双轮小车自主平衡功能。

 2. 电子硬件

      在这个示例中,我们采用了以下硬件,请大家参考:

主控板

Basra主控板(兼容Arduino Uno)

扩展板

Bigfish2.1扩展板

传感器六轴陀螺仪
电池7.4V锂电池

电路连接:

      ① 六轴陀螺仪传感器(GND、VCC、RX、TX)连接在Bigfish扩展板的Gnd、Vcc(3.3v)、RX、TX;

      ② 2个直流电机分别连在Bigfish扩展板的(5,6)、(9,10)。

 3. 功能实现

      编程环境:Arduino 1.8.19

      实现思路:实现小车的自平衡。当人为去打破小车的平衡时,小车能够自行恢复到平衡状态。这里当俯视小车时,小车处于水平位置代表平衡状态;前倾或后仰等均为非平衡状态。

3.1 测试数据

     ① 需要先测出陀螺仪沿Y轴的状态数据。下表是本实验中测试出的实验数据,大家可参考格式,测试出自己的实验数据。

物料

测试数据‍‍

陀螺仪的加速度包Y轴数据

沿Y轴俯仰陀螺仪时,数据从(-0.05,1.13)逐渐增大;

陀螺仪平放时的值为0.74;‍

     ② 找准双轮小车的平衡状态(大家可尝试把锂电池安装在小车底部,让小车默认为平衡态)

 3.2 示例程序

将参考例程(Gyroscope_Control_Car.ino)下载到主控板:

【程序源代码资料内容详见 双轮平衡车-自平衡】

/*------------------------------------------------------------------------------------

 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

 Distributed under MIT license.See file LICENSE for detail or copy at

 https://opensource.org/licenses/MIT

 by 机器谱 2023-04-25 https://www.robotway.com/

 ------------------------------*/

/*  

 功能:自平衡小车

 接线:陀螺仪传感器(GND、VCC、RX、TX)接在扩展板的( Gnd、Vcc(3.3v)、RX、TX);

 直流电机分别接在(5,6),(9,10)

*/

#include<Math.h>

#define Gyroscope_left_LimitAngle_Y  -0.05  //读取到陀螺仪 Y 轴向前的极限数值

#define Gyroscope_Right_LimitAngle_Y  1.13  //读取到陀螺仪 Y 轴向后的极限数值

#define Gyroscope_Middle_LimitAngle_Y  0.74  //读取到陀螺仪 Y 轴平放时的数值

#define Motor_Pin_Count 4


/*

 由于直流电机的物理差异,左右电机的速度值不同;

 需要先微调两电机的pwm值,保证小车能走直线(否则会出现小车原地打转)

*/

#define left_Motor_Speed_Init 60  //左侧电机的初始速度(0-255)

#define right_Motor_Speed_Init 70  //右侧电机的初始速度(0-255)

#define Motor_Speed_Mix 0  //电机速度增量最小值

#define Motor_Speed_Max 20  //电机速度增量最大值


unsigned char Re_buf[11],counter=0; //存储陀螺仪数据的变量

unsigned char sign=0;  //定义是否接收到陀螺仪数据的标志位

float a[3];  //用于存储x、y、z三轴的角速度包数值

int motor_pin[4] = {5,6,9,10};//定义电机引脚

int map_to_int[3] = {0,0,0};  //用于存储Y轴向左偏、向右偏、平放的数值

enum{Forward = 1,Back,Stop};  //定义电机前进、后退、停止三种状态

void setup()

{

 delay(1000);Serial.begin(115200);//打开串口,并设置波特率为115200

 for(int i=0;i<Motor_Pin_Count;i++){

 pinMode(motor_pin[i],INPUT);  //将电机的四个引脚设置为输出模式

 }

 map_to_int[0] = Gyroscope_left_LimitAngle_Y*100;  //重新赋予陀螺仪 Y 轴向前的极限数值

 map_to_int[1] = Gyroscope_Right_LimitAngle_Y*100;  //重新赋予陀螺仪 Y 轴向后的极限数值

 map_to_int[2] = Gyroscope_Middle_LimitAngle_Y*100; //重新赋予陀螺仪 Y 轴平放时的数值

}


void loop()

{

 Get_gyroscope_And_Control();//读取陀螺仪参数,并判断平衡小车前倾、后仰或者是平放状态

}


//实时读取陀螺仪发送的数据(serialEvent()函数会自动运行)

void serialEvent() {  

 while (Serial.available()) {

 Re_buf[counter]=(unsigned char)Serial.read();

 if(counter==0&&Re_buf[0]!=0x55) return;  //第0号数据不是帧头  

 counter++;  

 if(counter==11)  //接收到11个数据

 {  

 counter=0;  //重新赋值,准备下一帧数据的接收

 sign=1;

 }  

 }

}

判断双轮小车前倾、后仰或者是平放状态的参考程序(Gyroscope_Device.ino)如下:

/*------------------------------------------------------------------------------------

 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

 Distributed under MIT license.See file LICENSE for detail or copy at

 https://opensource.org/licenses/MIT

 by 机器谱 2023-04-25 https://www.robotway.com/

 ------------------------------*/

void Get_gyroscope_And_Control()//读取陀螺仪参数,并判断平衡小车前倾、后仰或者是平放状态

{

 int gyroscope_acc_data= 0;

 int map_data= 0;

 if(sign)

 {  

 sign=0;

 if(Re_buf[0]==0x55)  //检查帧头

 {  

switch(Re_buf [1])

{

case 0x51:

 {

a[0] = (short(Re_buf [3]<<8| Re_buf [2]))/32768.0*16;

a[1] = (short(Re_buf [5]<<8| Re_buf [4]))/32768.0*16;

a[2] = (short(Re_buf [7]<<8| Re_buf [6]))/32768.0*16;

 //把陀螺仪的加速度包的Y轴数据转换为直流电机的速度

 map_data = fabs(a[1]) * 100;  //fabs()取浮点数的绝对值

 if( (map_data >= (map_to_int[2]-10)) && (map_data <= (map_to_int[2]+10)) )

 {

 //小车处于平衡态

 Motor_State(Stop,0,0);  

 }

 else if( (map_data < (map_to_int[2]-10)) && (map_data >= map_to_int[0]) )

 {

 /*当小车前倾,自行调整至平衡

 假如现在获取到陀螺仪数据0.50,转换为50并进行映射为直流的pwm值过程

 Motor_State(Forward,60+map(50,64,5,0,20), 70+map(50,64,5,0,20))

 */

 Motor_State(Forward,left_Motor_Speed_Init+map(map_data,(map_to_int[2]-10),map_to_int[0],Motor_Speed_Mix,Motor_Speed_Max),right_Motor_Speed_Init+map(map_data,(map_to_int[2]-10),map_to_int[0],Motor_Speed_Mix,Motor_Speed_Max) );

 }

 else if( (map_data <= map_to_int[1]) && (map_data > (map_to_int[2]+10)) )

 {

 //当小车后仰,自行调整至平衡

 Motor_State(Back,left_Motor_Speed_Init+map(map_data,(map_to_int[2]+10),map_to_int[1],Motor_Speed_Mix,Motor_Speed_Max),right_Motor_Speed_Init+map(map_data,(map_to_int[2]+10),map_to_int[1],Motor_Speed_Mix,Motor_Speed_Max) );

 }  

 }break;

}

 }

 }

}


void Motor_State(int _mode, int _left, int _right)//电机状态函数

{

 switch(_mode)

 {

 case Forward: {analogWrite(motor_pin[0],_right);analogWrite(motor_pin[1],0);analogWrite(motor_pin[2],_left);analogWrite(motor_pin[3],0);}break;

 case Back:  {analogWrite(motor_pin[1],_right);analogWrite(motor_pin[0],0);analogWrite(motor_pin[3],_left);analogWrite(motor_pin[2],0);}break;

 case Stop:  {analogWrite(motor_pin[0],0);analogWrite(motor_pin[1],0);analogWrite(motor_pin[2],0);analogWrite(motor_pin[3],0);}break;

 }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/554153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于网络的思维导图WiseMapping

在退烧了一天半之后&#xff0c;老苏的抗原终于变两道杠了。之前还总怀疑自己是无症状&#xff0c;大意了&#xff0c;被新冠给查缺补漏了 &#x1f602; 什么是 WiseMapping &#xff1f; WiseMapping 是一款基于网络的免费思维导图产品。该项目的目标是提供可由企业、教育和学…

Java面试知识点(全)-分布式和微服务-dubbo面试知识点

Dubbo是什么&#xff1f; Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架&#xff0c;现已成为 Apache 基金会孵化项目。 面试官问你如果这个都不清楚&#xff0c;那下面的就没必要问了。 官网&#xff1a;http://dubbo.apache.org 为什么要用Dubbo&#xff1f…

内存泄漏之DispatcherTimer

https://www.jianshu.com/p/7e9ecb383bd0 我们经常会在程序中使用DispatcherTimer&#xff0c;但是如果一不小心就会发生内存泄漏&#xff0c;请看下面的Demo&#xff1a; 内存泄漏代码 我创建了一个简单的窗口Example1.xaml&#xff1a; <Window x:Class"MemoryLea…

Keep your Eyes on the Lane Real-time Attention-guided Lane Detection 论文精读

关注车道&#xff1a;实时注意力引导车道线检测 摘要 现代车道线检测方法在复杂的现实世界场景中取得了显著的性能&#xff0c;但许多方法在保持实时效率方面存在问题&#xff0c;这对自动驾驶汽车很重要。在这项工作中&#xff0c;我们提出了LaneATT&#xff1a;一种基于锚点…

【降维打击】T分布随机近邻嵌入(T-SNE)Python实践

近几天看到论文里面有T分布随机近邻嵌入&#xff08;T-distributed stochastic neighbor embedding, T-SNE&#xff09;这种可视化方法&#xff0c;以前好像也看到过&#xff0c;但没有系统了解过&#xff0c;现有时间正好实践记录一下。 1. T-SNE简介 T-SNE是一种降维方法&am…

搭建监控日志系统

在微服务或者集群架构中&#xff0c;一次请求的调用会跨多个服务&#xff08;web&#xff0c;mysql&#xff0c;feign等&#xff09;、多个模块&#xff08;用户模块&#xff0c;商品模块等&#xff09;、多个容器&#xff08;用户模块可能有多个实例&#xff09;&#xff0c;这…

【科普】干货!带你从0了解移动机器人(二)—— 移动机器人硬件组成

移动机器人是一个多功能于一体的综合系统&#xff0c;内容涵盖了传感器技术、自动化技术、信息处理、电子工程等&#xff0c;它集环境感知、动态决策与规划于一体&#xff0c;是目前科学技术发展最活跃的领域之一。移动机器人的各种组件之间需要协同工作才能实现机器人的自主移…

【源码解析】RuoYi-Vue-Plus翻译功能 Translation 源码分析

类说明功能Translation通用翻译注解标注需要翻译的字段&#xff0c;用于实体类字段上TranslationType翻译类型注解标注翻译字段的实现类型&#xff0c;用于实现类上标注TransConstant翻译常量TranslationType 类型常量TranslationConfig翻译模块配置类配置初始化&#xff0c;设…

深度学习基础入门篇[9.2]:卷积之1*1 卷积(残差网络)、2D/3D卷积、转置卷积数学推导、应用实例

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

一文了解customRef 自定义ref使用

概念 按照文档中的说明&#xff1a;customRef 可以用来创建一个自定义的 ref&#xff0c;并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数&#xff0c;该函数接收 track 和trigger函数作为参数&#xff0c;并且应该返回一个带有 get 和 set 的对象。 其实大致意思…

公有云——阿里云ECS服务器入门精通(IaaS)(2)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 一.ECS 实例规格族介绍 1.实例的架构类型、规格分类&#xff0c;详细信息 2.企业…

网络互联与互联网 - IP 子网划分详解

文章目录 1 概述1.1 划分目的1.2 划分原则1.3 子网掩码 2 IP 子网划分示例3 网工软考真题3.1 判断网络号和主机号3.2 计算可容纳的主机数3.3 子网划分 1 概述 IP 子网划分&#xff1a;实际上就是设计 子网掩码 的过程。原因&#xff1a;由于在五类的IP地址中&#xff0c;网络号…

【SpringBoot】数据校验API

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 数据校验API SpringBoot数据校验数据校验API的…

智能电动「唱主角」,哪些供应商在「领跑」智驾域控制器赛道

新势力&#xff0c;从哪里突围&#xff1f; 造车新势力在过去几年的成绩&#xff0c;已经代表了未来趋势&#xff1a;新能源汽车&#xff0c;尤其是纯电动。而对于智能化软硬件供应商&#xff0c;尤其是新势力供应商来说&#xff0c;亦是如此。 高工智能汽车研究院监测数据显…

深度学习框架-Tensorflow2:特点、架构、应用和未来发展趋势

引言 深度学习是一种新兴的技术&#xff0c;已经在许多领域中得到广泛的应用&#xff0c;如计算机视觉、自然语言处理、语音识别等。在深度学习中&#xff0c;深度学习框架扮演着重要的角色。Tensorflow是一种广泛使用的深度学习框架&#xff0c;已经成为深度学习的事实标准。…

全民拼购为什么能躺赢

大家好&#xff01;我叫小鱼 新商业&#xff0c;新模式 新机会&#xff01; 我们在拼购过程中 往往都觉得商家在亏钱 事实如此吗&#xff1f; 随着全球经济下行&#xff0c;党中央、国务院 高度重视发展流通扩大消费。 为推动流通创新发展&#xff0c;促进商业繁荣&#xff0c;…

回文子串问题

一&#xff1a;最长回文子串&#xff08;leetcode 5&#xff09; 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#x…

盛元广通疾病预防控制中心检测管理信息系统

近些年&#xff0c;在疾病预防控制领域&#xff0c;公共卫生事件的发生都是通过信息化手段在日常工作中加以应用以及广泛深入的探索&#xff0c;加快疾控实验室信息化建设进程&#xff0c;可以有效把控不同类型检测任务中的每个节点&#xff0c;严防不同系统填报多次出现信息误…

SpringBoot——热部署

简单介绍&#xff1a; 在之前我们的项目中&#xff0c;当我们在编写了一个新的类并且要应用的时候&#xff0c;需要手动重启服务器重新部署一下&#xff0c;这个过程需要我们手动去完成&#xff0c;但是很多时候&#xff0c;比如我们在做测试&#xff0c;需要反复的修改代码&a…

第14章_视图

第14章_视图 1. 常见的数据库对象 对象描述表(TABLE)表是存储数据的逻辑单元&#xff0c;以行和列的形式存在&#xff0c;列就是字段&#xff0c;行就是记录数据字典就是系统表&#xff0c;存放数据库相关信息的表。系统表的数据通常由数据库系统维护&#xff0c;程序员通常不…