1035506807 发表于 2016-1-16 17:22:39

超声波红外避障多功能传感小车

本帖最后由 1035506807 于 2016-1-16 17:35 编辑

    随着社会文明和科技的不断进步,人类探索的领域也在不断的拓展,需要获得的信息量也逐步增加,然而在研究和探索的过程中,有些地方是人体不方便或者根本无法进入的,例如在火灾严重处,地震废墟中等等,必须借助外力的帮助才能快捷高效的对这一系列不易进入的地域进行信息的获取和探索。基于这样一个背景,我们组立足当下现有条件设计并组装了一个多功能智能避障小车,该小车了实现超声避障、测距,红外避障、红外跟随, 温度传感、超声测距等三种主要功能。突破传统定点测温的局限,对所需探索环境进行智能移动智能测温。

基于以上目的,我们小组结合已有的资料,设计了超声波红外避障多功能传感小车。

这里感谢小组成员的共同努力。小组成员有魏凯、林桃、张昊天。




实验所需器材如下
Uno 开发板 *1
超声波模块 *1
舵机 *1
开关 *1
220Ω直插电阻*1
10KΩ直插电阻*1
车轮 *2
万向轮 *1
直流电机 *2
3.7V锂电池 *2
L298n直流电机驱动板 *1
大小面包板 *3
面包板跳线 *1 扎
红外传感器+遥控器 *1
1602LCD液晶屏 *1
螺丝螺母等小零件若干


大家根据原理图连接调试,有些简单的部分我就不说了,因为大家应该都会做。

实验原理图如下,由于有些零件找不到图,只能用相似的替代。




实验模块之间的联系如下:



      目前我们有超声波模块,直流电机驱动模块、红外模块、多传感器测量模块(主要包括红外传感器,温度传感器和光传感器)。通过超声波模块或红外模块我们都可以实现避障和跟随的功能(跟随把避障的程序的方向换一下就可以了)。通过避障模块反馈的信息,我们控制直流电机驱动两个前轮的高低电平来实现方向的调整。这里关于传感器的模块,就不多说了。




接下来把我们做小车的程序代码贴出来供大家参考:
超声波避障和多传感器测量模块代码
#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,6,5,4,3);
int potPin = A2;
int HY=A5;
int Echo = A1;// Echo回声脚(P2.0)
int Trig =A0;//Trig 触发脚(P2.1)
int temperature;
int Front_Distance = 0;//
int Left_Distance = 0;
int Right_Distance = 0;
int L;
int Left_motor_back=8;   //左电机后退(IN1)
int Left_motor_go=9;   //左电机前进(IN2)
int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)
int key=7;//定义按键 A2 接口
int beep=A3;//定义蜂鸣器 A3 接口
//const int SensorRight = 3;         //右循迹红外传感器(P3.2 OUT1)
//const int SensorLeft = 4;             //左循迹红外传感器(P3.3 OUT2)
//const int SensorRight_2 = 6;         //右红外传感器(P3.5 OUT4)
//const int SensorLeft_2 = 5;   //左红外传感器(P3.4 OUT3)
//int SL;    //左循迹红外传感器状态
//int SR;    //右循迹红外传感器状态
//int SL_2;    //左红外传感器状态
//int SR_2;    //右红外传感器状态
int servopin=2;//设置舵机驱动脚到数字口2
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量
int val;

void setup()
{
Serial.begin(9600);   // 初始化串口
//初始化电机驱动IO为输出方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
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(key,INPUT);//定义按键接口为输入接口
pinMode(beep,OUTPUT);
// pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
// pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
//pinMode(SensorRight_2, INPUT); //定义右红外传感器为输入
//pinMode(SensorLeft_2, INPUT); //定义左红外传感器为输入
//初始化超声波引脚
pinMode(Echo, INPUT);    // 定义超声波输入脚
pinMode(Trig, OUTPUT);   // 定义超声波输出脚
lcd.begin(16,2);      //初始化1602液晶工作                     模式
//定义1602液晶显示范围为2行16列字符
pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
}
//void run(int time)   // 前进
void run()   // 前进
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);   
analogWrite(Right_motor_go,100);//PWM比例0~255调速,左右轮差异略增
analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH);// 左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Left_motor_back,0);
//delay(time * 100);   //执行时间,可以调整
}
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 * 100);//执行时间,可以调整
}

