STC89C51基础及项目第14天:循迹小车、跟随小车、避障小车

1. 循迹小车基本原理和方案(269.114)

循迹模块使用

  • TCRT5000传感器的红外发射二极管不断发射红外线:
  • 当发射出的红外线 没有 被反射回来或被反射回来但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为 高电平,指示二极管一直处于 熄灭状态
  • 被检测物体出现 在检测范围内 时,红外线 被反射回来 且强度足够大,红外接收管饱和,此时模块的输出端为 低电平,指示二极管 被点亮
  • 总结:没反射回来,D0输出高电平,灭灯
    STC89C51基础及项目第14天:循迹小车、跟随小车、避障小车_第1张图片

STC89C51基础及项目第14天:循迹小车、跟随小车、避障小车_第2张图片

  • 接线方式
    • VCC:接电源正极(3 - 5V)
    • GND:接电源负极
    • DO: TTL开关信号输出 0、1
    • AO: 模拟信号输出(不同距离输出不同的电压,此脚一般可以不接)

循迹小车原理

  • 由于黑色具有较强的吸收能力,当循迹模块发射的红外线 照射到黑线时,红外线将会 被黑线吸收,导致循迹模块上光敏三极管 处于关闭状态,此时模块上 一个 LED 熄灭
  • 没有检测到 黑线时,模块上 两个 LED 常亮
  • 总结:有感应到黑线,D0输出高电平,灭灯
    STC89C51基础及项目第14天:循迹小车、跟随小车、避障小车_第3张图片
  • 循迹模块安装在小车车头两侧:
    • 下方小车两个模块都能 反射回来红外,输出 低电平,灯亮,直走
    • 上方小车左模块遇到黑线,红外被吸收,左模块输出 高电平且左灯灭,右模块输出 低电平且右灯亮,左转,反之右转

2. 根据循迹原理实现循迹功能代码编写(270.115)

  • 代码(20./07. 循迹小车实现)(不调速方式写代码)
#include "motor.h"
#include "delay.h"
#include "reg52.h"

sbit leftSensor = P2^7;
sbit rightSensor = P2^6;

void main(){
//下方小车两个模块都能反射回来红外,输出低电平,灯亮,直走
//上方小车左模块遇到黑线,红外被吸收,左模块输出高电平且左灯灭,右模块输出低电平且右灯亮,左转,反之右转
	while(1){
		if(leftSensor == 0 && rightSensor == 0){//左右都反射回来,都低电平,直走,灯都亮
			goForward();
		}
		
		if(leftSensor == 1 && rightSensor == 0){//左边没反射回来,左高电平,左转,右灯亮
			goLeft();
		}
		
		if(leftSensor == 0 && rightSensor == 1){//右边没反射回来,右高电平,右转,左灯亮
			goRight();
		}
		
		if(leftSensor == 1 && rightSensor == 1){//左右都没反射回来,都高电平,停,灯都不亮
			stop();
		}
	}
}

3. 循迹实际测试和电位器调节(271.116)

4. 解决转弯干滑问题,加入电机调速

#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "timer.h"
#include "reg52.h"

sbit leftSensor = P2^7;
sbit rightSensor = P2^6;

extern char speedLeft;
extern char speedRight;

void main(){
	Timer0Init();
	Timer1Init();
	//UartInit();
	
	while(1){
		if(leftSensor == 0 && rightSensor == 0){//左右都反射回来,都低电平,直走,灯都亮
			speedLeft = 40;
			speedRight = 40;
		}
		
		if(leftSensor == 1 && rightSensor == 0){//左边没反射回来,左高电平,左转,右灯亮
			speedLeft = 15;   //10份单位时间前进,30份停止,所以慢(20ms是40份的500us)
			speedRight = 40;	//左转
		}
		
		if(leftSensor == 0 && rightSensor == 1){//右边没反射回来,右高电平,右转,左灯亮
			speedLeft = 40;   //40份单位时间前进,0份停止,所以全速(20ms是40份的500us)
			speedRight = 15;	//右转
		}
		
		if(leftSensor == 1 && rightSensor == 1){//左右都没反射回来,都高电平,停,灯都不亮
			speedLeft = 0;
			speedRight = 0;
		}
	}
}
  • 代码(20./08. 循迹小车解决转弯平滑问题)(调速方式写代码)

5. 跟随小车(274.119)

红外壁障模块分析

STC89C51基础及项目第14天:循迹小车、跟随小车、避障小车_第4张图片

  • 原理和循迹是类似的,循迹红外朝下,跟随朝前

跟随小车的原理

  • 左边跟随模块能返回红外,输出低电平,说明物体在左边,右边不能返回,输出高电平,需要左转
  • 右边跟随模块能返回红外,输出低电平,说明物体在右边,左边不能返回,输出高电平,需要右转

代码(20./09. 跟随小车)

#include "motor.h"
#include "delay.h"
#include "reg52.h"

sbit leftSensor = P2^5;
sbit rightSensor = P2^4;

