小小菜鸡你我他 发表于 2018-10-20 14:01:57

Arduino智能小车功能间如何进行蓝牙遥控选择转换

做了一辆Arduino的智能车,其功能目前是:四路循迹行驶,同时在行驶过程中遇到障碍物进行规避(超声波避障模块),在把循迹用黑胶布遮住使它四个传感器均检测不到时候可以进行蓝牙遥控,现在我想做成使用蓝牙来远程选择自动还是手动(自动循迹加超声波避障/蓝牙纯手动遥控),附上代码如下,求大神帮我解决下。 int Left_motor_back=6;   //左电机后退(IN1)
int Left_motor_go=9;   //左电机前进(IN2)
int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)

const int SensorRight_1 = 7;//右外侧
const int SensorRight = 5;   //右循迹红外传感器(P3.2 OUT1)
const int SensorLeft = 4;//左循迹红外传感器(P3.3 OUT2)
const int SensorLeft_1 = 2;//左外侧
                                 //超声波测量数值定义
int Front_Distance = 0;
int Left_Distance = 0;
int Right_Distance = 0;

int SL; //左循迹红外传感器状态
int SL_1;
int SR;    //右循迹红外传感器状态
int SR_1;

int Echo = A0;// Echo回声脚(P2.0)
int Trig = A1 ;//Trig 触发脚(P2.1)
int Distance = 0;

int servopin= 12;//设置舵机驱动脚到数字口2
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量
int val;

const String GO = "1";//蓝牙遥控器发送信息代码定义
const String BACK = "2";
const String LEFT = "3";
const String RIGHT = "4";
const String STOP = "0";
const String SMALLLEFT = "5";
const String SMALLRIGHT = "6";
const String SLEFT = "7";


void setup()
{
Serial.begin(9600);    // 初始化串口
//初始化电机驱动IO为输出方式
   pinMode(Left_motor_go,OUTPUT); // PIN 6 (PWM)//初始化电机驱动IO为输出方式
pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM)
pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
pinMode(SensorRight_1, INPUT); //定义右红外传感器为输入
pinMode(SensorLeft_1, INPUT); //定义左红外传感器为输入
//初始化超声波引脚
pinMode(Echo, INPUT);    // 定义超声波输入脚
pinMode(Trig, OUTPUT);   // 定义超声波输出脚
pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
}

//=======================智能小车的基本动作=========================
   // 前进
void run(int time)
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);   
analogWrite(Right_motor_go,60);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH);// 左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,60);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Left_motor_back,0);
delay(time * 10);   //执行时间,可以调整
}

//void brake(int time)//刹车,停车
void brake(int time)
{
digitalWrite(Right_motor_go,LOW);
digitalWrite(Right_motor_back,LOW);
digitalWrite(Left_motor_go,LOW);
digitalWrite(Left_motor_back,LOW);
delay(time * 10);//执行时间,可以调整
}
//void brake(int time)//长时间刹车,停车
void brake_1()
{
digitalWrite(Right_motor_go,LOW);
digitalWrite(Right_motor_back,LOW);
digitalWrite(Left_motor_go,LOW);
digitalWrite(Left_motor_back,LOW);
//delay(time * 100);//执行时间,可以调整
}

//void left(int time)         //左转(左轮不动,右轮前进)
void left(int time)
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,110);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);   //左轮后退
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 10);//执行时间,可以调整
}

//void spin_left(int time)
void sleft(int time)          //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,110);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);   //左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,110);//PWM比例0~255调速
delay(time * 10);//执行时间,可以调整
}

//void right(int time)      //右转(右轮不动,左轮前进)
void right(int time)
{
digitalWrite(Right_motor_go,LOW);   //右电机后退
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,110);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 10);//执行时间,可以调整
}

//void spin_right(int time)
void sright(int time)      //右转(右轮后退,左轮前进)
{
digitalWrite(Right_motor_go,LOW);   //右电机后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,110);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,110);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
// delay(time * 10);//执行时间,可以调整   
}

//void back(int time)          //后退
void back(int time)
{
digitalWrite(Right_motor_go,LOW);//右轮后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,100);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,100);//PWM比例0~255调速
delay(time * 10);   //执行时间,可以调整
}
//==========================================================


float 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;
return Fdistance;
}

void servopulse(int servopin,int myangle)/*定义一个脉冲函数,用来模拟方式产生PWM值*/
{
pulsewidth=(myangle*11)+500;//将角度转化为500-2480 的脉宽值
digitalWrite(servopin,HIGH);//将舵机接口电平置高
delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
digitalWrite(servopin,LOW);//将舵机接口电平置低
delay(20-pulsewidth/1000);//延时周期内剩余时间
}

