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


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

    循迹模块使用

    • TCRT5000传感器的红外发射二极管不断发射红外线:
    • 当发射出的红外线 没有 被反射回来或被反射回来但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为 高电平,指示二极管一直处于 熄灭状态
    • 被检测物体出现 在检测范围内 时,红外线 被反射回来 且强度足够大,红外接收管饱和,此时模块的输出端为 低电平,指示二极管 被点亮
    • 总结:没反射回来,D0输出高电平,灭灯
      在这里插入图片描述

    在这里插入图片描述

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

    循迹小车原理

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

    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();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 代码(20./08. 循迹小车解决转弯平滑问题)(调速方式写代码)

    5. 跟随小车(274.119)

    红外壁障模块分析

    在这里插入图片描述

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

    跟随小车的原理

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

    代码(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();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    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();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    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();
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    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();
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
  • 相关阅读:
    QFileInfo 类【官翻】
    std::string与LPCTSTR/LPWSTR互转
    623. 在二叉树中增加一行(难度:中等)
    Go 语言内置类型全解析:从布尔到字符串的全维度探究
    项目管理,看这篇就够了,但一定要实操!
    会计基础——公式汇总
    限制容器中的进程
    Redash大屏视图样式(中)
    [附源码]计算机毕业设计停车场管理系统Springboot程序
    RPC远程调用加密方法获取返回值
  • 原文地址:https://blog.csdn.net/Jaci133/article/details/133708894