|
本帖最后由 jackzeng 于 2012-7-17 15:57 编辑
arduino专区的人气太差了,所以发布到这里,请谅解!
前段论坛有人说要发布arduino的控制协议,我是日盼夜盼盼了一个月也没见有人发布。求人不如求己,仿照liuviking的下位机程序,自己写了个arduino的通信协议。经测试已经能完全和论坛发布的上位机程序兼容,只是我还没解决单片机数据回传到电脑的问题,所以雷达的功能还未能实现,希望有解决方法的朋友能和我分享。本人是英语专业的,只能把程序当成英语来看,没系统学习过单片机知识,所以程序中不可避免有漏洞或者缺点,还请各位指正完善。此外,我还把论坛里的单字符控制上位机程序的视频获取部分换成了mjpeg流的方式,避免snapshot频繁向路由发送请求,如果需要此程序的朋友留下qq号码,我传给你。此外感谢liuviking同学的耐心解释和帮助!
#include <Servo.h>
#define BAUDRATE 9600
//DEFINE MOTO PINS
#define ENA 5 //MOTO_A PMW
#define IN1 3
#define IN2 4
#define ENB 6 //MOTO_B PMW
#define IN3 7
#define IN4 8
//DEFINE SERVO
Servo servo_X;
Servo servo_Y;
//CAR MOVEMENTS
void carGoFwd()
{
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.print("forward");
delay(5);
}
void carGoBwd()
{
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
Serial.print("Backward");
delay(5);
}
void carTurnL()
{
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
Serial.print("TurnL");
delay(5);
}
void carTurnR()
{
digitalWrite(IN1,LOW);
digitalWrite(IN2,HIGH);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.print("TurnR");
delay(5);
}
void carStop()
{
digitalWrite(IN1,LOW);
digitalWrite(IN2,LOW);
digitalWrite(IN3,LOW);
digitalWrite(IN4,LOW);
Serial.print("carStop");
delay(5);
}
//CAR SPEED
void CHNSpeed(int wheelDIR, int wheelSpeed)
{
int pwm = 100+(wheelSpeed+1)*15;
if(wheelDIR == 0X01) //LEFT WHEEL
{
analogWrite(ENA,pwm);
}
else if(wheelDIR == 0X02) //RIGHT WHEEL
{
analogWrite(ENB,pwm);
}
}
//SERVO TURN
void servoSet(int servoNum, int pos)
{
if(pos > 180) pos = 160;
else if(pos < 0) pos = 0;
switch(servoNum)
{
case 0X01:
servo_X.write(pos);
Serial.print("X");
Serial.print(pos);
break;
case 0X02:
servo_Y.write(pos);
Serial.print("Y");
Serial.print(pos);
break;
}
}
void setup()
{
Serial.begin(BAUDRATE);//SERIAL INIT
servo_X.attach(10,800,2300);//DEFINE SERVO PINS
servo_Y.attach(11,1200,2000);
servo_X.writeMicroseconds(1550);//RESET SERVO POS TO 90 DEGREE
servo_Y.writeMicroseconds(1600);
analogWrite(ENA,150);//INIT MOTOSPEED
analogWrite(ENB,150);
pinMode(IN1, OUTPUT);//DEFINE MOTO PINS MODE
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
//UART PROTOCOL///////////////////////
#define UART_FLAG 0XFF
//Moto////////////////////////////////
//PROTO: FLAG DEV DIRECTION EMPTY FLAG
#define MOTO 0X00
#define FORWARD 0X01 //MOTO COMMAND
#define BACKWARD 0X02
#define TURNLEFT 0X03
#define TURNRIGHT 0X04
#define CARSTOP 0X05
//Servo///////////////////////////////
//PROTO: FLAG DEV SERVONUM POS FLAG
#define SERVO 0X01
//Moto Speed//////////////////////////
//PROTO: FLAG DEV MOTOSIDE SPEED FLAG
#define MOTOSPEED 0X02
//////////////////////////////////////
int n = 1;
int flagCount = 0;
int tempData = 0;
int UARTReveived = 0;
int rxData[5];
void loop()
{
if(Serial.available())
{
tempData = Serial.read();
delay(3);
if(tempData == UART_FLAG && flagCount < 2)
{
rxData[0] = tempData;
flagCount++;
}
else
{
rxData[n] = tempData;
n++;
}
if(flagCount == 2)
{
rxData[4] == UART_FLAG;
UARTReveived = 1;
n = 1;
flagCount = 0;
tempData = 0;
Serial.flush();
}
}
if(UARTReveived == 1)
{
if(rxData[1] == MOTO)
{
switch(rxData[2])
{
case FORWARD:
carGoFwd();
break;
case BACKWARD:
carGoBwd();
break;
case TURNLEFT:
carTurnL();
break;
case TURNRIGHT:
carTurnR();
break;
case CARSTOP:
carStop();
break;
}
UARTReveived = 0;
}
else if(rxData[1] == SERVO)
{
servoSet(rxData[2], rxData[3]);
UARTReveived = 0;
}
else if(rxData[1] == MOTOSPEED)
{
CHNSpeed(rxData[2], rxData[3]);
UARTReveived = 0;
}
}
}
解释:
1、我的小车是2舵机的,舵机的角度和arduino舵机库的频宽不同,所以我在setup()里面初始化舵机时做了调整,如果没有这个需要的话请删掉!如果遇到舵机角度范围的问题(比如说转到170°+会卡住),可以参考我的方法解决!我稍后再放出调试舵机的下位机程序。
2、我的小车是用4个6V370减速电机,同一边的两个电机串联,开始时用降压模块降到6V供电,但是发现降压模块的输出功率不够,只好直接12V供电,所以初始化时用pwm把电压调低。如果没这个需要求删除相关语句。调速的时候我把pwm的下限设在100,怕太低了电机停转(这样做有个缺点就是调速不是很明显),如果电机参数不同请更改。
3、调试的时候再每个动作后面加了一个Serial.print,如果不需要调试的话请删掉!
3、arduino的ide不能输入中文,所以注释都是用英文的,看不懂的同学我稍后再改成中文。
|
|