|
最近对Wifi小车着迷,试着做了一下,用的组件如下:
Arduino Leonardo + 山寨AFMotor Shield + 大亚DB120(论坛Openwrt,带Ser2net及摄像头驱动)+12v 18650电池组+“WIFI/蓝牙智能小车操作平台”
通信部分通过TTL线连接板载RX/TX串口。
- Arduino源代码如下(借鉴《基于Arduino开源平台的WIFI视频监控小车》一文中的代码):
#include <Servo.h> //舵机控制库
#include <AFMotor.h> //AF motor shield library
//电机控制端口设置
#define EN1 5//控制左侧电机速度
#define EN2 6//控制右侧电机速度
#define IN1 4//控制左侧电机方向
#define IN2 7//控制右侧电机方向
#define FORW 0//前进
#define BACK 1//后退
#define dataLenMax 16 //设置最大数据帧长度 不大于16
//Servo servoX; //云台X轴舵机 左右
//Servo servoY; //云台Y轴舵机 上下
//Define Right_Front_motor,Left_Front_motor,Left_Back_motor,Right_Back_motor DC motors
AF_DCMotor Left_Back_motor(1);
AF_DCMotor Right_Back_motor(2);
AF_DCMotor Right_Front_motor(3);
AF_DCMotor Left_Front_motor(4);
//控制电机转动子函数
void Motor_Control(int M12_DIR,int M12_EN,int M34_DIR,int M34_EN)
{
//////////M12////////////////////////
if(M12_DIR==FORW)//M1电机的方向
{
Right_Front_motor.run(FORWARD); //Right_Front_motor forward
// Left_Front_motor.run(FORWARD); //Left_Front_motor forward
}
else{
Right_Front_motor.run(BACKWARD); //Right_Front_motor backward
// Left_Front_motor.run(BACKWARD); //Left_Front_motor backward
}
if(M12_EN==0)//M1电机的速度
{
Right_Front_motor.run(RELEASE); //Right_Front_motor stop
// Left_Front_motor.run(RELEASE); //Left_Front_motor stop
}
else
{
Right_Front_motor.setSpeed(M12_EN);
// Left_Front_motor.setSpeed(M12_EN);
}
///////////M34//////////////////////
if(M34_DIR==FORW)//M1电机的方向
{
Left_Front_motor.run(FORWARD); //Left_Front_motor forward
// Left_Back_motor.run(FORWARD); //Left_Back_motor forward
// Right_Back_motor.run(FORWARD); //Right_Back_motor forward
}
else
{
Left_Front_motor.run(BACKWARD); //Left_Front_motor backward
// Left_Back_motor.run(BACKWARD); //Left_Back_motor backward
// Right_Back_motor.run(BACKWARD); //Right_Back_motor backward
}
if(M34_EN==0)//M1电机的速度
{
Left_Front_motor.run(RELEASE); //Left_Front_motor stop
// Left_Back_motor.run(RELEASE); //Left_Back_motor stop
// Right_Back_motor.run(RELEASE); //Right_Back_motor stop
}
else
{
Left_Front_motor.setSpeed(M12_EN);
// Left_Back_motor.setSpeed(M34_EN);
// Right_Back_motor.setSpeed(M34_EN);
}
}
void setup()
{
int i;
for(i=4;i<=7;i++)//设置控制电机的各端口为输出模式
pinMode(i, OUTPUT);
Serial1.begin(9600);//设置波特率为9600bps
while (!Serial1) ;
servoX.attach(9);
servoY.attach(10);
//Initiate motors
Right_Front_motor.run(RELEASE);
Left_Front_motor.run(RELEASE);
Left_Back_motor.run(RELEASE);
Right_Back_motor.run(RELEASE);
}
///////////////////UART通讯命令字宏定义///////////////////////////////////////////
#define UART_START0 0X55 //通讯数据帧头
#define UART_START1 0XAA //通讯数据帧头
#define UART_END 0X0A //返回数据包结束标志
////////////////////////// 命令字定义/////////////////////////////////////////////////////
// 波特率 57600BPS,无奇偶效验,一位停止位。文中的数字都是8位的十六进制数 /////
///////////////////////////////////2路舵机控制/////////////////////////////////////////////
//本指令可同时控制6路舵机,每路可单独控制位置和速度。
//字头 桢长度 命令字 S1位置 S1速度 S2位置 S2速度 校验和
//55 aa 4 01
//"S1位置,s2位置"为2个舵机的角度值,范围为0~180,90为中位。
//"S1速度,s2速度"为运动的速度值,spd越高,运动速度越快,范围为0~0xff。
//返回值:
//字头 桢长度 命令字 应答标志 校验和
//55 aa 01 01 S SUM
//返回操作标志。设置成功S返回0X01,失败无返回。
//////////////////////////////////////////////////////////////////////////////////////////////
#define RC_MOTO_SET 0X01 // 2路舵机控制
////////////////////////////////2路电机调速控制////////////////////////////////////////////////
//本指令可同时控制2路直流电机速度。(机器人头超前方,人面对机器人后方)
//字头 桢长度 命令字 左电机 右电机 校验和
//55 aa 2 02 S1 S2 SUM
//S1,S2分别代表2个电机的PWM输出占空比。0x80代表电机停止,0x00代表正转最大速度(100%占空比,机器人向前),0xff代表反转最大速度(100%占空比机器人向后)。
//返回值:
//字头 桢长度 命令字 应答标志 校验和
//55 aa 01 02 S SUM
//返回操作标志。设置成功S返回0X01,失败无返回。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MOTO_SET 0X02 //2路电机调速控制
void loop()
{
//定义变量
int dataLen = 0; //数据长度
int start_flag = 0; //数据帧起始标志
int data_index = 0; //数据帧索引
int com_index = 0; //命令索引
int temp_char1 = 0; //接收暂存器1
int temp_char0 = 0; //接收暂存器1
int i,x,y; //变量
int state = 0; //接收数据帧状态 1代表有数据帧,0代表没有接收到数据帧
int SUM; //校验和
int RxData[32]; //数据存储寄存器
int Serial_flag;
int Moto1S,Moto2S; //电机1.2 速度控制暂存
int Moto1D,Moto2D; //电机1.2 方向控制暂存
while(1)
{
temp_char1 = Serial1.read(); //读取串口数据
if(temp_char1!=-1) //有数据接收到
{
Serial_flag=1;
if(start_flag == 0) // 判断 是否有 0X55 0XAA 数据帧头
{
if( temp_char1 == UART_START1)
{
if(temp_char0 == UART_START0)
{
start_flag = 1;
RxData[0]=UART_START0;
RxData[1]=UART_START1;
data_index = 0;
com_index = 0;
}
}
else temp_char0 = temp_char1;
}
else if( com_index < 2)
{
switch(com_index)
{
case 0 : RxData[2] = temp_char1; //数据长度
dataLen = temp_char1;
break;
case 1 : RxData[3] = temp_char1; //命令字
break;
}
com_index++;
}
else if((data_index < dataLen) && (dataLen < dataLenMax)) //接收数据,同时数据不大于最大数据长度
{
RxData[data_index+4] = temp_char1;
data_index ++;
}
else
{
RxData[data_index+4] = temp_char1;
state = 1;
start_flag = 0;
}
}
if(state == 1) //如果有数据帧接收到
{
SUM = 0;
for(i=0; i<dataLen+4; i++) SUM += RxData;//计算校验和
SUM%=256;
if(SUM == RxData[dataLen+4]) //如果校验和正确 解析命令
{
if(RxData[3] == RC_MOTO_SET) //舵机云台控制命令
{
if(RxData[4]>=150) x=150;
else if(RxData [4]<=30) x=30;
else x = RxData[4];
if(RxData[6]>=150) y=150;
else if(RxData[6]<=30) y=30;
else y = RxData[6];
// servoX.write(x);
// servoY.write(y);
state = 0;
}
else if(RxData[3] == MOTO_SET) //电机控制命令
{
///////////////////电机1控制量变换/////////////////////////////
if(RxData[4] == 0X80) Moto1S = 0;
else if(RxData[4] < 0X80) //小于0X80的控制数据 代表正转
{
Moto1D = FORW; //正转
Moto1S = 0xff - RxData[4]*2; //将0X00最大速度 到0X7F 最小速度,转换为0最小到255最大速度的值
}
else //大于0X80的控制数据 代表反转
{
Moto1D = BACK; //反转
Moto1S = (RxData[4] - 0X80)*2; //将0XFF最大速度 到0X81 最小速度,转换为0最小到254最大速度的值
}
///////////////////电机2控制量变换/////////////////////////////
if(RxData[5] == 0X80) Moto2S = 0;
else if(RxData[5] < 0X80) //小于0X80的控制数据 代表正转
{
Moto2D = FORW; //正转
Moto2S = 0xff - RxData[5]*2; //将0X00最大速度 到0X7F 最小速度,转换为0最小到255最大速度的值
}
else //大于0X80的控制数据 代表反转
{
Moto2D = BACK; //反转wwwww
Moto2S = (RxData[5] - 0X80)*2; //将0XFF最大速度 到0X81 最小速度,转换为0最小到254最大速度的值
}
Motor_Control(Moto1D,Moto1S,Moto2D,Moto2S);//电机速度及其方向控制
state = 0;
}
}
}
}
}
停止55AA0202808003 100% 速度前进 55AA0202000003 100% 速度后退 55AA0202FFFF01 100% 速度左转 55AA0202FF0002 100% 速度右转 55AA020200FF02
在“WIFI/蓝牙智能小车操作平台”上通过WIFI模式控制小车时,TT马达只动一下。通过串口助手看过DB120发的指令,都正确。百思不得其解,求大神指教。
|
|