void left(int time)         //左转(左轮不动,右轮前进)
//void left()         //左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,200);
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 * 100);      //执行时间,可以调整
}
void spin_left(int time)         //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,150);
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,150);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整
}

void right(int time)
//void right()      //右转(右轮不动,左轮前进)
{
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,200);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整
}

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

void back(int time)          //后退
{
digitalWrite(Right_motor_go,LOW);//右轮后退
digitalWrite(Right_motor_back,HIGH);
analogWrite(Right_motor_go,0);
analogWrite(Right_motor_back,200);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左轮后退
digitalWrite(Left_motor_back,HIGH);
analogWrite(Left_motor_go,0);
analogWrite(Left_motor_back,200);//PWM比例0~255调速
delay(time * 100);   //执行时间,可以调整
}
void keysacn()//按键扫描
{
int val;
val=digitalRead(key);//读取数字7 口电平值赋给val
while(!digitalRead(key))//当按键没被按下时,一直循环
{
    val=digitalRead(key);//此句可省略,可让循环跑空
}
while(digitalRead(key))//当按键被按下时
{
    delay(10);      //延时10ms
    val=digitalRead(key);//读取数字7 口电平值赋给val
    if(val==HIGH)//第二次判断按键是否被按下
    {
      digitalWrite(beep,HIGH);                //蜂鸣器响
      while(!digitalRead(key))      //判断按键是否被松开
      digitalWrite(beep,LOW);                //蜂鸣器停止
    }
    else
      digitalWrite(beep,LOW);          //蜂鸣器停止
}
}

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 Distance_display(int Distance)//显示距离
{ int DD;//定义变量
L=analogRead(HY);//读取传感器的模拟值并赋值给val
DD=analogRead(0);// 读取传感器的模拟值并赋值给val
temperature=(DD*0.0048828125*1000); //温度计算公式
if((2<Distance)&(Distance<400))
{
    lcd.home();      //把光标移回左上角,即从头开始输出   
    lcd.print("Distance: ");       //显示
    lcd.setCursor(11,0);   //把光标定位在第2行,第6列
    lcd.print(Distance);       //显示距离
    lcd.print("cm");
lcd.setCursor(0, 1) ; //设置光标位置为第二行第一个位置
lcd.print("T:"); //使屏幕显示文字LM35 Thermometer
lcd.print((long)temperature / 10+18); //显示温度整数位
lcd.print('.'); //显示小数点
lcd.print( (long)temperature % 10); //显示温度小数点后一位
lcd.print((char)223); //显示o符号
lcd.print('C'); //显示字母C
lcd.setCursor(9, 1) ;
lcd.print("L:");
lcd.print(L);
lcd.print("cd");
//延时2秒,这里也就是刷新速度。
}
else
{
    lcd.home();      //把光标移回左上角,即从头开始输出
    lcd.print("!Out of range !");

lcd.setCursor(0, 1) ; //设置光标位置为第二行第一个位置
lcd.print("T:"); //使屏幕显示文字LM35 Thermometer
lcd.print((long)temperature / 10+18); //显示温度整数位
lcd.print('.'); //显示小数点
lcd.print( (long)temperature % 10); //显示温度小数点后一位
lcd.print((char)223); //显示o符号
lcd.print('C'); //显示字母C
lcd.setCursor(9, 1) ;
lcd.print("L:");
lcd.print(L);
lcd.print("cd");
}
delay(250);
lcd.clear();
}
void servopulse(int servopin,int myangle)/ {
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,90);//模拟产生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);         //显示距离
}
void loop()
{
keysacn();         //调用按键扫描函数
while(1)
{
    front_detection();//测量前方距离
    if(Front_Distance < 30)//当遇到障碍物时
    {
      back(2);//后退减速
      brake(2);//停下来做测距
      left_detection();//测量左边距障碍物距离
      Distance_display(Left_Distance);//液晶屏显示距离
      right_detection();//测量右边距障碍物距离
      Distance_display(Right_Distance);//液晶屏显示距离
      if((Left_Distance < 20 ) &&( Right_Distance < 20 ))      spin_left(0.7);//旋转掉头
      else if(Left_Distance > Right_Distance)//左边比右边空旷
      {      
      left(3);//左转
      brake(1);//刹车,稳定方向
      }
      else//右边比左边空旷
      {
      right(3);//右转
      brake(1);//刹车,稳定方向
      }
    }
    else
    {
      run(); //无障碍物,直行   
    }
}
}
外红遥控模块

