Arduino智能避障小车避障程序.docx
- 文档编号:2900513
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:23
- 大小:430.65KB
Arduino智能避障小车避障程序.docx
《Arduino智能避障小车避障程序.docx》由会员分享,可在线阅读,更多相关《Arduino智能避障小车避障程序.docx(23页珍藏版)》请在冰点文库上搜索。
Arduino智能避障小车避障程序
首先建立一个名为modulecar.ino的主程序。
//modulecar.ino,玩转智能小车主程序
#include
#include
//对照系统配线方案依次指定各I/O
constintENA=3;//左电机PWM
constintIN1=4;//左电机正
constintIN2=5;//左电机负
constintENB=6;//右电机PWM
constintIN3=7;//右电机正
constintIN4=8;//右电机负
constinttrigger=9;//定义超声波传感器发射脚为D9
constintecho=10;//定义传感器接收脚为D10
constintmax_read=300;//设定传感器最大探测距离。
intno_good=35;//*设定35cm警戒距离。
intread_ahead;//实际距离读数。
ServosensorStation;//设定传感器平台。
NewPingsensor(trigger,echo,max_read);//设定传感器引脚和最大读数
//系统初始化
voidsetup()
{
Serial.begin(9600);//启用串行监视器可以给调试带来极大便利
sensorStation.attach(11);//把D11分配给舵机
pinMode(ENA,OUTPUT);//依次设定各I/O属性
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
pinMode(ENB,OUTPUT);
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
pinMode(trigger,OUTPUT);
pinMode(echo,INPUT);
sensorStation.write(90);//舵机复位至90°
delay(6000);//上电等待6s后进入主循环
}
//主程序
voidloop()
{
read_ahead=readDistance();//调用readDistance()函数读出前方距离
Serial.println("AHEAD:
");
Serial.println(read_ahead);//串行监视器显示机器人前方距离
if(read_ahead { fastStop();//就令机器人紧急刹车 waTch();//然后左右查看,分析得出最佳路线 goForward();//*此处调用看似多余,但可以确保机器人高速运转下动作的连贯性 } elsegoForward();//否则就一直向前行驶 } 主程序用到了两个库,Servo库是IDE自带的,NwePing库是第三方库,需要下载安装。 接下来建立一个名为move.ino的标签。 //move.ino,机动模块。 //刹车 voidfastStop() { Serial.println("STOP");//串行监视器显示机器人状态为STOP(停止) //左电机急停(注: L298N和L293D均带有刹车功能,在使能成立的条件下,同时向两相写入高电平可令电机急停,详见芯片手册) digitalWrite(ENA,HIGH); digitalWrite(IN1,HIGH); digitalWrite(IN2,HIGH); //右电机急停 digitalWrite(ENB,HIGH); digitalWrite(IN3,HIGH); digitalWrite(IN4,HIGH); } //前进 voidgoForward() { Serial.println("FORWARD");//串行监视器显示机器人状态为FORWARD(前进) //左电机逆时针旋转 analogWrite(ENA,106);//左电机PWM,可微调这个数值使小车左右两侧车轮转速相等,右电机同理 digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH); //右电机顺时针旋转 analogWrite(ENB,118); digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW); } //原地左转 voidturnLeft() { Serial.println("LEFT");//串行监视器显示机器人状态为LEFT(向左转) //左电机正转 analogWrite(ENA,106); digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW); //右电机正转 analogWrite(ENB,59);//*微调这个数值,使转弯时内侧车轮起主导作用。 相当于让小车向后打一把轮再拐弯。 右转同理 digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW); delay(205);//*延迟,数值以毫秒为单位,调节此值可使机器人动作连贯 } //原地右转 voidturnRight() { Serial.println("RIGHT");//串行监视器显示机器人状态为RIGHT(向右转) //左电机反转 analogWrite(ENA,53); digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH); //右电机反转 analogWrite(ENB,118); digitalWrite(IN3,LOW); digitalWrite(IN4,HIGH); delay(205);//*调节此值可使机器人动作连贯 } //原地掉头(暂时用不到) voidturnAround() { Serial.println("TURN180");//串行监视器显示机器人状态为TURN180(原地顺时针旋转180°) //左电机反转 analogWrite(ENA,106); digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH); //右电机反转 analogWrite(ENB,118); digitalWrite(IN3,LOW); digitalWrite(IN4,HIGH); delay(500);//* } //ping.ino,测距模块 intreadDistance() { delay(30);//声波发送间隔30ms,大约每秒探测33次。 受系统所限,此值不可小于29ms intcm=sensor.ping()/US_ROUNDTRIP_CM;//把Ping值(μs)转换为cm return(cm);//readDistance()返回的数值是cm } 最后是驱动云台扫描并分析左右两侧距离的watch.ino模块。 //watch.ino,查看模块 voidwaTch() { //测量右前方距离。 //*注意舵机旋转方向,SG5010为逆时针旋转 sensorStation.write(20);//*舵机右转至20°。 调节此值会影响传感器扫描区域,夹角越小,机器人转弯越谨慎 delay(1200);//延迟1.2s待舵机稳定 intread_right=readDistance();//调用readDistance()函数读出右前方距离 Serial.print("RIGHT: "); Serial.println(read_right); //sensorStation.write(90);//*舵机复位至90度。 廉价舵机大角度旋转会产生抖动,要加上这两行以求读数准确。 //delay(500);//延迟0.5s //测量左前方距离 sensorStation.write(160);//舵机左转至160° delay(1200);//延迟1.2s待舵机稳定。 intread_left=readDistance();//调用函数读出距离左前方距离。 Serial.print("LEFT: "); Serial.println(read_left); sensorStation.write(90);//这一行确保只要小车处于行驶状态,传感器就面向正前方 delay(500);//延迟0.5s。 //分析得出最佳行进路线。 if(read_right>read_left)//如果右前方距离比较大 { turnRight();//就向右转, } elseturnLeft();//否则就向左转 //此处也可以加入另一层逻辑: 如果左右两侧读数相等就调用turnAround()原地掉头。 但实际上触发的几率不大。 } //I2C液晶测试程序,Arduino版本1.5.6-r2,LiquidCrystal_I2C库版本2.0 #include #include"LiquidCrystal_I2C.h"//导入I2C液晶库 LiquidCrystal_I2Clcd(0x27,16,2);//设定I2C地址及液晶屏参数 voidsetup() { lcd.init();//始化液晶屏 lcd.backlight(); lcd.print("Hello,world! ");//开始打印信息 lcd.setCursor(3,1);//设定显示位置,第3列,第1行 lcd.print("ZANG.HAIBO"); } voidloop() { } //前进 voidgoForward() { Serial.println("FORWARD");//串行监视器显示机器人状态为FORWARD(前进) //左电机逆时针旋转 intval1=analogRead(A0);//手动调整左电机转速。 电位器两端分别接至+5V和GND,中心抽头接至A0 intleftSpeed=map(val1,0,1023,0,255);//把读数映射为PWM analogWrite(ENA,leftSpeed);//写入速度。 下面的右电机同理 digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH); //右电机顺时针旋转 intval2=analogRead(A1); intrightSpeed=map(val2,0,1023,0,255); analogWrite(ENB,rightSpeed); digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW); } //ping.ino,红外测距模块 //trigger脚沿用D9,echo脚换成A3 intreadDistance() { digitalWrite(trigger,HIGH);//点亮红外发射管 delayMicroseconds(200);//给接收管留出200μs响应时间 IRvalue=analogRead(echo);//读取自然光和红外线下反射值的总和 digitalWrite(trigger,LOW);//关闭红外发射管以读取自然光下的反射值 delayMicroseconds(200);//留出200μs响应时间 IRvalue=IRvalue-analogRead(echo);//刨除自然光得出实际值(红外发射管产生的部分) returnmap(IRvalue,120,930,30,0);//用map()函数把读数转换为距离 } 代码1: HC-SR04超声波传感器典型代码 digitalWrite(TrigPin,LOW); delayMicroseconds (2); digitalWrite(TrigPin,HIGH);//发送10μs的高电平触发信号 delayMicroseconds(10); digitalWrite(TrigPin,LOW); distance=pulseIn(EchoPin,HIGH)*340/60/2;//检测脉冲宽度即为超声波往返时间 代码2: 简易超声波测距代码 constintTrigPin=2; constintEchoPin=3;//设定SR04连接的Arduino引脚 floatdistance; voidsetup(){ //初始化串口通信及连接SR04的引脚 Serial.begin(9600); pinMode(TrigPin,OUTPUT); //要检测引脚上输入的脉冲宽度,需要先设置为输入状态 pinMode(EchoPin,INPUT); Serial.println("Ultrasonicsensor: "); } voidloop(){ //产生一个10μs的高脉冲去触发TrigPin digitalWrite(TrigPin,LOW); delayMicroseconds (2); digitalWrite(TrigPin,HIGH); delayMicroseconds(10); digitalWrite(TrigPin,LOW); //检测脉冲宽度,并计算出距离 distance=pulseIn(EchoPin,HIGH)/58.00; Serial.print(distance); Serial.print("cm"); Serial.println(); delay(1000); } 代码3: 具有温度补偿的超声波测距代码 #include #include //设定SR04连接的Arduino引脚 constintTrigPin=2; constintEchoPin=3; floatdistance; floattemperature_value; #defineONE_WIRE_BUS4 OneWireoneWire(ONE_WIRE_BUS); DallasTemperaturesensors(&oneWire); voidsetup(){//初始化串口通信及连接SR04的引脚 Serial.begin(9600); pinMode(TrigPin,OUTPUT); //要检测引脚上输入的脉冲宽度,需要先设置为输入状态 pinMode(EchoPin,INPUT); sensors.begin(); } voidloop(){ //产生一个10μs的高脉冲去触发TrigPin sensors.requestTemperatures(); temperature_value=sensors.getTempCByIndex(0); Serial.print("temperature="); Serial.print(temperature_value); Serial.print("C"); digitalWrite(TrigPin,LOW); delayMicroseconds (2); digitalWrite(TrigPin,HIGH); delayMicroseconds(10); digitalWrite(TrigPin,LOW); //检测脉冲宽度,并计算出距离 distance=pulseIn(EchoPin,HIGH)*(331.4+0.6*temperature_value)/2; Serial.print("distance="); Serial.print(distance); Serial.print("cm"); Serial.println(); delay(1000); } 代码4: 基于GP2D12的红外测距系统代码 inti; floatval; voidsetup(){ Serial.begin(9600); } voidloop(){ i=analogRead(A0); val=2547.8/((float)i*0.49-10.41)-0.42; Serial.println(val,2); } //蓝牙遥控小车 //Arduino 源程序 //定稿日期: 2016-3-16 //程序功能简介: //程序采用软件PWM方式,控制两支直流电机的运行行为,实现直行、后退、左转和右转动作。 //操作者使用Android手机的蓝牙功能发出指令,操控小车动作。 //操作者还通过蓝牙对小车的动作参数进行调试。 //使用自定义串口收发数据 //使用软件PWM,输出引脚可任意制定 //使用Atmega48芯片 //Arduio 版本1.0.5 #include #include #include #include"usart.h" unsignedintcounter; //PWM计数器 unsignedcharwCnt=0;//接收字计数 unsignedintpwm_LH; //左电机高电平计数 unsignedintpwm_RH; //右电机高电平计数 unsignedcharlDirect; //左电机运转方向 unsignedcharrDirect; //右电机运转方向 unsignedintLP=0; unsignedintRP=0; unsignedintLD=0; unsignedintRD=0; unsignedintPWM[6]; //存放当前PWM参数的整数型数组,全局变量 unsignedcharinputString[8]; // 存输入数据字符串变量 booleanstringComplete=false; // 数据串结束标志 //定时器2初始化函数 voidtimer2_init() { cli(); TCCR2B=0x00;// TCNT2=0xF6;// TCCR2A=0x00; TCCR2B=0x02;// TIMSK2=0x01;//定时器2中断允许 sei(); } //定时器2中断服务函数 //PWM波形产生器 ISR(TIMER2_OVF_vect) { TCNT2=0xF6;// counter++; if(counter==0x3ff) { if(rDirect==1) bitSet(PORTD,5); else bitSet(PORTD,4); if(lDirect==1) bitSet(PORTD,7); else bitSet(PORTD,6); counter=0; } if(counter==pwm_RH) { bitClear(PORTD,4); bitClear(PORTD,5); } if(counter==pwm_LH) { bitClear(PORTD,6); bitClear(PORTD,7); } } //电机运行函数 voidMove(unsignedintLS,unsignedcharLD,unsignedintRS,unsignedcharRD) { asm("BCLR7"); //关中断 pwm_LH=LS; pwm_RH=RS; lDirect=LD; rDirect=RD; asm("BSET7"); //开中断 } //获取EEPROM数据函数 //功能: 从EEPROM里顺序读出六个PWM参数,存入PWM数组 voidGetData() { unsignedcharbytes[2]; //暂时存放PWM参数的字节数组,全局变量 unsignedchari; unsignedcharj; unsignedchark; for(i=0;i<6;i++) //for循环,读六个参数 { for(j=0;j<2;j++) //内循环,每次读两个字节 { k=i*2+1-j; //地址计算 bytes[j]=EEPROM.read(k); //EEPROM读操作 } PWM =word(bytes[0],bytes[1]); //将读出的两个字节合成一个PWM整数数据 } } //数据发送函数 //功能: 将一个整数拆分成四个ASCII代码,通过蓝牙串口发出的函数。 //例如: 整数784,将拆分成;'','7','8','4'四个字符 voidNumber(intval) { inttmp; //中间变量 unsignedchari; //循环计数变量 unsignedcharbuf[4]; //存字符数组 tmp=val/1000; buf[0]=tmp+0x30; //获得千位 val=val%1000; tmp=val/100; buf[1]=tmp+0x30; //获得百位 val=val%100; tmp=val/10; buf[2]=tmp+0x30; //获得十位 val=val%10; buf[3]=val+0x30; //获得个位 for(i=0;i<4;i++) { if(buf ==0x30) //从高位整理,如
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Arduino 智能 小车 程序