Arduino/stm32 智能小车设计(二)

本节进行Arduino智能小车的代码讲解。

一、I/O口定义与初始化函数

如下图RGB指示灯用到10、11、12三个I/O口,分别对应蓝色、红色、绿色。当给对应的I/O口低电平时,对应颜色的灯亮。也可以用PWM进行调色,实现不同的颜色。这里先把控制端的原理图粘贴上来以便后面原理说明。

Arduino封装了很多底层的细节,使得学习者不需要太多的关注底层电路的原理。
Arduino一共有14个数字I/O口,分别为0-13,定义与初始化看代码;6个模拟I/O口,分别为A0-A5,定义与初始化看代码。
已下是所有I/O端口定义:

//0:TDX蓝牙     1:RXD蓝牙          2:DATA红外遥控
//3:蜂鸣器      4:按键             5:IN2左电机
//6:IN3右电机   7:IN4右电机     8:IN1左电机
//9:悬空       10:RGB_B         11:RGB_R
//12:RGB_G                   13:流水灯
//A0:Echo超声波回声脚             A1:Trig超声波触发脚
//A2:左循迹输入                  A3:右循迹输入
//A4:右壁障输入                  A5:左壁障输入//I/O口 0、1 是Arduino唯一的一组串口通信口(代码里无需定义)。用于蓝牙数据的接发,具体串口通信的知识可以看我的另外一篇博客了解。链接:
https://blog.csdn.net/weixin_43729724/article/details/101287363
//数字端口定义
int DATA= 2;       //红外数据输入端口
int BEEP=3;            //蜂鸣器输出
int KEY=4;             //按键输入
int IN2=5;          //左电机
int IN3=6;          //右电机
int IN4=7;             //右电机
int IN1=8;         //左电机//9脚悬空,不需要定义
int RGB_B=10;       //RGB蓝色
int RGB_R=11;      //RDB红色
int RGB_G=12;          //RGB绿色
int Water_L=13;     //流水灯I/O
//模拟I/O口定义
int Trig =A0;              //Trig 触发脚输出
int Echo = A1;         //Echo回声脚输入
int XunJi_R = A3;      //右寻迹输入
int XunJi_L = A2;      //左寻迹输入
int BiZhang_R = A4;    //右红外避障输入
int BiZhang_L = A5;     //左红外避障输入/************************************************************************* @描述:  Arduino初始化函数* @参数:  None* 功能:  定义I/O口模式,并赋初值* @返回值: None
**********************************************************************/
void setup()
{Serial.begin(9600);    //波特率9600 (蓝牙通讯设定波特率)pinMode(DATA,INPUT);pinMode(BEEP,OUTPUT); pinMode(KEY,INPUT); pinMode(IN2,OUTPUT);pinMode(IN3,OUTPUT);pinMode(IN4,OUTPUT);pinMode(IN1,OUTPUT);  pinMode(RGB_B,OUTPUT);pinMode(RGB_R,UTPUT); pinMode(RGB_G,UTPUT); pinMode(Water_L,OUTPUT);pinMode(Trig,OUTPUT); pinMode(Echo,INPUT);pinMode(XunJi_R,INPUT);pinMode(XunJi_L,INPUT);pinMode(BiZhang_R,INPUT);pinMode(BiZhang_L,INPUT);digitalWrite(BEEP,LOW);  digitalWrite(RGB_B,HIGH);digitalWrite(RGB_R,HIGH); digitalWrite(RGB_G,HIGH); digitalWrite(Water_L,HIGH);
}

二、前进、后退、左转、右转、左旋转、右旋转API函数

原理图如下:
电机驱动原理:L293DD是一款专用的电机驱动芯片,因为I/O口驱动电流受限,而电机运转需要高电流驱动。当8高5低时,电流从OUT1->OUT2驱动做电机正转,反之亦凡。I/O口6、7驱动右电机运动。
代码如下:

/************************************************************************* @描述:  * @参数:  speed:控制速度0-255* 功能:  小车前进* @返回值: None
**********************************************************************/
void run(int speed)
{analogWrite(IN1,speed);//PWM比例0~255调速,左右轮差异略增减digitalWrite(IN2,LOW);analogWrite(IN4,speed);//PWM比例0~255调速,左右轮差异略增减digitalWrite(IN3,LOW);
}
/************************************************************************* @描述:  * @参数:  None* 功能:    刹车* @返回值: None
**********************************************************************/
void brake()
{digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);digitalWrite(IN3,LOW);digitalWrite(IN4,LOW);
}
/************************************************************************* @描述:  左转(左轮不动,右轮前进)* @参数:  speed:控制速度0-255* 功能: 小车左转* @返回值: None
**********************************************************************/
void left(int speed)
{digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);analogWrite(IN4,speed);//PWM比例0~255调速,右轮前进digitalWrite(IN3,LOW);
}
/************************************************************************* @描述:  左旋转(左轮后退,右轮前进)* @参数:  speed:控制速度0-255* 功能:    小车左旋转* @返回值: None
**********************************************************************/
void spin_left(int speed)
{digitalWrite(IN1,LOW);analogWrite(IN2,speed);analogWrite(IN4,speed);digitalWrite(IN3,LOW);
}
/************************************************************************* @描述:  右转(左轮前进,右轮不动)* @参数:  speed:控制速度0-255* 功能: 小车右转* @返回值: None
**********************************************************************/
void right(int speed)
{analogWrite(IN1,speed);digitalWrite(IN2,LOW);digitalWrite(IN4,LOW);digitalWrite(IN3,LOW);
}
/************************************************************************* @描述:  右旋转(左轮前进,右轮后退)* @参数:  speed:控制速度0-255* 功能:    小车右旋转* @返回值: None
**********************************************************************/
void spin_right(int speed)
{analogWrite(IN1,speed);digitalWrite(IN2,LOW);digitalWrite(IN4,LOW);analogWrite(IN3,speed);
}
/************************************************************************* @描述:  * @参数:  speed:控制速度0-255* 功能: 小车后退* @返回值: None
**********************************************************************/
void back(int speed)
{digitalWrite(IN1,LOW);analogWrite(IN2,speed);digitalWrite(IN4,LOW);analogWrite(IN3,speed);
}

三、红外避障与红外寻迹API函数

红外避障原理:如图红外对管D24由一个发射管和一个接收管组成,发射管发出红外线,当遇到障碍物时反射红外线由接收管接收,使运放IN1-端口电压变化,当调节R16电位器使IN1+电压变化,当IN1+ 的电压大于IN1-的电压时,OUT1输出高电平,被A5接收。
红外寻迹原理:如图红外对管U8由一个发射管和一个接收管组成,发射管发出红外线,当没有探测到黑线时,一直反射红外线被接收管接受,IN4-端口输入固定电压,当探测到黑线时,红外线被吸收,接受管接受不到红外线,IN4-电压降低,对比IN4-、IN4+两端电压,OUT4输出高低电平,被A2接收。

代码如下:

int BiZhang_L_S;    //左红外传感器状态
int BiZhang_R_S;    //右红外传感器状态
/************************************************************************* @描述:  当没有探测到障碍物时,A4、A5为高电平,当探测到高电平时为低电平* @参数:  speed:控制速度0-255* 功能:  红外避障* @返回值: None
**********************************************************************/
void Infrared_Avoid(int speed)
{//有信号为LOW  没有信号为HIGHBiZhang_R_S = digitalRead(BiZhang_R);BiZhang_L_S = digitalRead(BiZhang_L);if (BiZhang_L_S == HIGH && BiZhang_R_S == HIGH)run(speed);else if (BiZhang_L_S == HIGH & BiZhang_R_S == LOW)left(speed);else if (BiZhang_R_S == HIGH & BiZhang_L_S == LOW)right(speed);else // 都是有障碍物spin_right(speed);
}
int XunJi_L_S;      //左循迹红外传感器状态
int XunJi_R_S;      //右循迹红外传感器状态
/************************************************************************* @描述:  当没有探测到黑线时,A4、A5为高电平* @参数:  speed:控制速度0-255* 功能:   红外寻迹* @返回值: None
**********************************************************************/
void Find_Tracking(int speed)
{ XunJi_R_S = digitalRead(XunJi_R);XunJi_L_S = digitalRead(XunJi_L);if (XunJi_R_S ==LOW && XunJi_L_S == LOW)run(speed); else if (XunJi_L_S == LOW & XunJi_R_S == HIGH)right(speed);else if (XunJi_R_S == LOW & XunJi_L_S ==  HIGH) left(speed);elsebrake();
}

四 、超声波测距原理

超声波模块如图:

产品特色:
1、典型工作用电压:5V。
2、超小静态工作电流:小于2mA。
3、感应角度:不大于15 度。
4、探测距离:2cm-400cm
5、高精度:可达0.3cm。
6、盲区(2cm)超近。
超声波时序如图:

原理图如下:

代码如下:

/************************************************************************* @描述:  * @参数:  None* 功能: 量出前方距离* @返回值: int:距离(单位:CM)
**********************************************************************/
int Ultrasonic_Distance()
{digitalWrite(Trig, LOW);   //给触发脚低电平2μsdelayMicroseconds(2);digitalWrite(Trig, HIGH);  //给触发脚高电平12μs,这里至少是10μsdelayMicroseconds(12);digitalWrite(Trig, LOW);   //持续给触发脚低电float Time = pulseIn(Echo, HIGH);  //读取高电平时间(单位:微秒)return Time/58; //公式:us/58 = CM
}