#include <IRremote.h>//包含红外库
int RECV_PIN = A3;//端口声明
int Distance;
IRrecv irrecv(RECV_PIN);
int temperature;
int L;
int Echo = A1;// Echo回声脚(P2.0)
int Trig =A0;//Trig 触发脚(P2.1)
int HY=A5;//定义模拟接口0 连接光敏电阻
decode_results results;//结构声明
int on = 0;//标志位
unsigned long last = millis();
#include <LiquidCrystal.h> //申明1602液晶的函数库
//申明1602液晶的引脚所连接的Arduino数字端口,8线或4线数据模式,任选其一
//LiquidCrystal lcd(12,11,10,9,8,7,6,5,4,3,2);   //8数据口模式连线声明
LiquidCrystal lcd(13,12,6,5,4,3); //4数据口模式连线声明
int potPin = A2;
int dat;
int servopin=2;//设置舵机驱动脚到数字口2
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量
int val;
int key=7;//定义按键 A2 接口
long run_car = 0x00FF18E7;//按键2
long back_car = 0x00FF4AB5;//按键8
long left_car = 0x00FF10EF;//按键4
long right_car = 0x00FF5AA5;//按键6
long stop_car = 0x00FF38C7;//按键5
long left_turn = 0x00ff30CF;//按键1
long right_turn = 0x00FF7A85;//按键3
//==============================
int Left_motor_back=8;   //左电机后退(IN1)
int Left_motor_go=9;   //左电机前进(IN2)

int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)

void setup()
{
//初始化电机驱动IO为输出方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
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(13, OUTPUT);////端口模式,输出
   pinMode(Echo, INPUT);    // 定义超声波输入脚
pinMode(Trig, OUTPUT);   // 定义超声波输出脚
lcd.begin(16,2);   
   pinMode(key,INPUT);//定义按键接口为输入接口
Serial.begin(9600);      //波特率9600
    pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
irrecv.enableIRIn(); // Start the receiver
}
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 run()   // 前进
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);   
//analogWrite(Right_motor_go,200);//PWM比例0~255调速,左右轮差异略增减
//analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH);// 左电机前进
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,200);//PWM比例0~255调速,左右轮差异略增减
//analogWrite(Left_motor_back,0);
//delay(time * 100);   //执行时间,可以调整
}

void brake()         //刹车,停车
{
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()         //左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);
//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 * 100);      //执行时间,可以调整
}

void spin_left()         //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);
//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,200);//PWM比例0~255调速
//delay(time * 100);      //执行时间,可以调整
}

void right()      //右转(右轮不动,左轮前进)
{
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,200);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100);      //执行时间,可以调整
}

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

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

void dump(decode_results *results)
{
int count = results->rawlen;
if (results->decode_type == UNKNOWN)
{
    //Serial.println("Could not decode message");
    brake();
}
//串口打印,调试时可以打开,实际运行中会影响反应速度,建议屏蔽
/*
else
{

    if (results->decode_type == NEC)
    {
      Serial.print("Decoded NEC: ");
    }
    else if (results->decode_type == SONY)
    {
      Serial.print("Decoded SONY: ");
    }
    else if (results->decode_type == RC5)
    {
      Serial.print("Decoded RC5: ");
    }
    else if (results->decode_type == RC6)
    {
      Serial.print("Decoded RC6: ");
    }
    Serial.print(results->value, HEX);
    Serial.print(" (");
    Serial.print(results->bits, DEC);
    Serial.println(" bits)");
   
}
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");

for (int i = 0; i < count; i++)
{
    if ((i % 2) == 1)
    {
      Serial.print(results->rawbuf*USECPERTICK, DEC);
    }
    else
    {
      Serial.print(-(int)results->rawbuf*USECPERTICK, DEC);
    }
    Serial.print(" ");
}
Serial.println("");
*/
}

void tep_display(int Distance)//显示距离
{ int DD;//定义变量

DD=analogRead(0);// 读取传感器的模拟值并赋值给val
temperature=(DD*0.0048828125*1000);
lcd.home();      //把光标移回左上角,即从头开始输出   
    lcd.print("Distance: ");       //显示
    lcd.setCursor(11,0);   //把光标定位在第2行,第6列
    lcd.print(Distance);       //显示距离
    lcd.print("cm");
lcd.setCursor(0, 1) ; //设置光标位置为第二行第一个位置
lcd.print("T:"); //使屏幕显示文字LM35 Thermometer
lcd.print((long)temperature / 10); //显示温度整数位
lcd.print('.'); //显示小数点
lcd.print( (long)temperature % 10); //显示温度小数点后一位
lcd.print((char)223); //显示o符号
lcd.print('C'); //显示字母C
lcd.setCursor(9, 1) ;
lcd.print("L:");
lcd.print(L);
lcd.print("cd");

delay(5000);
lcd.clear();
}

