基于ardiuno的智能小车

目录

一. 开发环境安装
1.1 下载


二. 常用C语言基本语法
2.1 注释
2.2 函数
2.3 初始化和主函数
2.4 输入输出函数

 

三. 让小车动起来
3.1 L298N控制逻辑
3.2 让小车左轮动起来
3.3 让小车右轮电机动起来
3.4 让小车实现前后左右
3.5 自定义函数和函数调用

 

四. 串口
 

五. 跟随模式开发
5.1 基本原理
5.2 代码实现
5.3 跟随小车

 

六. 摇头避障模式开发
6.1 舵机基本介绍
6.2 摇头测距组合
6.3 摇头避障功能实现

 

七. 小车控速
7.1 analogWrite函数
7.2 控制前进速度的代码
7.3 控速前进左转右转

 

八. 循迹功能
8.1 红外循迹模块 TCRT5000
8.2 代码实现

九.小车硬件安装流程

一. 开发环境安装
硬件是躯壳,代码是思想
开发环境主要两个功能
写代码
把代码通过USB转串口数据线传到单片机去 -- 称之为“烧写程序”
1.1 下载
百度搜索:Arduino官网
https://www.arduino.cc/en/software 下载版本1.8.19


二. 常用C语言基本语法
2.1 注释
在代码中程序员写给自己或者工程师同事的开发说明。
第一种写法:
/* 这是是长篇大论的注释,一般段落型呈现 */
第二种写法:
// 一般只针对从双斜杠开始的一行文字说明
2.2 函数
数学函数: 正弦函数 y = sin(a), 通过sin函数,产生y的变化。作用于数学数据关系
编程函数: 通过函数,除了作用数学关系,还能作用单片机,给操作系统下"命令"等
代码复用,方便开发调试
y = f(x) = 2x+1 y=f(x)=10
封装
编程函数三要素:
函数名 --- 体现功能,参数 ----需要变量或者某些条件,返回值 --- 得到数据型结果
编程函数非常强调函数名-一般函数名体现该函数功能
pinMode-引脚的模式 digitalWrite-输出一个电信号
参数
有点像变量x, y是结果,y的结果由x和运算规则决定
pinMode(2, OUTPUT),pinMode的结果是改变IO口状态, 2是目标IO口,OUTPUT是需要的状态
返回值
数学函数的数据结果
单片机被修改后的结果,或者修改后的外设状态
2.3 初始化和主函数
2.4 输入输出函数
三. 让小车动起来
3.1 L298N控制逻辑
void setup() {  //
 // put your setup code here, to run once: 把你的设置代码放在这里,运行一次
}
void loop() {
 // put your main code here, to run repeatedly: 把你的主代码放在这里,重复运行
}
void setup() {
 pinMode(2, OUTPUT);//设置某个IO口为输入或者输出,这里设置LED_BUILDIN为OUTPUT,现成的,调用
 
}
void loop() {
 digitalWrite(2, HIGH);  //让某个IO口输出“电信号”,HIGH代表高电平,LOW代表低电平
 delay(100);             
 digitalWrite(2, LOW);  
 delay(100);           
}
根据我们的接线:
左电机由引脚2,3控制,右电机由4,5控制。正反转导致前进后退需要根据输出端子那边的电机接线实际验证
测试。
接线说明
左电机安装朝向是接杜邦线的那侧朝外(朝轮子)
左轮上,接左端子的OUT2口,
左轮下,接左端子的OUT1口,
IN1由2控制,IN2为3控制
右电机安装朝向是接杜邦线的那侧朝内(背对轮子)
右轮上,接右端子的OUT3口,
右轮下,接右端子的OUT4口,
IN3由4控制,IN4为5控制
3.2 让小车左轮动起来
代码如下
3.3 让小车右轮电机动起来
代码如下
void setup() { //完整
 // put your setup code here, to run once:
 // 配置2,3口为输出引脚
 pinMode(2,OUTPUT);// 配置2口为输出引脚
 pinMode(3,OUTPUT);// 配置3口为输出引脚
}
void loop() {
 // put your main code here, to run repeatedly:
 //后退 2接的是IN1,3接的是IN2. 根据官方说明,正转,对应接线后的现象,后退
 digitalWrite(2,HIGH);
 digitalWrite(3,LOW);
 delay(1000);
 //前进 2接的是IN1,3接的是IN2. 根据官方说明,反转,对应接线后的现象,前进
 digitalWrite(2,LOW);
 digitalWrite(3,HIGH);
 delay(1000);
}
void setup() { //完整
 // put your setup code here, to run once:
 // 配置4,5口为输出引脚
 pinMode(4,OUTPUT);// 配置4口为输出引脚
 pinMode(5,OUTPUT);// 配置5口为输出引脚
}
void loop() {
 // put your main code here, to run repeatedly:
 //前进 4接的是IN3,5接的是IN4. 根据官方说明,正转,对应接线后的现象,
 digitalWrite(4,HIGH);
 digitalWrite(5,LOW);
 delay(1000);
 //后退 4接的是IN3,5接的是IN4. 根据官方说明,反转,对应接线后的现象,
 digitalWrite(4,LOW);
 digitalWrite(5,HIGH);
 delay(1000);
}
3.4 让小车实现前后左右
3.5 自定义函数和函数调用
把一段代码放在代码文件某个位置,并为其取个“组合名”的过程叫做函数封装
方便代码阅读和调试修改
可以多次通过函数名复用
让主流程函数更加简洁
void setup() {
 // put your setup code here, to run once:
 //左轮信号方向初始化
 pinMode(2,OUTPUT);// 配置2口为输出引脚
 pinMode(3,OUTPUT);// 配置3口为输出引脚
 //右轮信号方向初始化
 pinMode(4,OUTPUT);// 配置4口为输出引脚
 pinMode(5,OUTPUT);// 配置5口为输出引脚
}
void loop() {
 // put your main code here, to run repeatedly:
 //小车前进
 digitalWrite(2,LOW);
 digitalWrite(3,HIGH);
 digitalWrite(4,HIGH);
 digitalWrite(5,LOW);
 delay(1000);
 //小车后退
 digitalWrite(2,HIGH);
 digitalWrite(3,LOW);
 digitalWrite(4,LOW);
 digitalWrite(5,HIGH);
 delay(1000);
 //小车左转,右轮前,左轮后
 digitalWrite(2,HIGH);
 digitalWrite(3,LOW);
 digitalWrite(4,HIGH);
 digitalWrite(5,LOW);
 delay(1000);
 //小车右转,左轮前,右轮后
 digitalWrite(2,LOW);
 digitalWrite(3,HIGH);
 digitalWrite(4,LOW);
 digitalWrite(5,HIGH);
 delay(1000);
}
void qianJin() {
 // 小车前进的功能
  digitalWrite(2,LOW);
 digitalWrite(3,HIGH);
 digitalWrite(4,HIGH);
 digitalWrite(5,LOW);
}
void houTui() {//函数的封装
 // 小车后退的功能
 digitalWrite(2,HIGH);
 digitalWrite(3,LOW);
 digitalWrite(4,LOW);
 digitalWrite(5,HIGH);
}
void zuoZhuan(){
 digitalWrite(2,HIGH);
 digitalWrite(3,LOW);
 digitalWrite(4,HIGH);
 digitalWrite(5,LOW);
}
void youZhuan(){
 digitalWrite(2,LOW);
 digitalWrite(3,HIGH);
 digitalWrite(4,LOW);
 digitalWrite(5,HIGH); 
}
void carInit()
{
// put your setup code here, to run once:
 pinMode(2,OUTPUT);// 配置2口为输出引脚
 pinMode(3,OUTPUT);// 配置3口为输出引脚
 //右轮信号方向初始化
 pinMode(4,OUTPUT);// 配置4口为输出引脚
 pinMode(5,OUTPUT);// 配置5口为输出引脚 
}
void setup() {
 carInit();
}
void loop() {
 qianJin();//函数的调用
 delay(1000);
 houTui();
 delay(1000);
 zuoZhuan();
 delay(1000);
 youZhuan();
 delay(1000);
}