五、蓝牙控制原理

由于蓝牙通信用的是 0、1两个通用串行通信I/O口,Arduino官方提供了,串口通信的专用API函数供用户使用,这里我们用的是Serial.available()
函数说明见链接:https://www.arduino.cc/reference/en/language/functions/communication/serial/available/
手机APP或者电脑上位机通过蓝牙发送字符串给给蓝牙模块(蓝牙模块就相当于是一个中转站),Arduino控制板用过0、1串行端口读取到来自蓝牙的数据。然后,我们根据来自APP或者上位机的字符串来判断功能。比如,手机发送:0X00代表前进、0X01 代表后退等等。这样我们只需要用一个switch语句实现蓝牙API函数。
我的代码如下:

int speed = 150;    //小车运动速度
/************************************************************************* @描述:  * @参数:  None* 功能:    蓝牙控制* @返回值: int:距离(单位:CM)
**********************************************************************/
void Bluetooth_Control()
{     if (Data_Received){switch(IN_String[1]){case '1':   run(speed);break;case '2':    back(speed);break;case '3':   left(speed);break;case '4':   right(speed);break;case '0':      brake();break;default:  brake();break;}if(IN_String[3] == '1')  //旋转{spin_left();}else if(IN_String[3] == '2')  //旋转{spin_right();}if(IN_String[5] == '1')  //鸣笛0.5S{digitalWrite(BEEP,HIGH);//发声音delay(500);digitalWrite(BEEP,LOW);//不发声音}if(IN_String[7] == '1')  //加速{speed +=50;if(speed > 255)  speed = 255;}if(IN_String[9] == '1')  //减速{speed -= 50;if(speed < 50)    speed = 100;}           IN_String = "";   // clear the stringData_Received = false;    }
}
int Bluetooth_Data;             //接收蓝牙的数据
String IN_String = "";       //用来储存接收到的内容
boolean Start_flag = false;        //数据开始接收的状态标志
boolean Data_Received = false;     //接收数据结束标志
/************************************************************************* @描述:  串口中断函数* @参数:  None* 功能:  接收来自蓝牙模块的数据* @返回值: None
**********************************************************************/
void serialEvent()
{while (Serial.available()) {    Bluetooth_Data= Serial.read();if(Bluetooth_Data== '$'){Start_flag = true;}if(Start_flag == true){IN_String += (char) Bluetooth_Data;}  if (Bluetooth_Data== '#') {Data_Received = true; Start_flag = false;}}
}

还有红外遥控的代码不想敲了,个人感觉蓝牙遥控更加方便实用。
接下来写一个综合例程:

#define KEYMODE_1   1  // 定义模式1
#define KEYMODE_2   2  // 定义模式2
#define KEYMODE_3   3  // 定义模式3
#define KEYMODE_4   4  // 定义模式4
int keyMode = 1;
/************************************************************************* @描述:  按键模式切换* @参数:  None* 功能:  按键子程序* @返回值: None
**********************************************************************/
void KeyScanTask()
{static u8 keypre = 0;if((keypre == 0 ) && !digitalRead(KEY)){keypre = 1; //置1,避免持续按下按键时再次进入此函数。switch(keyMode){case KEYMODE_1:keyMode = KEYMODE_2; break;case KEYMODE_2:keyMode = KEYMODE_3; break;case KEYMODE_3:keyMode = KEYMODE_4; break;case KEYMODE_4:keyMode = KEYMODE_1; break;default: break;}}if(digitalRead(KEY))  //按键被放开{keypre = 0;//置0,允许再次切换LED模式}
}
/************************************************************************* @描述: 模式处理函数* @参数:  None* 功能:   任务程序* @返回值: None
**********************************************************************/
void LEDTask()
{switch(keyMode){case KEYMODE_1:    digitalWrite(RGB_B,LOW);digitalWrite(RGB_R,HIGH); digitalWrite(RGB_G,HIGH);Infrared_Avoid(200); //红外避障break;case KEYMODE_2: digitalWrite(RGB_B,HIGH);digitalWrite(RGB_R,LOW); digitalWrite(RGB_G,HIGH);Find_Tracking(200); //红外寻迹break;case KEYMODE_3:  digitalWrite(RGB_B,HIGH);digitalWrite(RGB_R,HIGH); digitalWrite(RGB_G,LOW);Bluetooth_Control(); //红外寻迹break;case KEYMODE_4: digitalWrite(RGB_B,LOW);digitalWrite(RGB_R,LOW); digitalWrite(RGB_G,LOW);//红外寻迹,此处可以写一个超声波避障的API break;default:break;}
}
/************************************************************************* @描述: * @参数:  None* 功能: loop函数相当于 Arm的main函数* @返回值: None
**********************************************************************/
void loop()
{ KeyScanTask();LEDTask();
}

Arduino/stm32 智能小车设计(二)相关推荐

  1. Arduino/stm32 智能小车设计(一)

    Arduino/stm32 智能小车设计(一) 智能小车原理图设计 智能小车原理图组件包括: 模块设计 一.控制模块 二.供电模块 三.充电管理模块 四.电机驱动模块 五.红外寻迹及红外避障模块 六. ...

  2. stm32智能小车设计

    提前说说 博主是用寄存器写的驱动 历时两周,总算把小车弄好了,总体上来说做的太慢了.自己在32的学习中还不够仔细深入,只是浅面的学习,当真正做一个项目时,暴露的问题就太多了.这次在小车的制作的过程中, ...

  3. stm32智能小车设计(1)——硬件选型思路

    目录 硬件整体逻辑 主控: 底盘: 电机 L298n电机驱动: 供电: 外设功能: 电机测速: 循迹功能(走s线,绕弯) 避障功能: 蓝牙遥控: 高级功能: 小车信息的获取及显示: 物体跟随,色块追踪 ...

  4. 用matlab结合STM32作上位机,基于stm32智能小车视觉控制导航的设计参考.pdf

    第 25 卷 第 9 期 电子设计工程 2017 年 5 月 Vol.25 No.9 Electronic Design Engineering May. 2017 基于STM32 智能小车视觉控制导 ...

  5. 集成智能小车(二...2)整体设计之谋

    说明: 1)此章节将讲述下我对各个环节的考虑,详细的选型和资源分配会在<二.3>节展开,软硬件设计会在设计部分讲.如果对智能小车熟悉的同学可以一带而过,看<二.3>最终选型和资 ...

  6. STM32智能小车循迹教程

    文章目录 前言 一.红外循迹模块工作原理及接线图 红外循迹模块工作原理 红外循迹模块和STM32的接线图 二.cubeMX配置 三.代码解析 总结 前言 本篇文章将带大家学习STM32智能小车的循迹功 ...

  7. 【毕业设计之树莓派系列】基于树莓派的智能小车设计

    基于树莓派的智能小车设计 摘要 随着人们对智能化生活的需求不断增长,智能小车的发展逐渐受到关注.然而,现有的智能小车硬件和软件设计有一定的局限性,需要进一步改进和完善.本文旨在基于树莓派PICO开发板 ...

  8. 智能小车设计指导 第二版

    这是我负责主编的设计指导,2009年9月初的第一版,一年之后出了第二版,现在吧链接放出来,有兴趣的可以参考. 点击此处下载 ourdev_599585DAN8LI.rar(文件大小:3.39M) (原 ...

  9. 毕业论文 | 基于安卓手机蓝牙控制的智能小车设计(源代码)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 预告:源代码.论文.电路图设计链接 ...

最新文章

  1. 限量!Alibaba首发“Java成长笔记”,差距不止一点点
  2. 使用CleanIISLog清除IIS记录
  3. 华兴资本任命项威为COO 向包凡汇报
  4. jsTree设置默认节点全部展开的方法
  5. JavaScript的案例(数据校验,js轮播图,页面定时弹窗)
  6. ubuntu下搭建eclipse+tomcat的web开发环境
  7. 上个ensp实验只发了配置,这次是命令条目
  8. php集成环境还需要mysql吗_是选择php集成环境好还是分开安装的原生版好
  9. 【分享】计算机ers,读博、国企、互联网公司该如何选择?
  10. sonarqube如何导入规则_webpack如何使用Vue
  11. (转) QImage总结
  12. 一键下载百度文库/豆丁/道客巴巴文档,支持导出PDF,Word,txt 文件
  13. C语言的体系结构--main函数存在的必然性(听杨力祥老师的课)
  14. Lenovo System x3650 M5 使用ServerGuide安装win2016(U盘安装)
  15. GCode软件使用说明书
  16. 学生成绩预测模型_学生成绩分析预测
  17. COSNET: Connecting Heterogeneous Social Networks with Local and Global Consistency 论文阅读笔记
  18. 51单片机电子琴编码 — 《断桥残雪》《庐州月》
  19. 怎么把pdf转换成excel转换器免费版
  20. 物业养老,智慧养老新方式

热门文章

  1. Tridium niagara N4---JACE 8000恢复出厂报错无法进去
  2. 让swfobject.js 支持透明的flash
  3. Trinity安装与报错
  4. VMware Workstation 11序列号一枚
  5. fixed 和 fixed
  6. fixed 和setprecision()的用法
  7. 利用Python做excel文本合并(根据左侧单元格,快速合并右侧单元格内容)
  8. IE8开发人员工具使用详解下(模式,JS调试,探查器)
  9. word表格中 英文排版
  10. 基于ip-iq变换的谐波检测算法,并联型APF 有源电力滤波器 谐波电流检测