void loop()
{tep_display(Distance);
if (irrecv.decode(&results)) //调用库函数:解码
{
    // If it's been at least 1/4 second since the last
    // IR received, toggle the relay
    if (millis() - last > 250) //确定接收到信号
    {
      on = !on;//标志位置反
      digitalWrite(13, on ? HIGH : LOW);//板子上接收到信号闪烁一下led
      dump(&results);//解码红外信号
    }
    if (results.value == run_car )//按键2
      run();//前进
    if (results.value == back_car )//按键8
      back();//后退
    if (results.value == left_car )//按键4
      left();//左转
    if (results.value == right_car )//按键6
      right();//右转
    if (results.value == stop_car )//按键5
      brake();//停车
    if (results.value == left_turn )//按键1
      spin_left();//左旋转
    if (results.value == right_turn )//按键3
      spin_right();//右旋转
    last = millis();      
    irrecv.resume(); // Receive the next value
}
}
红外避障
int Left_motor_back=8;   //左电机后退(IN1)
int Left_motor_go=9;   //左电机前进(IN2)
int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)
int key=7;//定义按键 数字7 接口
int beep=12;//定义蜂鸣器 数字12 接口
const int SensorRight = 3;         //右循迹红外传感器(P3.2 OUT1)
const int SensorLeft = 4;             //左循迹红外传感器(P3.3 OUT2)
const int SensorRight_2 = 6;         //右红外传感器(P3.5 OUT4)
const int SensorLeft_2 = 5;   //左红外传感器(P3.4 OUT3)
int SL;    //左循迹红外传感器状态
int SR;    //右循迹红外传感器状态
int SL_2;    //左红外传感器状态
int SR_2;    //右红外传感器状态
void setup()
{
//初始化电机驱动IO为输出方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
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(key,INPUT);//定义按键接口为输入接口
pinMode(beep,OUTPUT);
pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
pinMode(SensorRight_2, INPUT); //定义右红外传感器为输入
pinMode(SensorLeft_2, INPUT); //定义左红外传感器为输入
}
//void run(int time)   // 前进
void run()   // 前进
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);   
analogWrite(Right_motor_go,100);
analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH);// 左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Left_motor_back,0);
   // delay(time * 100);}
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 * 100);//执行时间,可以调整
}
//void left(int time)         //左转(左轮不动,右轮前进)
void left()         //左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,100);
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 * 100);      //执行时间,可以调整
}
void spin_left(int time)         //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,250);
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,100);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整
}
//void right(int time)
void right()      //右转(右轮不动,左轮前进)
{
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,100);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100);      //执行时间,可以调整
}
void spin_right(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,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,100);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整   
}
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,150);//PWM比例0~255调速
delay(time * 100);   //执行时间,可以调整
}
void keysacn()//按键扫描
{
int val;
val=digitalRead(key);//读取数字7 口电平值赋给val
while(!digitalRead(key))//当按键没被按下时,一直循环
{
    val=digitalRead(key);//此句可省略,可让循环跑空
}
while(digitalRead(key))//当按键被按下时
{
    delay(10);      //延时10ms
    val=digitalRead(key);//读取数字7 口电平值赋给val
    if(val==HIGH)//第二次判断按键是否被按下
    {
      digitalWrite(beep,HIGH);                //蜂鸣器响
      while(!digitalRead(key))      //判断按键是否被松开
      digitalWrite(beep,LOW);                //蜂鸣器停止
    }
    else
      digitalWrite(beep,LOW);//蜂鸣器停止
}
}
void loop()
{
keysacn();         //调用按键扫描函数
while(1)
{
    //有信号为LOW没有信号为HIGH
    SR_2 = digitalRead(SensorRight_2);
    SL_2 = digitalRead(SensorLeft_2);
    if (SL_2 == HIGH&&SR_2==HIGH)
    run();
         //调用前进函数
    else if (SL_2 == HIGH & SR_2 == LOW)// 右边探测到有障碍物,有信号返回,向左转
       right();
    else if (SR_2 == HIGH & SL_2 == LOW) //左边探测到有障碍物,有信号返回,向右转
       left();
    else // 都是有障碍物, 后退
      back(3);
}
}