四. 串口
关于串口大家可能有所耳闻,那实际上我们都用了好几次了。
我们把程序通过电脑下载到WemosD1上的时候,就是通过串口通信
在程序中,我们也可以通过函数调用实现串口通信
完整代码:


五. 跟随模式开发
5.1 基本原理
超声波测距模块是用来测量距离的一种产品,通过发送和收超声波,利用时间差和声音传播速度,
计算出模块到前方障碍物的距离
型号:HC-SR04
接线参考:模块除了两个电源引脚外,还有TRIG,ECHO引脚
串口的初始化函数:
描述:开启串口,通常置于setup()函数中。
Serial.begin(speed)
 
参数:
speed:波特率,一般取值9600,115200等。
 
ArduinoUno通过串口发送一个消息给电脑
  Serial.print(“test message,这里是消息,喜欢发什么消息,就写什么消息”)
Serial.println(“test message,这里是消息,喜欢发什么消息,就写什么消息”), 比上面多了ln,代
表换行
void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);
}
void loop() {
 // put your main code here, to run repeatedly:
 Serial.print("上官帅哥");
 Serial.println("18cm");
}
怎么让它发波,看时许原理图
Trig,给Trig端口至少10us的高电平 ,
实验中,我们把Trig接到了单品机9口
怎么知道开始发了
Echo(8脚)信号,由低电平跳转到高电平,表示开始发送
怎么知道接收了返回波
Echo(8脚),由高电平跳转回低电平,表示波回来了
怎么算时间
Echo(8脚)引脚维持高电平的时间!
digitalWrite(9, LOW);
delayMicroseconds(2);
digitalWrite(9, HIGH);
delayMicroseconds(10);
digitalWrite(9, LOW);
怎么算距离
距离=速度(340m/s)*时间/2
5.2 代码实现
功能测试代码:
读引脚的脉冲信号,被读取的脉冲信号可以是 HIGH 或 LOW
例如我们要检测HIGH脉冲信号,
Arduino将在引脚变为高电平时开始计时, 当引脚变为低电平时停止记时,并返回脉冲持续时长(时间单位:微
秒)
long time;
time = pulseIn(8, HIGH)
pin 引脚编号
state 脉冲状态
void setup() {
 // put your setup code here, to run once:
 // Trig 接 9,通过9发送一个触发信号给超声波
 pinMode(9,OUTPUT);
 // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
 pinMode(8,INPUT);
 Serial.begin(9600);
}
void loop() {
 long shijian;
 long juli;
 // put your main code here, to run repeatedly:
 // 发送一个10us的信号给超声波,9Trig
 digitalWrite(9, LOW);
 delayMicroseconds(2);
 digitalWrite(9, HIGH);
 delayMicroseconds(10);
 digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
 shijian = pulseIn(8,HIGH);
 // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
 juli = shijian * 0.017;
 Serial.print(juli);
 Serial.println("cm");
}
//封装测距代码

