四博智联产品售后
标题:
基于ESPDuino的四路循迹小车实例
[打印本页]
作者:
linXJ
时间:
2016-8-15 17:03
标题:
基于ESPDuino的四路循迹小车实例
本帖最后由 linXJ 于 2017-3-17 15:11 编辑
1,实验材料:
ESPDuino开发板,Doit电机驱动模块,四路循迹模块,T-200 Doit小车,杜邦线若干;
2,实物连接:
电机驱动模块的 DC-MOTOR 端口 A+、A-和 B+、B-分别接电机 A 的正负极和电机 B 的正负极;IN-6-18V 端口的 VM、GND 分别接电源(18650 电池盒)的正负极;
其中:PinPWMA 对应开发板的 IO 口 14---用于控制电机 A 速度;
PinPWMB 对应开发板的 IO 口 12---用于控制电机 B 速度;
PinDirA 对应开发板的 IO 口15---用于控制电机 A 转向;
PinDirB 对应开发板的 IO 口 13---用于控制电机 B 转向;
循迹模块上的vcc与GND分别接电机驱动板上面的5V和GND管脚;IN1、IN2、IN3、IN4分别接电机驱动板的5(D5)、4(D4)、11(D3)、2(D0),(括号里表示ESPDUINO板上对应的IO口管脚);
3,实验原理:
原理:
在白色地面上画一条宽度适中(1-3cm,最宽不能超过循迹模块最左端与最右端两个探测灯的距离)的黑色路线,让位于小车底盘的循迹模块发射的红外线,根据黑色对红外线的吸收作用,红外光射在白色地面会接收到反射光,相应管脚被置0(低电平),当循迹探头对准黑色路线上时没有接收到反射光,相应管脚置1(高电平);根据这个原理就可以控制小车沿着黑色路线前进了。
温馨提示:
4路循迹模块排成倒梯形(最左边(IN4)和最右边(IN1)位于稍微靠前的位置,让探测更具有前瞻性,进而反应更灵敏。中间的两个,左边为IN3,右边为IN2,两者距离要与地面的黑色路线等宽,循迹过程中保证两者一直在黑色路线上即可);
4,示例源码:
<div class="blockcode"><blockquote>#include <Ticker.h>
#define PinPWMA 14 //电机1速度
#define PinPWMB 12 //电机2速度
#define PinDirA 15 //电机1转向
#define PinDirB 13 //电机2转向
#define left1 0 //左1探头
#define left2 3 //左2探头
#define right2 4 //右2探头
#define right1 5 //右1探头
extern "C"
{
#include "user_interface.h"
#include "smartconfig.h"
}
/************** PWM Driver *************************/
#define MAXPIN 17
Ticker pwmTickersSetHigh[MAXPIN];
Ticker pwmTickersSetLow[MAXPIN];
const int pwmExponent = 3;
const int pwmFactor = 8;
const int pwmRoundoff = pwmFactor/2;
const int pwmDutyCycle = 256/pwmFactor;
// 类似analogWrite()
void pwmWrite(int pin, int value)
{
if (pin < 0 || pin >= MAXPIN || value < 0 || value > 255)
return;
pwmTickersSetHigh[pin].detach();
pwmTickersSetLow[pin].detach();
int highTime = (value+pwmRoundoff)/pwmFactor;
if (highTime <= 0)
pwmSetLow(pin);
else if (highTime >= pwmDutyCycle)
pwmSetHigh(pin);
else
{
pwmSetHigh(pin);
pwmTickersSetHigh[pin].attach_ms(pwmDutyCycle, pwmSetHigh, pin);
pwmTickersSetLow[pin].once_ms(highTime, pwmStartLow, pin);
}
}
void pwmSetHigh(int pin)
{
digitalWrite(pin, HIGH);
}
void pwmSetLow(int pin)
{
digitalWrite(pin, LOW);
}
void pwmStartLow(int pin)
{
pwmSetLow(pin);
pwmTickersSetLow[pin].attach_ms(pwmDutyCycle, pwmSetLow, pin);
}
/********************** PWM Driver *********************/
Ticker timer;
unsigned char val_L1 =1;//左1
unsigned char val_L2 =1;//左2
unsigned char val_R2 =1;//右2
unsigned char val_R1 =1;//右1
unsigned char temp=0;
unsigned char bb=0;
unsigned char flag=0;
int value = 0;
//定时每0.1秒红外自动扫描
void tick_Infrared_control()
{
val_L1=digitalRead(left1);
val_L2=digitalRead(left2);
val_R2=digitalRead(right2);
val_R1=digitalRead(right1);
temp=0;
temp=temp|(val_L1);
temp=(temp<<1)|(val_L2);
temp=(temp<<1)|(val_R2);
temp=(temp<<1)|(val_R1);
bb=0x0f&temp;
}
void initParseData()
{
//电机控制初始化
pinMode(PinPWMA, OUTPUT);
pinMode(PinPWMB, OUTPUT);
pinMode(PinDirA, OUTPUT);
pinMode(PinDirB, OUTPUT);
digitalWrite(PinDirA, HIGH);
digitalWrite(PinDirB, HIGH);
pwmWrite(PinPWMA, 100);
pwmWrite(PinPWMB, 100);
//红外扫描初始化
pinMode(left1, INPUT);
pinMode(left2, INPUT);
pinMode(right2, INPUT);
pinMode(right1, INPUT);
//启动定时器
timer.attach(0.1, tick_Infrared_control);//红外扫描
}
//小车控制
void go_stopp()//暂停
{
pwmWrite(PinPWMA, 0);
pwmWrite(PinPWMB, 0);
delay(100);
}
void go_advance(int value)// 前进
{
int aa;
aa=value;
digitalWrite(PinDirA, HIGH);
digitalWrite(PinDirB, HIGH);
pwmWrite(PinPWMA, aa);
pwmWrite(PinPWMB, aa);
delay(100);
}
void go_advance1(int value)// 前进 偏向左
{
int aa;
aa=value;
digitalWrite(PinDirA, HIGH);
digitalWrite(PinDirB, HIGH);
pwmWrite(PinPWMA, aa);
pwmWrite(PinPWMB, aa+20);
delay(100);
}
void go_advance2(int value)// 前进 偏向右
{
int aa;
aa=value;
digitalWrite(PinDirA, HIGH);
digitalWrite(PinDirB, HIGH);
pwmWrite(PinPWMA, aa+20);
pwmWrite(PinPWMB, aa);
delay(100);
}
void go_back(int value)//后退
{
int aa;
aa=value;
digitalWrite(PinDirA, LOW);
digitalWrite(PinDirB, LOW);
pwmWrite(PinPWMA, aa);
pwmWrite(PinPWMB, aa);
delay(100);
}
void go_left_1(int value)//原地左转
{
int aa;
aa=value;
digitalWrite(PinDirA, LOW);
digitalWrite(PinDirB, HIGH);
pwmWrite(PinPWMA, 0);
pwmWrite(PinPWMB, aa);
delay(100);
}
void go_left_2(int value)//大左转(双轮)
{
int aa;
aa=value;
digitalWrite(PinDirA, LOW);
digitalWrite(PinDirB, HIGH);
pwmWrite(PinPWMA, aa);
pwmWrite(PinPWMB, aa);
delay(100);
}
void go_right_1(int value)//原地右转
{
int aa;
aa=value;
digitalWrite(PinDirA, HIGH);
digitalWrite(PinDirB, LOW);
pwmWrite(PinPWMA, aa);
pwmWrite(PinPWMB, 0);
delay(100);
}
void go_right_2(int value)//大右转(双轮)
{
int aa;
aa=value;
digitalWrite(PinDirA, HIGH);
digitalWrite(PinDirB, LOW);
pwmWrite(PinPWMA, aa);
pwmWrite(PinPWMB, aa);
delay(100);
}
//循迹程序
void setup()
{
initParseData();
delay(10);
go_advance(100);
}
void loop()
{
switch(bb)
{
case 0x00: //0000 0
{
go_advance(50);
break;
}
case 0x08: //1000 8
{
go_left_2(90);
flag=1;
break;
}
case 0x0c: //1100 12
{
go_left_1(140);
flag=1;
break;
}
case 0x04: //0100 4
{
go_left_1(80);
delay(100);
go_advance(100);
break;
}
case 0x0e: //1110 14
{
go_advance1(100);
break;
}
case 0x06: //0110 6
{
go_advance(100);
flag=0;
break;
}
case 0x07: //0111 7
{
go_advance2(90);
break;
}
case 0x02: //0010 2
{
go_right_1(80);
delay(100);
go_advance(100);
break;
}
case 0x03: //0011 3
{
go_right_1(100);
flag=2;
break;
}
case 0x01: //0001 1
{
go_right_1(120);
flag=2;
break;
}
case 0x0f: //1111 15
{
go_left_2(100);
flag=2;
break;
}
default :
{
switch(flag)
{
case 0:go_advance(100);break;
case 1:go_left_1(120);break;
case 2:go_right_1(110);break;
case 3:go_stopp();break;
}
}
}
}
复制代码
5,实物连接与效果图:
Doit循迹小车.jpg
(301.91 KB, 下载次数: 1551)
下载附件
2017-3-17 15:10 上传
欢迎光临 四博智联产品售后 (http://bbs.doit.am/)
Powered by Discuz! X3.2