|
本帖最后由 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,实物连接与效果图:
|
|