void front_detection()
{
//此处循环次数减少,为了增加小车遇到障碍物的反应速度
for(int i=0;i<=5;i++) //产生PWM个数,等效延时以保证能转到响应角度
{
    servopulse(servopin,95);//模拟产生PWM
}
Front_Distance = Distance_test();
//Serial.print("Front_Distance:");      //输出距离(单位:厘米)
// Serial.println(Front_Distance);         //显示距离
//Distance_display(Front_Distance);
}

void left_detection()
{
for(int i=0;i<=15;i++) //产生PWM个数,等效延时以保证能转到响应角度
{
    servopulse(servopin,175);//模拟产生PWM
}
Left_Distance = Distance_test();
//Serial.print("Left_Distance:");      //输出距离(单位:厘米)
//Serial.println(Left_Distance);         //显示距离
}
void right_detection()
{
for(int i=0;i<=15;i++) //产生PWM个数,等效延时以保证能转到响应角度
{
    servopulse(servopin,5);//模拟产生PWM
}
Right_Distance = Distance_test();
//Serial.print("Right_Distance:");      //输出距离(单位:厘米)
//Serial.println(Right_Distance);         //显示距离
}
String readTtl() {
String comdata = "";
while (Serial.available())
{
    comdata += char(Serial.read());
    delay(2);
}
return comdata;
}

void loop()
{
while(1)
{
    {
//有信号为LOW没有信号为HIGH
SR = digitalRead(SensorRight);//有信号表明在白色区域,车子底板上L3亮;没信号表明压在黑线上,车子底板上L3灭
SL = digitalRead(SensorLeft);//有信号表明在白色区域,车子底板上L2亮;没信号表明压在黑线上,车子底板上L2灭
SL_1 = digitalRead(SensorLeft_1);
SR_1 = digitalRead(SensorRight_1);
if (SL == LOW&&SR==LOW&&SL_1==LOW && SR_1== LOW)
    run(10);   //调用前进函数
    else if (SL_1 == LOW && SL == LOW && SR==HIGH && SR_1== LOW ) // 右循迹红外传感器,检测到信号,车子向左偏离轨道,向右转
    left(30);
    else if(SL_1==LOW && SL== HIGH&&SR == LOW &&SR_1==LOW)
    right(30);
    else if(SL_1==HIGH && SL == LOW && SR==LOW && SR_1==LOW)
      sright(30);
    else if(SL_1==LOW && SL == LOW && SR==LOW && SR_1==HIGH)// 左循迹红外传感器,检测到信号,车子向右偏离轨道,向左转
   sleft(30);
    else if(SL_1 == LOW && SL == LOW && SR==HIGH && SR_1== HIGH)
    left(30);
    else if(SL_1==HIGH && SL== HIGH&&SR == LOW &&SR_1==LOW)
    right(30);
   //else//停止
   // brake_1();
}
front_detection();//测量前方距离
    if(Front_Distance < 20)//数值为碰到障碍物的距离,可以按实际情况设置
      {
      brake(50);
      back(60);
         brake(100);
      left_detection();//测量左边距障碍物距离
       right_detection();//测量右边距障碍物距离
      brake(10);
       if((Left_Distance < 40 ) &&( Right_Distance < 40 ))//当左右两侧均有障碍物靠得比较近
      sleft(180);//旋转掉头根据具体情况调整执行时间
       else if(Left_Distance > Right_Distance)//左边比右边空旷
      {
      left(60);//左转
         brake(10);//刹车,稳定方向
      }
      else if(Left_Distance < Right_Distance)//右边比左边空旷
      {right(60);//右转
      brake(10);//刹车,再次判定
      }
      else
      run(1);//无障碍物,直行
}

   // 蓝牙主代码
      String s = readTtl();
if (s == GO ) run(70);//如果按GO键,小车前进,直到按STOP键停止
else if (s == LEFT ) left(65);
else if (s == STOP ) brake_1();
else if (s == RIGHT ) right(70);
else if (s == BACK ) back(65);
else if (s == SMALLLEFT ) left(20);
else if (s == SMALLRIGHT) right(20);
else if (s == SLEFT) sleft(90);
}
}

catnull 发表于 2018-10-20 15:07:11

设置一个标志变量,然后按照工作流程进行分支,对于不同状态,进行不同的处理。
页: [1]
查看完整版本: Arduino智能小车功能间如何进行蓝牙遥控选择转换