找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2398|回复: 0
打印 上一主题 下一主题
收起左侧

如何做到让Arduino小车检测到障碍物就停止呢?

[复制链接]
跳转到指定楼层
楼主
ID:714862 发表于 2020-4-7 19:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想做一个WiFi遥控小车,现在可以实现WiFi遥控了,但是在前方加了一个红外,做避障,如何做到让小车检测到障碍物就停止呢。


/*前进  按下发出 ONA  松开ONF
  后退:按下发出 ONB  松开ONF
  左转:按下发出 ONC  松开ONF
  右转:按下发出 OND  松开ONF
  停止:按下发出 ONE  松开ONF

  WIFI程序功能是按下对应的按键执行操,松开按键就停止
*/
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 servopin7=7;//设置左右舵机驱动脚到数字口7
int servopin12=12;//设置上下舵机驱动脚到数字口12
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量

const int sensorPin = 5; //定义人体红外传感器的引脚、、、
int sensorValue;      //声明传感器数据变量、、、

int val;               
char buffer[18];                //串口缓冲区的字符数组


void setup()                        //设定串口和引脚模式
{
     Serial.begin(9600);
     Serial.flush();                //清空串口缓存
     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(servopin7,OUTPUT);//设定舵机接口为输出接口
     pinMode(servopin12,OUTPUT);//设定舵机接口为输出接口

     pinMode(sensorPin, INPUT);  //定义红外为输入变量、、、

}
void run()     // 前进
{
  Serial.flush();    //清空串口缓存

  digitalWrite(Right_motor,LOW);  // 右电机前进
  digitalWrite(Right_motor_pwm,HIGH);  // 右电机前进     
  analogWrite(Right_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减


  digitalWrite(Left_motor,LOW);  // 左电机前进
  digitalWrite(Left_motor_pwm,HIGH);  //左电机PWM     
  analogWrite(Left_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减
  //delay(time * 100);   //执行时间,可以调整

}

void brake()         //刹车,停车
{

  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 * 100);//执行时间,可以调整  
}

void left()         //左转(左轮后退,右轮前进)
{
  Serial.flush();    //清空串口缓存
  digitalWrite(Right_motor,LOW);  // 右电机前进
  digitalWrite(Right_motor_pwm,HIGH);  // 右电机前进     
  analogWrite(Right_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减

  digitalWrite(Left_motor,HIGH);  // 左电机后退
  digitalWrite(Left_motor_pwm,HIGH);  //左电机PWM     
  analogWrite(Left_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减
  //delay(time * 100);  //执行时间,可以调整  
}

void right()        //右转(右轮后退,左轮前进)
{
  Serial.flush();    //清空串口缓存
  digitalWrite(Right_motor,HIGH);  // 右电机后退
  digitalWrite(Right_motor_pwm,HIGH);  // 右电机PWM输出1     
  analogWrite(Right_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减


  digitalWrite(Left_motor,LOW);  // 左电机前进
  digitalWrite(Left_motor_pwm,HIGH);  //左电机PWM     
  analogWrite(Left_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减
  //delay(time * 100);        //执行时间,可以调整   
}

void back()          //后退
{
  Serial.flush();    //清空串口缓存
  digitalWrite(Right_motor,HIGH);  // 右电机后退
  digitalWrite(Right_motor_pwm,HIGH);  // 右电机前进     
  analogWrite(Right_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减


  digitalWrite(Left_motor,HIGH);  // 左电机后退
  digitalWrite(Left_motor_pwm,HIGH);  //左电机PWM     
  analogWrite(Left_motor_pwm,110);//PWM比例0~255调速,左右轮差异略增减
  //delay(time * 100);   //执行时间,可以调整   
}

void servopulse(int servopin7,int myangle)/*定义一个脉冲函数,用来模拟方式产生PWM值舵机的范围是0.5MS到2.5MS 1.5MS 占空比是居中周期是20MS*/
{
  pulsewidth=(myangle*11)+450;//将角度转化为500-2480 的脉宽值 这里的myangle就是0-180度  所以180*11+50=2480  11是为了换成90度的时候基本就是1.5MS
  digitalWrite(servopin7,HIGH);//将舵机接口电平置高                                      90*11+50=1490uS  就是1.5ms
  delayMicroseconds(pulsewidth);//延时脉宽值的微秒数  这里调用的是微秒延时函数
  digitalWrite(servopin7,LOW);//将舵机接口电平置低
// delay(20-pulsewidth/1000);//延时周期内剩余时间  这里调用的是ms延时函数
  delay(20-(pulsewidth*0.001));//延时周期内剩余时间  这里调用的是ms延时函数
}
void servopulsesx(int servopin12,int myangle)/*定义一个脉冲函数,用来模拟方式产生PWM值舵机的范围是0.5MS到2.5MS 1.5MS 占空比是居中周期是20MS*/
{
  pulsewidth=(myangle*11)+400;//将角度转化为500-2480 的脉宽值 这里的myangle就是0-180度  所以180*11+50=2480  11是为了换成90度的时候基本就是1.5MS
  digitalWrite(servopin12,HIGH);//将舵机接口电平置高                                      90*11+50=1490uS  就是1.5ms
  delayMicroseconds(pulsewidth);//延时脉宽值的微秒数  这里调用的是微秒延时函数
  digitalWrite(servopin12,LOW);//将舵机接口电平置低
// delay(20-pulsewidth/1000);//延时周期内剩余时间  这里调用的是ms延时函数
  delay(20-(pulsewidth*0.001));//延时周期内剩余时间  这里调用的是ms延时函数
}
void front_detection()// 左右电机前   
{
  //此处循环次数减少,为了增加小车遇到障碍物的反应速度
  for(int i=0;i<=5;i++) //产生PWM个数,等效延时以保证能转到响应角度
  {
    servopulse(servopin7,90);//模拟产生PWM
  }

}
void left_detection()//左右舵机靠左
{
  for(int i=0;i<=1;i++) //产生PWM个数,等效延时以保证能转到响应角度
  {
    servopulse(servopin7,175);//模拟产生PWM
  }

}

void right_detection()//左右电机靠右
{
  for(int i=0;i<=1;i++) //产生PWM个数,等效延时以保证能转到响应角度
  {
    servopulse(servopin7,1);//模拟产生PWM
  }

}
void s_detection()//上下舵机上
{
  for(int i=0;i<=1;i++) //产生PWM个数,等效延时以保证能转到响应角度
  {
    servopulsesx(servopin12,0);//模拟产生PWM
  }
}
void x_detection()//上下舵机下
{
  for(int i=0;i<=1;i++) //产生PWM个数,等效延时以保证能转到响应角度
  {
    servopulsesx(servopin12,175);//模拟产生PWM
  }
}
void loop()
{
    if(Serial.available() > 0)                        //Serial.available()返回串口收到的字节数
    {
       int index = 0;
       delay(100);                                //延时等待串口收完数据,否则刚收到1个字节时就会执行后续程序
       int numChar = Serial.available();        
       if(numChar > 15)                                //确认数据不会溢出,应当小于缓冲大小
       {
         numChar = 15;
        }
       while(numChar--)
      {
          buffer[index++] = Serial.read();        //将串口数据一字一字的存入缓冲
      }
       splitString(buffer);                                //字符串分割
    }
}

void splitString(char *data)
{
       Serial.print("Data entered:");
       Serial.println(data);
       char *parameter;
       parameter = strtok(data, " ,");                //string token,将data按照空格或者,进行分割并截取
       Serial.print("***");
       Serial.println(parameter);
while(parameter != NULL)
{
    setLED(parameter);
    parameter = strtok(NULL, " ,");                //string token,再次分割并截取,直至截取后的字符为空
    Serial.print("---");
    Serial.println(parameter);                        
}
   for(int x = 0; x < 16; x++)                        //清空缓冲
  {
   buffer[x] = '\0';
  }
     Serial.flush();
  }

void setLED(char *data)
{
   sensorValue = digitalRead(sensorPin);     //  用于读取红外传感器数据信息、、、、、、
   if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'A'))  //条件函数  在此加入了红外传感器的条件、、、、
   {
      Serial.println("go forward!");
      run();
  }
  if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'B'))
   {
    Serial.println("go back!");
      back();
}
    if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'C'))
   {
      Serial.println("go left!");
      left();
  }
    if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'D'))
   {
     Serial.println("go right!");
      right();
  }
    if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'E'))
   {
      Serial.println("Stop!");
      brake();
  }
    if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'F'))
   {
    Serial.println("Stop!");
     brake();  
   }
  /* 以下是控制舵机左,上下舵机                            */
  if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'L'))//左
   {
     left_detection();  
   }
  if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'I'))//右
   {
      right_detection();
   }

   if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'J'))//上
   {
      s_detection();
   }
   if((data[0] == 'O') && (data[1] == 'N')&& (data[2] == 'K'))//下
   {
      x_detection();
   }

}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表