https://www.cnblogs.com/flyingjun/p/8954043.html
一直以来都想通过代码控制马达转动、LED闪烁奈何不具备电子方面的储备,只能工作闲暇之余整了个Arduino的小车来实现梦寐以求的东西。
目标:
1.实现四驱小车电机的转动
2.通过Android app 进行蓝牙通讯
协议:FF FF FF CMD SIZE [Data1,Data2,Data3,Data4]
3.超声波测距
void Distance_test() // 量出前方距离
{
digitalWrite(Trig, LOW); // 给触发脚低电平2μs
delayMicroseconds(2);
digitalWrite(Trig, HIGH); // 给触发脚高电平10μs,这里至少是10μs
delayMicroseconds(10);
digitalWrite(Trig, LOW); // 持续给触发脚低电
float Fdistance = pulseIn(Echo, HIGH); // 读取高电平时间(单位:微秒)
Fdistance = Fdistance / 58; //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
Serial.print("Distance:"); //输出距离(单位:厘米)
Serial.println(Fdistance); //显示距离
Distance = Fdistance;
}
蓝牙+避障(没处理好 蓝牙摇杆控制的,行进间转弯不知道怎么控制)
App端代码:
https://download.csdn.net/download/zdy10326621/12502116
int Left_motor = 8; //左电机(IN3) 输出0 前进 输出1 后退
int Left_motor_pwm = 9; //左电机PWM调速
int Right_motor_pwm = 10; // 右电机PWM调速
int Right_motor = 11; // 右电机后退(IN1) 输出0 前进 输出1 后退
int Echo = A1; // Echo回声脚(P2.0)
int Trig = A0; // Trig 触发脚(P2.1)
int beep = A3; //定义蜂鸣器 A3 接口
float Distance;
const int SensorRight_2 = 5; //左边红外避障传感器()
const int SensorLeft_2 = 6; //右边红外避障传感器()
int SR_2; //右边红外避障传感器状态
int SL_2; //左边红外避障传感器状态
enum
{
NONE, FF1, FF2, FF3, CMD, SIZE, DATA, SUCCESS
} packet;
int MAX_LEN = 30;
byte data[30] = {0};
byte cmds[30] = {0};
int pos = 0;
int len;
//
int linear = 0;//15; //cm/second线速度
int angular = 0;//1; //角速度,ros的angular.z
int val_right = 0; //小车右轮电机的PWM功率值
int val_left = 0; //左轮电机PWM功率值。以左轮为基速度,PID调节右轮的速度
//
int rt = 0;
#define max_linear 120 //最大线速度cm/秒
#define max_linear_pwd 255
String comdata = "";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
//初始化电机驱动IO为输出方式
pinMode(Left_motor, OUTPUT); // PIN 8 8脚无PWM功能
pinMode(Left_motor_pwm, OUTPUT); // PIN 9 (PWM)
pinMode(Right_motor_pwm, OUTPUT); // PIN 10 (PWM)
pinMode(Right_motor, OUTPUT); // PIN 11 (PWM)
pinMode(SensorLeft_2, INPUT); //定义中间避障传感器为输入
pinMode(SensorRight_2, INPUT); //定义中间避障传感器为输入
pinMode(beep, OUTPUT);
//初始化超声波引脚
pinMode(Echo, INPUT); // 定义超声波输入脚
pinMode(Trig, OUTPUT); // 定义超声波输出脚
packet = NONE;
}
void loop() {
robotRun();
}
void robotRun() {
if (Serial.available() > 0) {
len = Serial.readBytes(data, MAX_LEN);
//Serial.write(data,len);
for (int i = 0; i < len; i++) {
rt = parseBuf(data[i]);
if (rt == 1) {
angular = cmds[5] - 100;
linear = cmds[6] - 100;
comdata += angular;
comdata += " linear ";
comdata += linear;
Serial.println(comdata);
comdata = "";
doRemote();
pos = 0;
packet = NONE;
}
}
}
}
void doRemote() {
if (angular == 0 && linear == 0) {
brake(0);
digitalWrite(beep, LOW);
return;
}
if (angular == 0) {
if (linear > 0) { //前进
Serial.println("Go Forward!\n");
Distance_test();
if (Distance < 40) {
brake(0);
digitalWrite(beep, HIGH);
return;
}
run(0);
Distance_test();
if (Distance < 40) {
brake(0);
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
} else if (linear < 0) { //后退
Serial.println("Go Backward!\n");
back(0);
digitalWrite(beep, LOW);
}
} else if (linear == 0) {
if (angular > 0) { //右转
Serial.println("Go Right!\n");
spin_right(0);
digitalWrite(beep, LOW);
} else if (angular < 0) { //左转
Serial.println("Go Left!\n");
spin_left(0);
digitalWrite(beep, LOW);
}
} else {
int v = (int)( abs(angular) * 0.01 * 70);
if (angular > 0 && linear > 0 ) {
Serial.println("turnRight ....");
Distance_test();
if (Distance < 40) {
brake(0);
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
turnRight(v);
Distance_test();
if (Distance < 40) {
brake(0);
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
} else if (angular < 0 && linear > 0) {
Serial.println("turnLeft ....");
Distance_test();
if (Distance < 40) {
brake(0);
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
turnLeft(v);
Distance_test();
if (Distance < 40) {
brake(0);
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
} else if (angular > 0 && linear < 0) {
Serial.println("turnBackRight ....");
turnBackRight(v);
Distance_test();
if (Distance < 40) {
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
} else if (angular < 0 && linear < 0) {
Serial.println("turnBackLeft ....");
turnBackLeft(v);
Distance_test();
if (Distance < 40) {
digitalWrite(beep, HIGH);
return;
} else {
digitalWrite(beep, LOW);
}
}
}
}
void turnBackLeft(int v) {
digitalWrite(Right_motor, LOW); // 右电机后退
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 100 ); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, LOW); // 左电机后退
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 100 - v ); //PWM比例0~255调速,左右轮差异略增减
}
void turnBackRight(int v) {
digitalWrite(Right_motor, LOW); // 右电机后退
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 100 - v ); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, LOW); // 左电机后退
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 100 ); //PWM比例0~255调速,左右轮差异略增减
}
void turnLeft(int v) {
digitalWrite(Right_motor, HIGH); // 右电机后退
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 100 ); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, HIGH); // 左电机后退
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 100 - v ); //PWM比例0~255调速,左右轮差异略增减
}
void turnRight(int v) {
digitalWrite(Right_motor, HIGH); // 右电机后退
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 100 - v ); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, HIGH); // 左电机后退
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 100 ); //PWM比例0~255调速,左右轮差异略增减
}
int parseBuf(byte a) {
int result = 0;
switch (packet) {
case NONE:
if (a == 0xFF) {
cmds[pos++] = a;
packet = FF1;
} else {
pos = 0;
packet = NONE;
}
break;
case FF1:
if (a == 0xFF) {
cmds[pos++] = a;
packet = FF2;
} else {
pos = 0;
packet = NONE;
}
break;
case FF2:
if (a == 0xFF) {
cmds[pos++] = a;
packet = FF3;
} else {
pos = 0;
packet = NONE;
}
break;
case FF3:
cmds[pos++] = a;
packet = CMD;
break;
case CMD:
cmds[pos++] = a;
packet = SIZE;
break;
case SIZE:
cmds[pos++] = a;
if ((pos - 4 - 1) == cmds[4]) {
packet = DATA;
result = 1;
}
break;
}
return result;
}
void showTest() {
int i;
delay(2000); //延时2s后启动
run(10);
back(10);//全速前进急停后退
brake(5);
for (i = 0; i < 5; i++)
{
run(10);//小车间断性前进5步
brake(1);
}
for (i = 0; i < 5; i++)
{
back(10);//小车间断性后退5步
brake(1);
}
for (i = 0; i < 5; i++)
{
left(10);//大弯套小弯连续左旋转
spin_left(5);
}
for (i = 0; i < 5; i++)
{
right(10);//大弯套小弯连续右旋转
spin_right(5);
}
for (i = 0; i < 10; i++)
{
right(1);//间断性原地右转弯
brake(1);
}
for (i = 0; i < 10; i++)
{
left(1);//间断性原地左转弯
brake(1);
}
for (i = 0; i < 10; i++)
{
left(3);//走S形前进
right(3);
}
for (i = 0; i < 10; i++)
{
spin_left(3);//间断性原地左打转
brake(3);
}
for (i = 0; i < 10; i++)
{
spin_right(3);//间断性原地右打转
brake(3);
}
}
void back(int time) // 前进
{
digitalWrite(Right_motor, LOW); // 右电机前进
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, LOW); // 左电机前进
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
// delay(time * 120); //执行时间,可以调整
}
void brake(int time) //刹车,停车
{
digitalWrite(Right_motor_pwm, LOW); // 右电机PWM 调速输出0
analogWrite(Right_motor_pwm, 0); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor_pwm, LOW); //左电机PWM 调速输出0
analogWrite(Left_motor_pwm, 0); //PWM比例0~255调速,左右轮差异略增减
delay(time * 120);//执行时间,可以调整
}
void left(int time) //左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor, HIGH); // 右电机前进
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, HIGH); // 左电机前进
digitalWrite(Left_motor_pwm, LOW); //左电机PWM
analogWrite(Left_motor_pwm, 0); //PWM比例0~255调速,左右轮差异略增减
delay(time * 120); //执行时间,可以调整
}
void spin_right(int time) //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor, LOW); // 右电机前进
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, HIGH); // 左电机后退
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
delay(time * 120); //执行时间,可以调整
}
void right(int time) //右转(右轮不动,左轮前进)
{
digitalWrite(Right_motor, HIGH); // 右电机不转
digitalWrite(Right_motor_pwm, LOW); // 右电机PWM输出0
analogWrite(Right_motor_pwm, 0); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, HIGH); // 左电机前进
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
delay(time * 120); //执行时间,可以调整
}
void spin_left(int time) //右转(右轮后退,左轮前进)
{
digitalWrite(Right_motor, HIGH); // 右电机后退
digitalWrite(Right_motor_pwm, HIGH); // 右电机PWM输出1
analogWrite(Right_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, LOW); // 左电机前进
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
delay(time * 120); //执行时间,可以调整
}
void run(int time) //后退
{
digitalWrite(Right_motor, HIGH); // 右电机后退
digitalWrite(Right_motor_pwm, HIGH); // 右电机前进
analogWrite(Right_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
digitalWrite(Left_motor, HIGH); // 左电机后退
digitalWrite(Left_motor_pwm, HIGH); //左电机PWM
analogWrite(Left_motor_pwm, 120); //PWM比例0~255调速,左右轮差异略增减
// delay(time * 120); //执行时间,可以调整
}
void Distance_test() // 量出前方距离
{
digitalWrite(Trig, LOW); // 给触发脚低电平2μs
delayMicroseconds(2);
digitalWrite(Trig, HIGH); // 给触发脚高电平10μs,这里至少是10μs
delayMicroseconds(10);
digitalWrite(Trig, LOW); // 持续给触发脚低电
float Fdistance = pulseIn(Echo, HIGH); // 读取高电平时间(单位:微秒)
Fdistance = Fdistance / 58; //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
Serial.print("Distance:"); //输出距离(单位:厘米)
Serial.println(Fdistance); //显示距离
Distance = Fdistance;
}