5.3 跟随小车
//函数:名 参数 返回值
long getDis() {
 // 测距函数
 long shijian;
 long juli;
 // put your main code here, to run repeatedly:
 // 发送一个10us的信号给超声波,9Trig
 digitalWrite(9, LOW);
 delayMicroseconds(2);
 digitalWrite(9, HIGH);
 delayMicroseconds(10);
 digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
 shijian = pulseIn(8,HIGH);
 // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
 juli = shijian * 0.017;
 return juli;
}
void setup() {
 // put your setup code here, to run once:
 // put your setup code here, to run once:
 // Trig 接 9,通过9发送一个触发信号给超声波
 pinMode(9,OUTPUT);
 // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
 pinMode(8,INPUT);
 Serial.begin(9600);
}
void loop() {
 // put your main code here, to run repeatedly:
 long juli;
 juli = getDis();
 Serial.print(juli);
 Serial.println("cm");
}
//前进
void qianJin() {
 // 小车前进的功能
 digitalWrite(2,LOW);
 digitalWrite(3,HIGH);
 digitalWrite(4,HIGH);
 digitalWrite(5,LOW);
}
//后退
void houTui() {//函数的封装
 // 小车后退的功能
  digitalWrite(2,HIGH);
 digitalWrite(3,LOW);
 digitalWrite(4,LOW);
 digitalWrite(5,HIGH);
}
//ting
void ting() {//函数的封装
 // 小车后退的功能
 digitalWrite(2,LOW);
 digitalWrite(3,LOW);
 digitalWrite(4,LOW);
 digitalWrite(5,LOW);
}
//测距
//函数:名 参数 返回值
long getDis() {
 // 测距函数
 long shijian;
 long juli;
 // put your main code here, to run repeatedly:
 // 发送一个10us的信号给超声波,9Trig
 digitalWrite(9, LOW);
 delayMicroseconds(2);
 digitalWrite(9, HIGH);
 delayMicroseconds(10);
 digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
 shijian = pulseIn(8,HIGH);
 // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
 juli = shijian * 0.017;
 return juli;
}
void carInit()
{
// put your setup code here, to run once:
 pinMode(2,OUTPUT);// 配置2口为输出引脚
 pinMode(3,OUTPUT);// 配置3口为输出引脚
 //右轮信号方向初始化
 pinMode(4,OUTPUT);// 配置4口为输出引脚
 pinMode(5,OUTPUT);// 配置5口为输出引脚 
}
void setup() {
 // put your setup code here, to run once:
 carInit();
  // Trig 接 9,通过9发送一个触发信号给超声波
 pinMode(9,OUTPUT);
 // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间


六. 摇头避障模式开发
6.1 舵机基本介绍
如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制用处:垃圾桶项目开盖
用、智能小车的全比例转向、摄像头云台、机械臂等
常见的有0-90°、0-180°、0-360°
怎么控制转角
Arduino官方提供Servo类来支持舵机操作
 pinMode(8,INPUT);
}
void loop() {
 // put your main code here, to run repeatedly:
 delay(50);//为了放缓超声波交互的速度,交互过快,得出距离后会卡顿,影响效果体验
 long juli;
 juli = getDis();
 //如果距离大于3且小于13,后退
 if( 3 < juli && juli < 15){
  houTui();
}
 //如果距离大于14且小于40,前进
 if( 14 < juli && juli < 40){
  qianJin(); 
}
 if(juli > 50){
  ting(); 
}
}
小车摇头代码实现
6.2 摇头测距组合
代码实现
//舵机的初始化
Servo  myServo; //定义一个Servo变量
myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
myServo.write(0);//转到某角度,根据实际执行观看
myServo.write(90);//转到某角度,根据实际执行观看
#include
Servo  myServo;//因为很多子函数要用这个变量,所以把servo定义成全局变量,作用域是整个代码文件
void setup() {
 // put your setup code here, to run once:
 //定义一个Servo变量
 myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
}
void loop() {
 // put your main code here, to run repeatedly:
 myServo.write(30);//右方向
 delay(500);
 myServo.write(100);//中间方向
 delay(500);
 myServo.write(170);//左边方向
 delay(500);
 myServo.write(100);//中间方向
 delay(500);
}
#include
Servo  myServo;//因为很多子函数要用这个变量,所以把servo定义成全局变量,作用域是整个代码文件
long getDis() {
 // 测距函数
 long shijian;
 long juli;
 // put your main code here, to run repeatedly:
 // 发送一个10us的信号给超声波,9Trig
 digitalWrite(9, LOW);
 delayMicroseconds(2);
 digitalWrite(9, HIGH);
 delayMicroseconds(10);
 digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
  // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
 shijian = pulseIn(8,HIGH);
 // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
 juli = shijian * 0.017;
 return juli;
}
void setup() {
 // put your setup code here, to run once:
 //定义一个Servo变量
 myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
 // Trig 接 9,通过9发送一个触发信号给超声波
 pinMode(9,OUTPUT);
 // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
 pinMode(8,INPUT);
 Serial.begin(9600);
}
void loop() {
 long youjuli;
 long zhongjuli;
 long zuojuli;
 // put your main code here, to run repeatedly:
 myServo.write(30);//右方向
 delay(500);
 youjuli = getDis();
 Serial.print("右边距离是:");
 Serial.println(youjuli);
 myServo.write(100);//中间方向
 delay(500);
 zhongjuli = getDis();
 Serial.print("中间距离是:");
 Serial.println(zhongjuli);
 myServo.write(170);//左边方向
 delay(500);
 zuojuli = getDis();
 Serial.print("左边距离是:");
 Serial.println(zuojuli);
 myServo.write(100);//中间方向
 delay(500);
}
6.3 摇头避障功能实现
代码
#include
Servo  myServo;//因为很多子函数要用这个变量,所以把servo定义成全局变量,作用域是整个代码文件
void ting() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 digitalWrite(5, LOW);
}
void qianJin() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 digitalWrite(3, HIGH);
 digitalWrite(4, HIGH);
 digitalWrite(5, LOW);
}
void houTui() {//函数的封装
 // 小车后退的功能
 digitalWrite(2, HIGH);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 digitalWrite(5, HIGH);
}
void zuoZhuan() {
 digitalWrite(2, HIGH);
 digitalWrite(3, LOW);
 digitalWrite(4, HIGH);
 digitalWrite(5, LOW);
}
void youZhuan() {
 digitalWrite(2, LOW);
 digitalWrite(3, HIGH);
 digitalWrite(4, LOW);
 digitalWrite(5, HIGH);
}
void carInit()
{
 // put your setup code here, to run once:
 pinMode(2, OUTPUT); // 配置2口为输出引脚
 pinMode(3, OUTPUT); // 配置3口为输出引脚
 //右轮信号方向初始化
 pinMode(4, OUTPUT); // 配置4口为输出引脚
  pinMode(5, OUTPUT); // 配置5口为输出引脚
}
long getDis() {
 // 测距函数
 long shijian;
 long juli;
 // put your main code here, to run repeatedly:
 // 发送一个10us的信号给超声波,9Trig
 digitalWrite(9, LOW);
 delayMicroseconds(2);
 digitalWrite(9, HIGH);
 delayMicroseconds(10);
 digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
 shijian = pulseIn(8, HIGH);
 // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
 juli = shijian * 0.017;
 return juli;
}
void setup() {
 // put your setup code here, to run once:
 //定义一个Servo变量
 carInit();
 myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
 // Trig 接 9,通过9发送一个触发信号给超声波
 pinMode(9, OUTPUT);
 // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
 pinMode(8, INPUT);
 Serial.begin(9600);
}
void loop() {
 long youjuli;
 long zhongjuli;
 long zuojuli;
 //如果前面没有障碍物,我让小车往前走
 myServo.write(100);//中间方向
 delay(500);
 zhongjuli = getDis();
 Serial.print("中间距离是:");
 Serial.println(zhongjuli);
 if (zhongjuli < 35) {
  ting();//检测到前方右障碍物
七. 小车控速
7.1 analogWrite函数
analogWrite替换digitalWrite
说明
将一个模拟数值写进Arduino引脚。这个操作可以用来控制LED的亮度, 或者控制电机的转速.
在Arduino UNO控制器中,
analogWrite()函数支持以下引脚: 3, 5, 6, 9, 10, 11
在调用analogWrite()函数前,您无需使用pinMode()函数来设置该引脚。
  //往右边摇头,并测距
  myServo.write(30);//右方向
  delay(500);
  youjuli = getDis();
  Serial.print("右边距离是:");
  Serial.println(youjuli);
  myServo.write(100);//测完右边距离,再回到中间,此时可以不测距
  delay(500);
  //往左边摇头,测左边距离
  myServo.write(170);//左边方向
  delay(500);
  zuojuli = getDis();
  Serial.print("左边距离是:");
  Serial.println(zuojuli);
  myServo.write(100);//测完右边距离,再回到中间,此时可以不测距
  delay(500);
  if(zuojuli > youjuli){
   Serial.println("左转");
   zuoZhuan();
   delay(100);
   ting(); 
 }
  if(zuojuli < youjuli){
   Serial.println("右转");
   youZhuan();
   delay(100);
   ting(); 
 }
} else { //前方无障碍物,小车前进
  qianJin();
}
}
语法
参数

