基于arduino的避障.跟随小车(带有魔术手)
避障小车的制作方法大概有两种:一个是利用超声波制作,一个是光电开关(避障模块),而跟随小车便一个是利用超声波和光电开关配合制作,一个是光电开关(避障模块)制作。
所以本篇博客,最终决定:用超声波模块制作避障、小车的避障部分;用5个光电开关制作跟随部分。
1、CSDN下载:
① 避障:https://download.csdn.net/download/qq_38351824/11107034
② 跟随:https://download.csdn.net/download/qq_38351824/11107197
③ 魔术手:https://download.csdn.net/download/qq_38351824/11107060
2、可以关注点赞并在下方评论,我给你邮箱发过去。
3、关注微信公众号下载:
① 关注微信公众号:Tech云
②
作者:sumjess
1、避障小车的制作
(1)伪代码部分:
主函数
{
舵机摆正
循环部分
{
c如果超声波采集的数据<X
{
电机停转
舵机左摆
b如果超声波采集的数据<X
{
舵机右摆
a如果超声波采集的数据<X
{
舵机摆正
倒车
}
aelse
{
舵机摆正
电机右转--->停下---->直行
}
baelse
{
舵机摆正
电机左转--->停下---->直行
}
}
celse
{
电机直行
}
}
}
.(2)滤波部分(超声波滤波):算术平均滤波法
/*
A、名称:算术平均滤波法
B、方法:连续取N个采样值进行算术平均运算:N值较大时:信号平滑度较高,但灵敏度较低;N值较小时:信号平滑度较低,但灵敏度较高;N值的选取:一般流量,N=12;压力:N=4。
C、优点:适用于对一般具有随机干扰的信号进行滤波;这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
D、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用;比较浪费RAM。
E、整理:sumjess 2018-07-01
*/int Filter_Value;void setup() {Serial.begin(9600); // 初始化串口通信randomSeed(analogRead(0)); // 产生随机种子
}void loop() {Filter_Value = Filter(); // 获得滤波器输出值Serial.println(Filter_Value); // 串口输出delay(50);
}// 用于随机产生一个300左右的当前值
int Get_AD() {return random(295, 305);
}// 算术平均滤波法
#define FILTER_N 12
int Filter() {int i;int filter_sum = 0;for(i = 0; i < FILTER_N; i++) {filter_sum += Get_AD();delay(1);}return (int)(filter_sum / FILTER_N);
}
(3)舵机转向:
调节出中值和左右摆的值,写一个按键程序,每按一次旋转一定角度,便可轻易记录下各个位置的数据,操作简单,此处就不再赘述。
(4)电机接线方式如下:
https://jingyan.baidu.com/article/75ab0bcbcb5320d6864db2e4.html
(5)按照伪代码写程序:
#include <Servo.h>
#include <NewPing.h>///目前使用的引脚: 4-5-6-9-10-12-13
//舵机设置//
Servo myservo; // 创建车体转向(X轴)舵机对象
#define servo_pin 4 // 定义车体转向舵机信号线接口
/*int servopin = 7; //定义舵机接口数字接口7void servopulse(int angle)//定义一个脉冲函数{int pulsewidth=(angle*11)+500; //将角度转化为500-2480的脉宽值digitalWrite(servopin,HIGH); //将舵机接口电平至高delayMicroseconds(pulsewidth); //延时脉宽值的微秒数digitalWrite(servopin,LOW); //将舵机接口电平至低delayMicroseconds(20000-pulsewidth);}*/
超声波设置//
//#define PING_PIN 12 // Arduino pin tied to both trigger and echo pins on the ultrasonic sensor.
#define MAX_DISTANCE 450 // 设置最大距离(厘米)。最大传感器距离为400-500cm。
#define TRIG_PIN 12 //超声波引脚配置
#define ECHO_PIN 13 //超声波引脚配置
int Filter_Value;//滤波后的数值
int Filter();//用于滤波计算
int Get_ultra();//用于获取一个目前的超声波值
#define FILTER_N 10 //超声波均值滤波(去多少次做平均数)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // 调整引脚和最大距离
电机设置//
#define leftA_PIN 5
#define leftB_PIN 6
#define righA_PIN 9
#define righB_PIN 10void motor_pinint(void); //引脚初始化
void forward( ); //前进
void back( ); //后退
void turnLeft( ); //左转
void turnRight( ); //右转
void turnbackLeft( ); //左后
void turnbackRight( ); //右后
void turnLeftOrigin( ); //原地左
void turnRightOrigin( ); //原地右
void _stop(); //停车void setup()
{Serial.begin(115200); //串口波特率115200(PC端使用)myservo.attach(servo_pin, 1000, 2500); // min 默认1000,max 默认2500 1200 1800 2300myservo.writeMicroseconds(1200); //摆正舵机pinMode(TRIG_PIN, OUTPUT); // 要检测引脚上输入的脉冲宽度,需要先设置为输入状态pinMode(ECHO_PIN, INPUT); // 要检测引脚上输入的脉冲宽度,需要先设置为输入状态motor_pinint(); //电机引脚初始化
}void loop()
{
if(Filter()<20)//危险
{_stop();//电机停转myservo.writeMicroseconds(2300);//向左转舵机if(Filter()<20)//危险{myservo.writeMicroseconds(1200);//向右转舵机if(Filter()<20)//危险{myservo.writeMicroseconds(1800);//向中间舵机back( ); //后退}else{myservo.writeMicroseconds(1800);//向中间舵机turnRight( ); //右转delay(30);_stop();//电机停转forward( ); //前进}}else {turnLeft( ); //左转delay(30);_stop();//电机停转forward( ); //前进}}else {forward( ); //前进}
}// Filter_Value = Filter(); // 获得滤波器输出值
// Serial.println(Filter_Value); // 串口输出
// delay(50);
// if((int)Filter_Value>100)
// myservo.writeMicroseconds(1200);//向右转舵机
// else if((50<(int)Filter_Value)&&((int)Filter_Value<100))
// myservo.writeMicroseconds(2300);//向左转舵机
// else if((0<(int)Filter_Value)&&((int)Filter_Value<49))
// myservo.writeMicroseconds(1800);//向中间舵机/*
A、名称:算术平均滤波法
B、方法:连续取N个采样值进行算术平均运算:N值较大时:信号平滑度较高,但灵敏度较低;N值较小时:信号平滑度较低,但灵敏度较高;N值的选取:一般流量,N=12;压力:N=4。
C、优点:适用于对一般具有随机干扰的信号进行滤波;这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
D、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用;比较浪费RAM。
E、整理:sumjess 2018-07-01
*/// 用于获得一个超声波的当前值
int Get_ultra()
{// 产生一个10us的高脉冲去触发TrigPindigitalWrite(TRIG_PIN, LOW);delayMicroseconds(2);digitalWrite(TRIG_PIN, HIGH);delayMicroseconds(10);digitalWrite(TRIG_PIN, LOW);// 检测脉冲宽度,并计算出距离return pulseIn(ECHO_PIN, HIGH) / 58.00;}
int Filter()
{int i;int filter_sum = 0;for(i = 0; i < FILTER_N; i++) {filter_sum += Get_ultra();delay(30);//超声波采集用一般为30ms间隔}return (int)(filter_sum / FILTER_N);
}//电机引脚初始化void motor_pinint(void){pinMode (leftA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (leftB_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righB_PIN, OUTPUT); //设置引脚为输出引脚}
/**************************************************
forward子函数——前进子函数
函数功能:控制车前进
**************************************************/void forward( )
{analogWrite(leftA_PIN,120); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,120); analogWrite(righB_PIN,0); //右轮前进
}/**************************************************
back子函数——后退子函数
函数功能:控制车后退
**************************************************/
void back( )
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,120); //左轮后退analogWrite(righA_PIN,0); analogWrite(righB_PIN,120); //右轮后退
}/**************************************************
turnLeft子函数——左转子函数
函数功能:控制车左转
**************************************************/
void turnLeft( )
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,0); //左轮静止不动analogWrite(righA_PIN,120); analogWrite(righB_PIN,0); //右轮前进
}/**************************************************
turnbackLeft子函数——左后转弯子函数
函数功能:控制车左后转弯
**************************************************/
void turnbackLeft( )
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,0); //左轮静止不动analogWrite(righA_PIN,0); analogWrite(righB_PIN,120); //右轮后退
}/**************************************************
turnRight子函数——右后转弯转子函数
函数功能:控制车右后转弯
**************************************************/
void turnRight( )
{analogWrite(leftA_PIN,120); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,0); analogWrite(righB_PIN,0); //右轮静止不动
}/**************************************************
turnbackRight子函数——右转子函数
函数功能:控制车右转
**************************************************/
void turnbackRight( )
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,120); //左轮后退analogWrite(righA_PIN,0); analogWrite(righB_PIN,0); //右轮静止不动
}/**************************************************
turnLeftOrigin子函数——原地左转子函数
函数功能:控制车原地左转
**************************************************/
void turnLeftOrigin( )
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,120); //左轮后退analogWrite(righA_PIN,120); analogWrite(righB_PIN,0); //右轮前进
}/**************************************************
turnRightOrigin子函数——原地右转子函数
函数功能:控制车原地右转
**************************************************/
void turnRightOrigin( )
{analogWrite(leftA_PIN,120); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,0); analogWrite(righB_PIN,120); //右轮后退
}/**************************************************
stop子函数—停止子函数
函数功能:控制车停止
**************************************************/
void _stop()
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,0); //左轮静止不动analogWrite(righA_PIN,0); analogWrite(righB_PIN,0); //右轮静止不动
}
2、跟随小车的制作
一、接线:
(1)电机接线:
四个逻辑通道从左到右(即IN1到IN4)分别接5、6、9、10
12v供电,5伏输出给arduino供电
注意:此处驱动一定要和arduino共地!!!否则无法传输数据。
输出A接左边电机,输出B做右边电机
(2)避障模块接线:
使用了三个该模块,分别在车的前左、前中、前右。如图:
引脚从左到右分别接的是11、8、2
二、书写代码:
下载下面的代码:
//电机使用:5-6-9-10
//避障模块使用:11--8--2
// 左 中 右/************电机设置*************/
#define leftA_PIN 5
#define leftB_PIN 6
#define righA_PIN 9
#define righB_PIN 10void motor_pinint(); //电机引脚初始化
void _stop(); //停车
void turnSRight(); //小右转
void turnSLeft(); //小左转
void turnRight(); //右转
void turnLeft(); //左转
void forward(); //前进
int error; //中间变量
int sensor[4]; //存取三个传感器数据信息的数组
//****************循迹模块设置 ***************//
#define left_track_PIN 11
#define middle_track_PIN 8
#define righ_track_PIN 2
int read_sensor_values(void); //读取初值
void track_pinint(); //避障引脚初始化 void setup()
{ motor_pinint(); //电机引脚初始化
}
void loop()
{switch (read_sensor_values()){ //读取初值 case 0: turnLeft(); break; case 1: turnSLeft(); break; case 2: forward();break; case 3: _stop(); break; case 4: turnSRight(); break; case 5: turnRight(); break; default: _stop();break; }
}
/*循迹模块引脚初始化*/
void track_pinint()
{ pinMode (left_track_PIN , INPUT); //设置引脚为输入引脚pinMode (middle_track_PIN, INPUT); //设置引脚为输入引脚pinMode (righ_track_PIN , INPUT); //设置引脚为输入引脚
}
/*电机引脚初始化*/
void motor_pinint(void)
{pinMode (leftA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (leftB_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righB_PIN, OUTPUT); //设置引脚为输出引脚}
int read_sensor_values()
{sensor[0] = digitalRead(left_track_PIN);sensor[1] = digitalRead(middle_track_PIN);sensor[2] = digitalRead(righ_track_PIN);//0为检测到障碍if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 1)) {error = 0;// 001 大左转} else if ((sensor[0] == 0) && (sensor[1] == 1) && (sensor[2] == 1)) {error = 1;// 011 小左转} else if ((sensor[0] == 1) && (sensor[1] == 1) && (sensor[2] == 1)) {error = 2;// 111 前进} else if ((sensor[0] == 0) && (sensor[1] == 1) && (sensor[2] == 0)) {error = 3;// 010 停止} else if ((sensor[0] == 1) && (sensor[1] == 1) && (sensor[2] == 0)) {error = 4;// 110 小右转} else if ((sensor[0] == 1) && (sensor[1] == 0) && (sensor[2] == 0)) {error = 5;// 100 大右转} else if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 0)) {error = 3;// 000 前进} else if ((sensor[0] == 1) && (sensor[1] == 0) && (sensor[2] == 1)) {error = 3;// 101 停止} else error = 3;// error 停止return error;
}
/**************************************************
forward子函数——前进子函数
函数功能:控制车前进
**************************************************/void forward()
{analogWrite(leftA_PIN,120); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,120); analogWrite(righB_PIN,0); //右轮前进
}
/**************************************************
turnLeft子函数——大左转子函数
函数功能:控制车大左转
**************************************************/
void turnLeft()
{analogWrite(leftA_PIN,50); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,120); analogWrite(righB_PIN,0); //右轮前进
}
/**************************************************
turnRight子函数——小右转子函数
函数功能:控制车大右转弯
**************************************************/
void turnRight()
{analogWrite(leftA_PIN,120); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,50); analogWrite(righB_PIN,0); //右轮前进
}
/**************************************************
turnLeft子函数——大左转子函数
函数功能:控制车小左转
**************************************************/
void turnSLeft()
{analogWrite(leftA_PIN,90); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,120); analogWrite(righB_PIN,0); //右轮前进
}
/**************************************************
turnRight子函数——小右转子函数
函数功能:控制车小右转弯
**************************************************/
void turnSRight()
{analogWrite(leftA_PIN,120); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,90); analogWrite(righB_PIN,0); //右轮前进
}
/**************************************************
stop子函数—停止子函数
函数功能:控制车停止
**************************************************/
void _stop()
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,0); //左轮静止不动analogWrite(righA_PIN,0); analogWrite(righB_PIN,0); //右轮静止不动
}
3、魔术手的制作
(1)逻辑部分:
只写了一个简单的,能前后走的,用了跟随小车的左右两边的那个两个避障模块
(2)按照逻辑部分部分程序(算法):
//电机使用:5-6-9-10
//避障模块使用:11----2
// 左 右/************电机设置*************/
#define leftA_PIN 5
#define leftB_PIN 6
#define righA_PIN 9
#define righB_PIN 10void motor_pinint(); //电机引脚初始化
void back(int a);
void forward(int a);
//****************循迹模块设置 ***************//
#define left_track_PIN 11
#define righ_track_PIN 2
void read_sensor_values(void); //读取初值
void track_pinint(); //避障引脚初始化
int error; //中间变量
int sensor[4]; //存取三个传感器数据信息的数组void setup()
{motor_pinint(); //电机引脚初始化
}
void loop()
{read_sensor_values3();
}
/*循迹模块引脚初始化*/
void track_pinint()
{ pinMode (left_track_PIN , INPUT); //设置引脚为输入引脚pinMode (righ_track_PIN , INPUT); //设置引脚为输入引脚
}
/*电机引脚初始化*/
void motor_pinint()
{pinMode (leftA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (leftB_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righA_PIN, OUTPUT); //设置引脚为输出引脚pinMode (righB_PIN, OUTPUT); //设置引脚为输出引脚}
void read_sensor_values3()
{sensor[0] = digitalRead(left_track_PIN);sensor[2] = digitalRead(righ_track_PIN);/*****左边远、右边近*****/if ( (sensor[0] == 1) && (sensor[2] == 1) || (sensor[0] == 0) && (sensor[2] == 1)) {forward(80); // 前进 1 1/0 1} else if ( (sensor[0] == 0) && (sensor[2] == 0) || (sensor[0] == 1) && (sensor[2] == 0)) {back(80); // 后退 0 0/1 0}}/**************************************************
forward子函数——前进子函数
函数功能:控制车前进
**************************************************/void forward(int a)
{analogWrite(leftA_PIN,a); analogWrite(leftB_PIN,0); //左轮前进analogWrite(righA_PIN,a); analogWrite(righB_PIN,0); //右轮前进
}
/**************************************************
forward子函数——后退子函数
函数功能:控制车后退
**************************************************/void back(int a)
{analogWrite(leftA_PIN,0); analogWrite(leftB_PIN,a); //左轮后退analogWrite(righA_PIN,0); analogWrite(righB_PIN,a); //右轮后退
}
如果大家在制作过程中有什么问题或者思路可以在下方留言和我一起交流噢!
如果发现本文有错误,也请在下方评论区指出,感激不尽!
基于arduino的避障.跟随小车(带有魔术手)相关推荐
- 基于Wemos D1避障WiFi小车及智能垃圾桶设计
基于Wemos D1避障WiFi小车及智能垃圾桶设计 一.实验器材 主控芯片 Wemos D1 其他器材 HC-SR04超声波.L9110s电机.ESP82660WiFi模块.蜂鸣器 所需设备 TCP ...
- arduino麦轮转弯程序_Arduino 自动避障智能小车制作教程
Arduino 自动避障智能小车制作教程 材料: Arduino UNO r3 L298N电机驱动模块 小车底盘一个,万向轮一个 2个电机及匹配的车轮 9V电池盒及6个1.5V电池 超声波测距模块及其 ...
- stm32捕获占空比_基于STM32超声波避障小车
不管是对于初学者还是对于一个玩过单片机的电子爱好者来说,或多或少都接触到过小车项目,今天给大家介绍的的一个项目基于STM32超声波避障小车.这也是我曾经的一个课设,在此开源分享给大家,全文5000多字 ...
- 避障跟随测距c语言程序,红外避障小车c语言程序.pdf
智能小车红外避障智能小车红外避障 c 语言程序语言程序 #include bit RandomFactor = 0 ; bit RandomFactorBuf = 0 ; #include #defi ...
- 35、基于51单片机自动灭火避障智能小车 消防灭火小车系统设计
摘要 智能作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途.智能小车就是其中的一个体现,本次设计的多功能智能灭火避障小车 ...
- 非确定性算法_使用最坏情况提高基于MPC的避障算法对参数不确定性的鲁棒性
编者按:避障问题是AGV行驶过程中的一个重点,尤其是在未知和非结构化的环境中,没有关于环境的先验知识以及准确的车辆模型参数,难以充分发挥车辆的性能.作者在以前工作中,提出了在未知和非结构化环境中基于非 ...
- 山东省高校机器人大赛-智能避障避险小车经验分享
山东省高校机器人大赛-智能避障避险小车经验分享 概述 竞赛题目 详细设计过程 车体设计 现在开车 过⑧号障碍物 如何跑完全程 概述 今天是2020年2月9日,因为新冠肺炎的原因,学校依然没有要开学的意 ...
- Arduino+红外避障模块
Arduino+红外避障模块 文章目录 Arduino+红外避障模块 前言 一.模块原理 二.使用步骤 1.材料准备 2.线路连接 三.代码 总结 前言 从当前文章开始,我将记录自学Arduino的一 ...
- [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车
目录 1.小车驱动主要是通过L9110S模块来驱动电机 motor.c 2.我们可以加入串口控制电机驱动(重写串口接收回调函数,和重定向printf) Uart.c main.c 3.点动功能 uar ...
- 基于89C51单片机的智能小车——07.语音识别切换寻迹避障跟随并Oled显示
语音模块配置 模块配置网站:http://www.smartpi.cn/#/ 1.点击创建产品 -> 其他 -> 其他产品 2.选择场景为 纯离线方案 ,选择模组为 SU-03T. 3.填 ...
最新文章
- Linux用户态和内核态
- 使用WinDbg内核调试
- Ubuntu 16.04 LTS下编译GPU版tensorflow
- bzoj3192: [JLOI2013]删除物品
- 只剩 1 天 | 神策 2019 数据驱动大会明天开幕
- Chrome 74 稳定版发布,Windows 10 支持黑暗模式
- linux裸机网络安装,linux下PXEServer实现网络安装【实验】
- win7 vs2015配置qt5.11
- 信息学奥赛C++语言: 判决素数个数
- javascript 模仿点击链接
- 使用Ntdsutil.exe捕获系统状态数据
- 各种PLC解密软件集合
- Yaml:基本语法使用
- 【项目管理/PMP/PMBOK第六版/新考纲】计算题! 项目章程/变更/工作绩效报告/项目范围说明书/工作分解结构WBS/最小浮动时间/挣值分析/采购
- iOS循环引用问题集合、内存泄漏、僵尸对象、代码静态分析
- c语言调用calculate函数,关于c语言中int calculate函数求解。谢谢
- Windows 去除我的电脑页面多余的设备和驱动器图标
- UEFI与 Legacy BIOS两种启动模式详解
- HTML静态网页设计基础
- C语言基础 C语言标识符
热门文章
- 21王道计算机网络pdf百度云,王道计算机网络第五章.pdf
- Navicat Premium 15 激活后打开就会无响应,或者崩溃,自动退出,没有任何提示,有时候会说未响应
- 日期时间公式计算机,App Store 上的“多少天-重要日期时间计算器”
- AR5B22刷win10的killer驱动
- 经济学和哲学_边做边学的哲学
- 软件测试典型缺陷分析,几种典型的软件缺陷分析方法
- Windows环境搭建Red5流媒体服务器
- 利用Dbgview和OutputDebugString
- STM32串口通信UARTx
- python 批量提取 mkv 视频文件内嵌 srt 字幕