void main(){
//左边跟随模块能返回红外,输出低电平,说明物体在左边,右边不能返回,输出高电平,需要左转
//右边跟随模块能返回红外,输出低电平,说明物体在右边,左边不能返回,输出高电平,需要右转
	while(1){
		if(leftSensor == 0 && rightSensor == 0){//两边都反射回来了,都低电平,直走
			goForward();
		}
		
		if(leftSensor == 1 && rightSensor == 0){//右边反射回来了,右低电平,右转
			goRight();
		}
		
		if(leftSensor == 0 && rightSensor == 1){//左边反射回来了,左低电平,左转
			goLeft();
		}
		
		if(leftSensor == 1 && rightSensor == 1){//两边都没反射回来,都高电平,停
			stop();
		}
	}
}

6. 跟随小车效果(275.120)

7. 摇头测距小车01_舵机和超声波封装(276.121)

  • 代码(20./10. 摇头避障小车/摇头避障小车01_改装垃圾桶代码)

8. 摇头测距小车02_实现疯狂摇头(277.122)

  • 代码(20./10. 摇头避障小车/摇头避障小车02_摇头)
#include "reg52.h"
#include "hc04.h"
#include "delay.h"
#include "sg90.h"

void main()
{
	Timer0Init();
	Timer1Init();
	//舵机的初始位置
	sgMiddle();
	Delay2000ms();
	
	while(1){
		sgLeft();
		Delay300ms();
		sgMiddle();
		Delay300ms();
		
		sgRight();
		Delay300ms();
		sgMiddle();
		Delay300ms();
	}
}

9. 摇头测距小车03_测距摇头(278.123)

  • 代码(20./10. 摇头避障小车/摇头避障小车03_测距摇头实现)
#include "reg52.h"
#include "hc04.h"
#include "delay.h"
#include "sg90.h"

void main(){
	
	double disMiddle;
	double disLeft;
	double disRight;
	
	Timer0Init();
	Timer1Init();
	//舵机的初始位置
	sgMiddle();
	Delay2000ms();
	
	while(1){
		disMiddle = getDistance();
		
		if(disMiddle > 35){
			//前进
		}else{
			//停止
			//sg左转 测左边距离
			sgLeft();
			Delay300ms();
			disLeft = getDistance();
			
			sgMiddle();
			Delay300ms();
			
			//sg右转 测右边距离
			sgRight();
			Delay300ms();
			disRight = getDistance();
			
			sgMiddle();
			Delay300ms();
		}
	}
}

10. 摇头测距小车04_摇头训距和行驶(279.124)

  • 代码(20./10. 摇头避障小车/摇头避障小车04_摇头测距加电机联动)
#include "reg52.h"
#include "hc04.h"
#include "delay.h"
#include "sg90.h"
#include "motor.h"

#define MIDDLE 0
#define LEFT 1
#define RIGHT 2

void main(){
	char dir;

	double disMiddle;
	double disLeft;
	double disRight;
	
	Timer0Init();
	Timer1Init();
	//舵机的初始位置
	sgMiddle();
	Delay2000ms();
	
	while(1){
		if(dir != MIDDLE){
			sgMiddle();
			dir = MIDDLE;
			Delay300ms();
		}
		disMiddle = getDistance();
		
		if(disMiddle > 35){
			//前进
			goForward();
		}else{
			//停止
			stop();
			//sg左转 测左边距离
			sgLeft();
			Delay300ms();
			disLeft = getDistance();
			
			sgMiddle();
			Delay300ms();
			
			//sg右转 测右边距离
			sgRight();
			Delay300ms();
			disRight = getDistance();
			
			if(disLeft < disRight){
				goRight();
				Delay150ms();
				stop();
			}
			if(disLeft > disRight){
				goLeft();
				Delay150ms();
				stop();
			}
		}
	}
}

11. 实地测试及BUG微调(280.125)

  • 代码(20./10. 摇头避障小车/摇头避障小车05_bug修改)
#include "reg52.h"
#include "hc04.h"
#include "delay.h"
#include "sg90.h"
#include "motor.h"

#define MIDDLE 0
#define LEFT 1
#define RIGHT 2

void main(){
	char dir;

	double disMiddle;
	double disLeft;
	double disRight;
	
	Timer0Init();
	Timer1Init();
	//舵机的初始位置
	sgMiddle();
	Delay2000ms();
	dir = MIDDLE;

	while(1){
		if(dir != MIDDLE){
			sgMiddle();
			dir = MIDDLE;
			Delay300ms();
		}
		disMiddle = getDistance();
		
		if(disMiddle > 35){
			//前进
			goForward();
		}else if(disMiddle < 10){
			goBack();
		}else{
			//停止
			stop();
			//sg左转 测左边距离
			sgLeft();
			Delay300ms();
			disLeft = getDistance();
			
			sgMiddle();
			Delay300ms();
			
			//sg右转 测右边距离
			sgRight();
			dir = RIGHT;
			Delay300ms();
			disRight = getDistance();
			
			if(disLeft < disRight){
				goRight();
				Delay150ms();
				stop();
			}
			if(disLeft > disRight){
				goLeft();
				Delay150ms();
				stop();
			}
		}
	}
}

你可能感兴趣的:(单片机)