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();
}
}
}
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)
红外壁障模块分析
- 原理和循迹是类似的,循迹红外朝下,跟随朝前
跟随小车的原理
- 左边跟随模块能返回红外,输出低电平,说明物体在左边,右边不能返回,输出高电平,需要左转
- 右边跟随模块能返回红外,输出低电平,说明物体在右边,左边不能返回,输出高电平,需要右转
代码(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();
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();
Delay300ms();
disRight = getDistance();
if(disLeft < disRight){
goRight();
Delay150ms();
stop();
}
if(disLeft > disRight){
goLeft();
Delay150ms();
stop();
}
}
}
}