小车情况说明
2,3控左电机,4,5控右电机
analogWrite(pin, value)
//小车前进的代码是:
void qianJin() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 digitalWrite(3, HIGH);
 digitalWrite(4, HIGH);
 digitalWrite(5, LOW);
}
//如果我们只对前进,左转,右转控制速度
//由于硬件特性:Arduino UNO的3,5口支持analogWrite函数,2,4口不支持
//所以,我希望前进的代码是
void qianJin() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 digitalWrite(3, HIGH);
 digitalWrite(4, LOW);
 digitalWrite(5, HIGH);
}
//此时,把接口4,5的杜邦线对调
//为了速度控制可以优化代码成
  void qianJin() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 analogWrite(3, 120);
 digitalWrite(4, HIGH);
 analogWrite(5, 120);//120是
}
7.2 控制前进速度的代码
7.3 控速前进左转右转
/*
非常注意:
把IO口4和IO口5的接线对调!
前进代码左轮3是模拟输出,5是模拟输出,2和4口不支持,直接给低电平
3口和5口支持模拟输出,达到小车前进方向上的速度控制目的。
*/
void carInit()
{
 // put your setup code here, to run once:
 pinMode(2, OUTPUT); // 配置2口为输出引脚
 pinMode(3, OUTPUT); // 配置3口为输出引脚
 //右轮信号方向初始化
 pinMode(4, OUTPUT); // 配置4口为输出引脚
 pinMode(5, OUTPUT); // 配置5口为输出引脚
}
void qianJin() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 analogWrite(3, 230);
 digitalWrite(4, LOW);
 analogWrite(5, 230);
}
void setup() {
 // put your setup code here, to run once:
 carInit();
}
void loop() {
 // put your main code here, to run repeatedly:
 qianJin();
}
void carInit()
{
 // put your setup code here, to run once:
 pinMode(2, OUTPUT); // 配置2口为输出引脚
 pinMode(3, OUTPUT); // 配置3口为输出引脚
 //右轮信号方向初始化
 pinMode(4, OUTPUT); // 配置4口为输出引脚
 pinMode(5, OUTPUT); // 配置5口为输出引脚
}
void qianJin() {
 // 小车前进的功能


八. 循迹功能
8.1 红外循迹模块 TCRT5000
 digitalWrite(2, LOW);
 analogWrite(3, 150);
 digitalWrite(4, LOW);
 analogWrite(5, 150);
}
void zuoZhuan() {
 // 小车左转,左边电机速度慢,右边电机速度快
 digitalWrite(2, LOW);
 analogWrite(3, 90); //左
 digitalWrite(4, LOW);
 analogWrite(5, 250);//右
}
void youZhuan() {
 // 小车左转,左边电机速度慢,右边电机速度快
 digitalWrite(2, LOW);
 analogWrite(3, 250); //左
 digitalWrite(4, LOW);
 analogWrite(5, 90);//右
}
void setup() {
 // put your setup code here, to run once:
 carInit();
}
void loop() {
 // put your main code here, to run repeatedly:
 youZhuan();
}
TCRT5000传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来
但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于
熄灭状态;
总之一句话:没反射回来,D0输出高电平,灭灯
思考:
什么情况下红外线没有返回来
红外照射在黑线上咯
在黑线上DO电平表现
高电平!
灯的表现
灭灯
什么时候该左转
说明小车偏右,说明左循迹模块在黑线上,左循迹模块的电平表现为高电平,右循迹模块能接收
到红外,电平表现为低电平
什么实时该右转
说明小车偏左,右循迹在黑线上,右循迹高电平,左循迹低电平


