超声波避障_超声波避障小车 - CSDN
精华内容
参与话题
  • Arduino智能小车——超声波避障

    万次阅读 多人点赞 2020-05-19 10:51:23
    Arduino智能小车——超声波避障  经过这几篇的测试大家应该对小车有一定的认识了,在实际的操作过程中经常会由于操作不当各种碰壁吧?那这次我们将给小车装上一只“眼睛”,让小车看到障碍,躲避障碍。准备材料...

    Arduino智能小车——超声波避障

      经过前几篇的测试大家应该对小车有一定的认识了,在实际的操作过程中经常会由于操作不当各种碰壁吧?那这次我们将给小车装上一只“眼睛”,让小车看到障碍,躲避障碍。

    准备材料

    超声波模块HC-SR04

    SouthEast

      在这里简单说下超声波测距的原理,相信大家也都知道。超声波发射装置发出超声波,它的根据是接收器接到超声波时的时间差,与雷达测距原理相似。 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。

    1. 采用Trig引脚触发,给至少10us的高电平脉冲信号
    2. 模块自动发送8个40kHz的方波,自动检测是否有信号返回
    3. 有信号返回,通过Echo引脚输出一个高电平脉冲,高电平脉冲持续的时间就是超声波从发射到反射返回的时间。距离=(高电平脉冲时间*340)/2。(声音在空气中传播速度为340m/s)
    主要技术参数
    工作电压 DC5V
    静态电流 <2mA
    输出电平 0-5V
    感应角度 ≤15度
    探测距离 2cm-450cm
    最高精度 0.3cm

    ###舵机
      在这里推荐9G舵机SG90,或者其他类似的舵机,这种舵机体积比较小,扭矩虽然不是大, 但是足够带动简易云台,很方便在小车上使用,大家购买时注意舵机的转动角度,有55度的,180度的等等,大家可以根据需要购买。

    SouthEast

    舵机固定架

      舵机固定架的购买一定要配合舵机,所以大家购买的时候注意尺寸哦!!~

    舵机安装

      舵机在安装之前大家一定要记得校准,为什么要校准那,这个跟舵机的工作原理有关。控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
      舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:

    SouthEast
    高电平时间 对应位置
    0.5ms 0度
    1.0ms 45度
    1.5ms 90度
    2.0ms 135度
    2.5ms 180度

      也就是说当对舵机输入相同控制信号时,舵机会运动到固定位置,他的动作不是做圆周运动,而是在运动范围内,每一个位置对应一个控制信号。

      因此我们需要在将舵机安装在固定架上之前,需要先将舵机初始化好,舵机一般为三根线:棕色——GND,红色——VCC,橙色——控制信号。因此我们将棕色线接到GND,红色线接到“+5V”引脚,橙色线接到“10”引脚,初始化程序如下:

    #include <Servo.h>  //加入含有舵机控制库的头文件
    
    #define PIN_SERVO 10  //舵机信号控制引脚
    Servo myservo;  
      
    void setup()  
    {  
      myservo.attach(PIN_SERVO);  //舵机初始化
    }  
      
    void loop()  
    {  
      myservo.write(90);  //PWM输出
    } 
    

      在舵机初始化好之后将其安装在固定架上,然后装配在小车上,此时保证超声波模块超前。

    SouthEast

    超声波接线

      估计不少朋友早已经发现板子上的“+5V”和“GND”引脚已经不够用了,这个时候你们可以向我这样焊一个扩展板出来,上面固定两排排针,一排用来扩展“+5V”,一边用来扩展“GND”引脚。

    SouthEast

      超声波模块有四个引脚,“VCC”接到Arduino UNO开发板的“+5V”引脚,“GND”接到开发板“GND”引脚,“Trig”引脚接到开发板“8”引脚,“Echo”引脚接到开发板“7”引脚

    SouthEast

      线太乱了,真的没办法整理,我自己都没眼看。

    代码测试

    #include <Servo.h>
    
    #define STOP      0
    #define FORWARD   1
    #define BACKWARD  2
    #define TURNLEFT  3
    #define TURNRIGHT 4
    
    int leftMotor1 = 16;
    int leftMotor2 = 17;
    int rightMotor1 = 18;
    int rightMotor2 = 19;
    
    int leftPWM = 5;
    int rightPWM = 6;
    
    Servo myServo;  //舵机
    
    int inputPin=7;   // 定义超声波信号接收接口
    int outputPin=8;  // 定义超声波信号发出接口
    
    void setup() {
      // put your setup code here, to run once:
      //串口初始化
      Serial.begin(9600); 
      //舵机引脚初始化
      myServo.attach(9);
      //测速引脚初始化
      pinMode(leftMotor1, OUTPUT);
      pinMode(leftMotor2, OUTPUT);
      pinMode(rightMotor1, OUTPUT);
      pinMode(rightMotor2, OUTPUT);
      pinMode(leftPWM, OUTPUT);
      pinMode(rightPWM, OUTPUT);
      //超声波控制引脚初始化
      pinMode(inputPin, INPUT);
      pinMode(outputPin, OUTPUT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      avoidance();
    }
    void motorRun(int cmd,int value)
    {
      analogWrite(leftPWM, value);  //设置PWM输出,即设置速度
      analogWrite(rightPWM, value);
      switch(cmd){
        case FORWARD:
          Serial.println("FORWARD"); //输出状态
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         case BACKWARD:
          Serial.println("BACKWARD"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNLEFT:
          Serial.println("TURN  LEFT"); //输出状态
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNRIGHT:
          Serial.println("TURN  RIGHT"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         default:
          Serial.println("STOP"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, LOW);
      }
    }
    void avoidance()
    {
      int pos;
      int dis[3];//距离
      motorRun(FORWARD,200);
      myServo.write(90);
      dis[1]=getDistance(); //中间
      
      if(dis[1]<30)
      {
        motorRun(STOP,0);
        for (pos = 90; pos <= 150; pos += 1) 
        {
          myServo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);                       // waits 15ms for the servo to reach the position
        }
        dis[2]=getDistance(); //左边
        for (pos = 150; pos >= 30; pos -= 1) 
        {
          myServo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);                       // waits 15ms for the servo to reach the position
          if(pos==90)
            dis[1]=getDistance(); //中间
        }
        dis[0]=getDistance();  //右边
        for (pos = 30; pos <= 90; pos += 1) 
        {
          myServo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);                       // waits 15ms for the servo to reach the position
        }
        if(dis[0]<dis[2]) //右边距离障碍的距离比左边近
        {
          //左转
          motorRun(TURNLEFT,250);
          delay(500);
        }
        else  //右边距离障碍的距离比左边远
        {
          //右转
          motorRun(TURNRIGHT,250);
          delay(500);
        } 
      }
    }
    int getDistance()
    {
      digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2μs
      delayMicroseconds(2);
      digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10μs,这里是至少10μs
      delayMicroseconds(10);
      digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平
      int distance = pulseIn(inputPin, HIGH); // 读出脉冲时间
      distance= distance/58; // 将脉冲时间转化为距离(单位:厘米)
      Serial.println(distance); //输出距离值
     
      if (distance >=50)
      {
        //如果距离小于50厘米返回数据
        return 50;
      }//如果距离小于50厘米小灯熄灭
      else
        return distance;
    }
    

    代码详解

    “Trig”引脚控制超声波发出声波,对应int outputPin=8;
    “Echo”引脚反应接收到返回声波,对应int inputPin=7;

    int inputPin=7;   // 定义超声波信号接收接口
    int outputPin=8;  // 定义超声波信号发出接口
    

    int getDistance()函数解析

    超声波发出引脚“Trig”为高时对外发出超声波,为保证发出10μs声波,因此在发送之前需要将该引脚拉低,并给他一定反应时间。

    digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2μs
    delayMicroseconds(2);
    

    之后发送10μs超声波

    digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10μs,这里是至少10μs
    

    声波发送之后禁止其继续发送,同时开始检测是否反射回来的声波

    digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平
      int distance = pulseIn(inputPin, HIGH); // 读出脉冲时间
    

    pulseIn()单位为微秒,声速344m/s,所以距离cm=344100/1000000pulseIn()/2约等于pulseIn()/58.0distance= distance/58; // 将脉冲时间转化为距离(单位:厘米)
    超声波模块工作受物体表面反射程度影响,并且在传播过程中信号强度容易衰减,因此该模块适用的检测距离有限,一般在50cm以内相对正确,而且我们在避障时不需要检测太远的距离,因此超过50cm以上的都按50cm计算

    if (distance >=50)
      {
        //如果距离小于50厘米返回数据
        return 50;
      }//如果距离小于50厘米小灯熄灭
      else
        return distance;
    

    void avoidance()函数解析

    小车前进过程中只检测前方距离障碍的距离,并且控制舵机,保持超声波模块位于正前方。

    motorRun(FORWARD,200);
      myServo.write(90);
      dis[1]=getDistance(); //中间
    

    当检测到小车前方距离障碍距离小于30cm时停车,检测两边距离。

    motorRun(STOP,0);
    

    控制舵机每次运动一个周期后都返回正前方位置。由于舵机运动需要一定的时间,因此在每转过一个角度的时候都延时delay(15),供其运动。

    for (pos = 90; pos <= 150; pos += 1) 
    {
          myServo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);                       // waits 15ms for the servo to reach the position
    }
    

    当运动到最左边时检测小车左边距离障碍的距离

    dis[2]=getDistance(); //左边
    

    向右边运动,检测右边距离

    for (pos = 150; pos >= 30; pos -= 1) 
    {
      myServo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
      if(pos==90)
        dis[1]=getDistance(); //中间
    }
    dis[0]=getDistance();  //右边
    

    将前边、左边、右边距离障碍的距离都检测结束之后,舵机回到最初位置。

    for (pos = 30; pos <= 90; pos += 1) 
    {
      myServo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
    }
    

    注意事项

    1.舵机使用时要防止其堵转,因为点击堵转时电流会增大,很容易烧坏舵机。
    2.舵机的红色电源线接入电压一般要大于等于其工作电压,供电不足会导致舵机不停自传。
    3.Arduino 《Servo.h》库里提供的write()函数输出的PWM即为舵机专用的20ms为周期的PWM波,如果使用其他开发板或者函数的话,请务必保证输出方波周期为20ms,否则舵机不会受控制

    总结

      这一篇讲解了舵机和超声波模块的使用方法,舵机在大家以后的开发生涯中应该会经常用到,因此舵机的使用规则(控制周期为20ms)请大家一定要记清楚,在舵机不受控制的时候建议大家可以购买一个舵机测试仪来测试舵机。

    欢迎各位有兴趣的朋友加入Q群1:789127261 点评、交流

    展开全文
  • 基于stm32f103vc的智能小车——超声波避障部分

    千次阅读 多人点赞 2019-07-10 11:47:35
    智能小车的超声波避障实现过程 在硬件综合训练这门课程中,我们以小组的形式完成了基于stm32f103vc的智能小车的制作,实现的主要功能有:遥控、避障、语音控制、人脸识别以及舵机控制摄像头旋转。其中我主要负责的...

    智能小车的超声波避障实现过程

    在硬件综合训练这门课程中,我们以小组的形式完成了基于stm32f103vc的智能小车的制作,实现的主要功能有:遥控、避障、语音控制、人脸识别以及舵机控制摄像头旋转。其中我主要负责的是stm32板的开发,以下是超声波避障的实现过程。

    1. 超声波模块的介绍
      我们所用的是HC-SR04超声波测距模块,它可以测量 3cm – 4m 的距离,精确度可以达到 3mm。
      HC-SR04 实物图
    2. 超声波模块的工作原理
      (1)采用IO口TRIG触发测距,给至少10us的高电平信号;
      (2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
      (3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速/2;
      (4)本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离。如此不断的周期测,即可以达到你移动测量的值。
    3. 超声波模块电路图
      在这里插入图片描述
    4. 超声波模块时序图
      在这里插入图片描述
    5. 超声波模块实现代码
      时钟与GPIO初始化:
    void iniTim()
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
     	TIM_TimeBaseInitStructer.TIM_Period=9999;// 定时周期 .1s 100ms overflow
     	TIM_TimeBaseInitStructer.TIM_Prescaler=71;  // 72 000 000 1mhz 1us
     	TIM_TimeBaseInitStructer.TIM_ClockDivision=0; 
     	TIM_TimeBaseInitStructer.TIM_CounterMode=TIM_CounterMode_Up;
     	TIM_TimeBaseInitStructer.TIM_RepetitionCounter = 0;
     	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructer);
    
    	TIM_Cmd(TIM2,ENABLE);
     	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
     
     	NVIC_InitTypeDef NVIC_InitStructure;
     	NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
     	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
     	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
     	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    	 NVIC_Init(&NVIC_InitStructure);
     
     	TIM_Cmd(TIM2,DISABLE);// 关闭定时器使能
    
    	GPIO_InitTypeDef GPIO_InitStructure;
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
     
    	 /*TRIG 信号 */
     	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
     	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
     	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
     	GPIO_Init(GPIOB, &GPIO_InitStructure);
    	 /*ECOH 信号 */
    	 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
     	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
     	GPIO_Init(GPIOB, &GPIO_InitStructure);
     
     	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
     	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
     	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
     	GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
     	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
     	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
     	GPIO_Init(GPIOB, &GPIO_InitStructure);
     
     	GPIO_ResetBits(GPIOB,GPIO_Pin_9);//关闭距离过远led
    }

    测距函数:

    double get_length(void)
    {
     	GPIO_SetBits(GPIOB,GPIO_Pin_8);
     	 Delay_us(11);
      	GPIO_ResetBits(GPIOB,GPIO_Pin_8);
     	 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) == RESET);
       	TIM2->CNT = 0;//清零计时器
      	TIM_Cmd(TIM2,ENABLE);// 回响信号到来,开启定时器计数
      	while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==SET);
      	TIM_Cmd(TIM2,DISABLE);// 关闭定时器
      
     	if(!toofar) //没有完成一次计数周期,即距离不是很远 
      	{
       		t=TIM_GetCounter(TIM2);// 获取 TIM2 寄存器中的计数值
       		time = (double)t/(double)1000000; //往返时间,单位s 
       		length =  340*time/2; //单程长度,单位m 
       		TIM2->CNT=0; // 将 TIM2 计数寄存器的计数值清零
      	}
      	else
     	{
       		toofar = 0; 
       		length =99; //足够远,不用考虑 
       		TIM2->CNT=0; // 将 TIM2 计数寄存器的计数值清零
      	}
     	return length;
    }

    设置中断:

    void TIM2_IRQHandler(void) // 中断,当距离足够远时,设置toofar = 1,不必再计算 
    {
     	if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
       	{
       		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);// 清除中断标志
       		toofar = 1;
       		GPIO_ResetBits(GPIOB,GPIO_Pin_9);
       	}
    }

    主函数:

    int main(void) 
    {
     	SysTick_Init();
     	iniTim();
     	while(1) 
     	{
     		double len = 0;
      		len = get_length();
      		if ( len < 0.5 ) //如果距离够近
      		{
      			GPIO_SetBits(GPIOB,GPIO_Pin_7);//点亮距离过近led
       			GPIO_ResetBits(GPIOB,GPIO_Pin_9);//复位距离过远led
      		}
      		else 
       		{
       			if(toofar)//距离长到tim溢出,> 17m
       			{
        				GPIO_SetBits(GPIOB,GPIO_Pin_9);//点亮距离过远led
        				GPIO_ResetBits(GPIOB,GPIO_Pin_7);//复位距离过近led
       			}
       			else
       			{
         				GPIO_ResetBits(GPIOB,GPIO_Pin_7);//复位距离过近led
        				GPIO_ResetBits(GPIOB,GPIO_Pin_7);//复位距离过近led
        			}
      		}  
     	}
    }

    注:我添加了两个led灯来判断超声波测距功能的实现,其中
    PB7引脚上连接的是距离过近led,如果近距离内出现障碍,它会亮起;
    PB9引脚上连接的是距离过远led,如果在很远的距离范围里都没有障碍,它会亮起。

    展开全文
  • 超声波传感器概述 超声波传感器型号繁多,价格从几元钱到几百元不等,主要用于检测距离,同时根据声速计算出物体的距离.但超声波传感器有四个缺点:1.声音速度易受温度和风向等环境因素干扰,在室内应用可忽略.2.超声波...

    引言.超声波传感器概述

         超声波传感器型号繁多,价格从几元钱到几百元不等,主要用于检测距离,同时根据声速计算出物体的距离.但超声波传感器有四个缺点:

    1.声音速度易受温度和风向等环境因素干扰,在室内应用可忽略.

    2.超声波有可能被吸引材料吸收,如毛毯,毛衣等.

    3.传感器可能受外部噪音(干扰源与传感器有同样的频率)或相同传感器干扰.

    4.超声波传感器检测与自身斜角较大的物体可能出现检测不到的情况.

    .HC-SR04超声波传感器电子结构


    二.HC-SR04工作原理

       采用IO触发测距,触发信号输入端(Trig)输入一个10微秒以上的高电平信号,超声发送口收到信号自动发送840Hz方波,同时启动定时器,待传感器接收到回波则停止计时并输出回响信号,回响信号脉冲宽度与所测距离正比.根据时间间隔可以计算距离,公式:距离=(高电平时间*声速)/2.

       使用I2C协议,一个CPU可控制多个传感器.

    三.HC-SR04出厂标准参数

     

    四.HC-SR04际测量结果

      测距时,被测物体面积不宜少于0.5平方米且尽量要求平整,否则影响测量结果.

    1.前方有平滑物体(如图书封面,镜面,墙体)与传感器夹角大于45(非垂直反射)时误差明显,且在5-40cm范围内读数不稳定.其中可能会出现的误差有三角误差、镜面反射、多次反射等。

    2.前方有毛衣,毛毯等吸音材料时读数不稳定.

    3.声波测量角度为30,精度平均正负4cm.

    五.其他研究应用方法

        1.一体式超声波传感器与步进电机组成的探测系统:利用电机带动一个超声波传感器旋转测距,并与步进电机相互协调.

        2.多超声波传感器共同作用,互相补偿.多见超声波和红外协同 

        3.物理感应:超声波传感器和弹簧式的保护层共同工作,如保护层碰到障碍物,弹簧压缩,机器人接收到碰撞信息,调整位置.

    六.在机器人上的应用设计

    由于用超声波测量距离并不是一个点测量。超声波传感器具有一定的扩散特性,发射的超声能量主要集中在主波瓣上,沿着主波轴两侧呈波浪型衰减,左右约30°的扩散角。事实上,距离计算是基于超声波成功、垂直的反射名义下进行的。但对于移动机器人很难保证其自身运动姿态的稳定性,采用超声波传感器固定在移动机器人车身的探测方式,当移动机器人偏离平行墙面时,探测系统往往很难得到实际的距离。另外,超声波这种发散特性在应用于测量障碍物的时候,只能提供目标障碍物的距离信息,而不能提供目标的方向和边界信息。因此需要用多个超声传感器以及其他传感器共同工作.

    应用6个超声波传感器,两边对称放置,每20度角一个,单侧角度为40,60,80度.探测盲区在15cm以内,整体探测角度150度以上,可以应用. 

    建议测量周期60ms以上,防止发射信号受回响信号影响.

    展开全文
  • 51单片机的超声波智障(避障)小车

    万次阅读 多人点赞 2020-01-20 21:24:51
    51单片机制作的超声波智障(避障)小车 最近在学习51单片机,暑假闲着无聊,便从网上买了个51单片机和一些传感器模块,不知怎么的突然想起小时候对小车的痴迷,于是便准备利用暑假时间做一超声波避障小车,就算是对...

    51单片机制作的超声波智障(避障)小车

    最近在学习51单片机,暑假闲着无聊,便从网上买了个51单片机和一些传感器模块,准备利用暑假时间做一超声波避障小车。
    小车做的很简陋,因为是初学51单片机,所以代码可能写的不是很好。
    小车需要用到的材料:

    • 51单片机小板
    • HC-SR04超声波模块
    • SG90舵机
    • L298n电机驱动模块
    • 两个电机

    keil中的代码

    #include<reg52.h>
    #include<intrins.h>
    #define uchar unsigned char
    #define uint unsigned int
    #define barrierDis 15      //距离障碍物的距离 
    uint sum;
    float L;
    sbit LED = P0^0;
    sbit Trig = P1^1;	   //超声波模块的TRIG
    sbit Echo = P1^2;	   //超声波模块的ECHO
    sbit motorDriver_1 =P2^1;  //控制第一个电机,从单片机出来后接L298n模块的IN1
    sbit motorDriver_2 =P2^2;  //控制第一个电机,从单片机出来后接L298n模块的IN2
    sbit motorDriver_3 =P2^3;  //控制第二个电机,从单片机出来后接L298n模块的IN3
    sbit motorDriver_4 =P2^4;  //控制第二个电机,从单片机出来后接L298n模块的IN4
    sbit servorControl =P1^0;  //舵机的控制引脚
    uchar flag=0;
    uchar control=5;
    uchar servorTime=0;
    uchar lFlag=0;//左方向是否有障碍的标志
    uchar rFlag=0;//右方向是否有障碍的标志
    void delay(uchar time){	 //延迟函数
    	uchar i;
    	for(;time>0;time--){
    		for(i=0;i<255;i++);
    	}
    }
    void stop(){	 //小车停止
    	motorDriver_1=0;
    	motorDriver_2=0;
    	motorDriver_3=0;
    	motorDriver_4=0;
    }
    void turnLeft(){		//小车向左转
    	motorDriver_1=1;
    	motorDriver_2=0;
    	motorDriver_3=0;
    	motorDriver_4=0;
    }						 //小车向右转
    void turnRight(){
    	motorDriver_1=0;
    	motorDriver_2=0;
    	motorDriver_3=1;
    	motorDriver_4=0;
    }
    void turnUp(){			  //小车向前走
    	motorDriver_1=1;
    	motorDriver_2=0;
    	motorDriver_3=1;
    	motorDriver_4=0;
    }
    void turnDown(){		  //小车向后走
    	motorDriver_1=0;
    	motorDriver_2=1;
    	motorDriver_3=0;
    	motorDriver_4=1;
    }
    void openHc(){
       Trig=1;
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       Trig=0;
    }
    uchar getDistance(){  //利用超声波模块判断有无障碍物
    	TH0=0;
    	TL0=0;
    	openHc();
    	while(!Echo);
    	TR0=1;
    	while(Echo);
    	TR0=0;
    	sum=TH0*256+TL0;
    	L=(sum*1.78)/100;
    	if(L<barrierDis&&flag==0){
    		LED=0;
    		return 0;
    	}
    	else{
    		LED=1;
    		flag=0;
    		return 1;
    	}
    }
    void main(){
    		LED=1;
    		EA=1;
    		ET0=1;
    		ET1=1;
    		TMOD=0x11;
    		TH1=0xff;
    	    TL1=0x9c;
    		servorTime=0;
    		while(1){
    			 stop();	 
    			 control=15;//控制舵机使超声波模块正对前方
    			 servorTime=0;
    			 TR1=1;
    			 delay(200);
    			 TR1=0;
    			 turnUp();
    			 LED=0;
    			 delay(200);
    			 LED=1;
    			 while(getDistance()==1); //向前行驶,直到前方有障碍物
    			 do{
    			    stop();
    				control=22;	   //使舵机向左摆动
    				servorTime=0;
    				TR1=1;
    			 	delay(200);
    				TR1=0;
    				rFlag=getDistance();
    		 		control=5;		 //使舵机向右摆动
    				servorTime=0;
    				TR1=1;
    		 		delay(200);
    				TR1=0;
    				lFlag=getDistance();
    				turnDown();
    				delay(220);
    				delay(220);
    				delay(220);
    			}while(lFlag==0&&rFlag==0);
    			 if(rFlag==1&&lFlag==0)	//左侧没有障碍物
    			 	turnLeft();
    			 else if(rFlag==0&&lFlag==1)//右侧没有障碍物
    			 	turnRight();
    			 else if(rFlag==1&&lFlag==1)//两侧都没有障碍物,默认向左走
    			 	turnLeft();
    			 delay(220);
    			 delay(220);
    			 delay(200);
    		}
    }
    void T1_int(void) interrupt 3{	  //产生舵机所需要的脉冲
     		TH1=0xff;
    		TL1= 0x9c;
    		servorTime++;
    		if(servorTime<=control)
    			servorControl=1;
    		else
    			servorControl=0;
    		if(servorTime>=200)
    			servorTime=0;
    }
    void T0_int(void) interrupt 1{	  //超声波超出测量范围
    		flag=1;
    }
    
    
    

    ###做好的实物图
    这里写图片描述

    展开全文
  • 51超声波避障小车

    千次阅读 多人点赞 2018-12-26 13:24:11
    超声波避障小车 简介 本文小车的功能主要有两个:超声波测距避障,以及蓝牙遥控。主控芯片用的是STC89C52,电机驱动模块用的是L298N,超声波传感器HC-SR04,蓝牙模块使用的是HC-05,电机采用5V的直流电机。 总体设计...
  • 树莓派超声波测距自动避障

    千次阅读 2019-07-08 22:33:48
    超声波测距的原理很简单,发射一个声波,反弹回来,然后接受反弹回来的这个声波。 利用这个时间差,就可以算出距离了。 欢迎加入交流群:580710182 首先,连接超声波模块,我的连接在GPIO20和GPIO21上,所以相应...
  • 超声波避障

    千次阅读 2016-06-20 15:11:44
    运行如下脚本roslaunch dashgo_bringup bringup_smoother_ob.launch在另一个终端运行rostopic pub -r 10 /smoother_cmd_vel geometry_msgs/Twist '{linear: {x: 0.2, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0}}'...
  • 基于STM32三路超声波避障小车

    万次阅读 多人点赞 2020-05-09 19:20:03
    一般学习单片机的第一步就是做智能小车,通过PWM控制调节车速,以及使用超声波模块进行输入捕获,而这篇文章在于多通道实现输入捕获,因为用到了3个超声波。详细讲解了输入捕获的原理以及一些重要功能的实现代码
  • 机器人避障研究现状

    千次阅读 2018-10-18 10:26:12
    目前主流的无人机避障导航有三种实现方式:使用超声波的方法、使用 TOF 的方法,以及使用视觉图像处理的避障导航方法。前两种为非视觉传感器避障,后一种为新兴的视觉传感器避障方法。 (1)超声波避障 超声波能够...
  • 避障小车是一种智能设备,可以自动感知前方的障碍物,并通过朝另一个方向转动来避开障碍物。该设计允许小车通过避免碰撞在未知环境中导航,这是任何自主移动小车的主要要求。避障小车的应用不受限制,现在大多数军事...
  • 一、使用Arduino与L298N(红板) 驱动直流电机 ...二、接超声波传感器(百度) 三、接红外传感器(百度) 四、3D打印超声波传感器支架 五、mixly图形代码(这个可能不太完善) 红外遥控器设置 ...
  • 测距和避障传感器概述之:超声波

    千次阅读 2016-11-23 18:16:38
    挖坑
  • 前几天已经实现了小车的循迹功能,下面是通过写避障的一些想法:   超声波原理:超声波传感器先发送一个信号,信号遇到障碍物后就会被反弹回来再被超声波传感器接收,接收到的高电平持续的时间就是超声波从发射到...
  • 基于Arduino的超声波避障小车

    千次阅读 多人点赞 2019-11-27 20:20:28
    基于Arduino的超声波避障小车 利用超声波,判断前方是否有障碍物,如果有小车转向,没有小车直行 所需材料 小车车架及车轮(可以用sw建模然后利用3D打印机打印,也可以在网上直接购买小车地板,用纸板最廉价O...
  • **51单片机智能小车(舵机云台超声波避障+循迹+蓝牙+红外跟随+遥控+TFT液晶显示屏) 本人由于使用的液晶显示屏,程序大于8K,所以更换为STC12C5A60S2芯片,与51芯片兼容。 功能比较多: 1舵机云台超声波避障 2....
  • stm32 智能避障小车(二)之hc-sr04

    千次阅读 2019-02-14 17:35:35
    这一篇紧接着介绍hc-sr04超声波模块,思路是实物讲解、模块原理、代码讲解 1、实物讲解 首先还是看看模块的样子,由于超声波不太老实,所以我已经用橡皮筋把它封印住了,咯咯咯个。 紧接着是外部接线,超声波模块...
  • 求一个超声波避障程序,谢谢

    千次阅读 2019-05-08 22:43:52
    求一个超声波避障程序,不要显示模块,也不要外部蓝牙什么控制,简单的自动避障就行。最好是高低电平的定义来控制的 比如 void Car_Turn-Left(void) { RIN1_set; RIN2_clr; LIN1_clr; LIN2_set; 这样的就可以,谢谢 ...
  • 超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计超声波避障小车设计...
  • 超声波避障程序随处可见,基于51单片机的超声波避障小车也很成熟,但是完整的Proteus仿真并不容易找到开源资料。 这次主要给大家分享其Proteus仿真部分。 涉及到的模块有:超声波模块(hc-sr04)、L293D电机驱动器和...
  • Arduino使用红外避障传感器

    万次阅读 2017-11-12 19:55:55
    本文介绍37款传感器套件中的红外避障传感器,它的原理其实和超声波测距类似,一个是发送、接收超声波,另外一个是发送、接收红外线。红外避障传感器的实物图如下所示: 它的左边包含一个红外发射装置和一个接收装置...
1 2 3 4 5 ... 20
收藏数 1,222
精华内容 488
关键字:

超声波避障