红外跟随模块
int Left_motor_back=8;   //左电机后退(IN1)
int Left_motor_go=9;   //左电机前进(IN2)

int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)

int key=7;//定义按键 数字7 接口
int beep=12;//定义蜂鸣器 数字12 接口

const int SensorRight = 3;         //右循迹红外传感器(P3.2 OUT1)
const int SensorLeft = 4;             //左循迹红外传感器(P3.3 OUT2)

const int SensorRight_2 = 6;         //右红外传感器(P3.5 OUT4)
const int SensorLeft_2 = 5;   //左红外传感器(P3.4 OUT3)

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

void setup()
{
//初始化电机驱动IO为输出方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
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(key,INPUT);//定义按键接口为输入接口
pinMode(beep,OUTPUT);
pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
pinMode(SensorRight_2, INPUT); //定义右红外传感器为输入
pinMode(SensorLeft_2, INPUT); //定义左红外传感器为输入
}
void run(int time)   // 前进
//void run()   // 前进
{
digitalWrite(Right_motor_go,HIGH);// 右电机前进
digitalWrite(Right_motor_back,LOW);   
analogWrite(Right_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,HIGH);// 左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
analogWrite(Left_motor_back,0);
    delay(time * 100);   //执行时间,可以调整
}

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

//void left(int time)         //左转(左轮不动,右轮前进)
void left(int time)         //左转(左轮不动,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,100);
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 * 100);      //执行时间,可以调整
}

void spin_left(int time)         //左转(左轮后退,右轮前进)
{
digitalWrite(Right_motor_go,HIGH);      // 右电机前进
digitalWrite(Right_motor_back,LOW);
analogWrite(Right_motor_go,250);
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,100);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整
}

//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,100);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整
}

void spin_right(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,HIGH);//左电机前进
digitalWrite(Left_motor_back,LOW);
analogWrite(Left_motor_go,100);
analogWrite(Left_motor_back,0);//PWM比例0~255调速
delay(time * 100);      //执行时间,可以调整   
}

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,150);//PWM比例0~255调速
delay(time * 100);   //执行时间,可以调整
}
//==========================================================

void keysacn()//按键扫描
{
int val;
val=digitalRead(key);//读取数字7 口电平值赋给val
while(!digitalRead(key))//当按键没被按下时,一直循环
{
    val=digitalRead(key);//此句可省略,可让循环跑空
}
while(digitalRead(key))//当按键被按下时
{
    delay(10);      //延时10ms
    val=digitalRead(key);//读取数字7 口电平值赋给val
    if(val==HIGH)//第二次判断按键是否被按下
    {
      digitalWrite(beep,HIGH);                //蜂鸣器响
      while(!digitalRead(key))      //判断按键是否被松开
      digitalWrite(beep,LOW);                //蜂鸣器停止
    }
    else
      digitalWrite(beep,LOW);//蜂鸣器停止
}
}

void loop()
{
keysacn();         //调用按键扫描函数
while(1)
{
    //有信号为LOW没有信号为HIGH
    SR_2 = digitalRead(SensorRight_2);
    SL_2 = digitalRead(SensorLeft_2);
    if (SL_2 == HIGH&&SR_2==HIGH)
    {digitalWrite(Right_motor_go,LOW);
    digitalWrite(Left_motor_go,LOW);
    digitalWrite(Right_motor_back,LOW);
    digitalWrite(Left_motor_back,LOW);
    }
         //调用前进函数
    else if (SL_2 == HIGH & SR_2 == LOW)// 右边探测到有障碍物,有信号返回,向左转
      left(3);
    else if (SR_2 == HIGH & SL_2 == LOW) //左边探测到有障碍物,有信号返回,向右转
      right(3);
    else // 都是有障碍物, 后退
      run(3);
}
}

    目前由于一些传感器的缺失和零器件的不足,导致一些功能暂时无法实现。而且由于个人技术的不成熟以及设计的不合理,在运行过程中偶尔会出现卡壳、车轮打滑等现象,这都需要我们接下来进一步改进和完善。

suoma 发表于 2016-1-18 22:07:24

谢谢分享学习一下

holiday117 发表于 2016-1-26 13:21:52

学习学习:)

老屁孩 发表于 2017-7-25 19:44:31

真的让我学习到了
页: [1]
查看完整版本: 超声波红外避障多功能传感小车