8.2 代码实现
/*
做循迹模块接Arduino的11口,右循迹模块接Arduinod的12口
小车控制速度前进
*/
int leftX = 11;
int rightX = 12;
void carInit()
{
 // put your setup code here, to run once:
 pinMode(2, OUTPUT); // 配置2口为输出引脚
 pinMode(3, OUTPUT); // 配置3口为输出引脚
  //右轮信号方向初始化
 pinMode(4, OUTPUT); // 配置4口为输出引脚
 pinMode(5, OUTPUT); // 配置5口为输出引脚
}
void qianJin() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 analogWrite(3, 100);
 digitalWrite(4, LOW);
 analogWrite(5, 100);
}
void ting() {
 // 小车前进的功能
 digitalWrite(2, LOW);
 analogWrite(3, 0);
 digitalWrite(4, LOW);
 analogWrite(5, 0);
}
void zuoZhuan() {
 // 小车左转,左边电机速度慢,右边电机速度快
 digitalWrite(2, LOW);
 analogWrite(3, 80); //左
 digitalWrite(4, LOW);
 analogWrite(5, 250);//右
}
void youZhuan() {
 // 小车左转,左边电机速度慢,右边电机速度快
 digitalWrite(2, LOW);
 analogWrite(3, 250); //左
 digitalWrite(4, LOW);
 analogWrite(5, 80);//右
}
void setup() {
 // put your setup code here, to run once:
 carInit();
 pinMode(leftX,INPUT);
 pinMode(rightX,INPUT);
}
void loop() {
 // put your main code here, to run repeatedly:
 //什么时候该左转
 //左循迹模块的电平表现为高电平,右循迹模块表现为低电平
 if( digitalRead(leftX) == 1 && digitalRead(rightX) == 0 ){
   zuoZhuan();
}
 //什么时候右转
 //右循迹高电平,左循迹低电平
 if( digitalRead(leftX) == 0 && digitalRead(rightX) == 1 ){
  youZhuan(); 
}
 //什么时候前进
 //左右都为低电平
 if( digitalRead(leftX) == 0 && digitalRead(rightX) == 0 ){
  qianJin(); 
}
 //什么时候停
 //左右都为高电平
 if( digitalRead(leftX) == 1 && digitalRead(rightX) == 1 ){
  ting(); 
}
}
 

你可能感兴趣的:(单片机,嵌入式硬件)