15292| 11
|
[项目] 【chocho精选】报告!前方发现mega2560超声波雷达 |
小时候看美国电影,那里面经常出现一个黑黑的屏幕上一根绿色的线来回扫描的机器,后来才知道那叫雷达。在那个年代,雷达简直就是我跟小伙伴们心中唯一的“黑科技”。看见网上很多大神都制作了属于自己的超声波雷达,看得我心痒难耐。今天,我不能再压抑天性了——我也要做一台属于自己的超声波雷达,圆童年的梦,哈哈。 实现原理 用Arduino mega2560作为主控板,控制舵机转动,同时通过超声波采集距离数据,mega2560把这些信息处理后,显示在3.5寸 TFT屏幕上。 所需材料 TowerPro SG90舵机 x1 购买地址 URM07-UART低功耗超声波测距模块x1 购买地址 Bluno Mega2560控制器x1 购买地址 3.5 TFT Mega 触摸显示屏x1 购买地址 制作 在制作之前,请先下载代码到Bluno Mega2560开发板上,点击下载程序源码,源码如下: [mw_shl_code=applescript,true]#include<Servo.h> #include "MultiLCD.h" #include <SPI.h> #include <Arduino.h> #include <FlexiTimer2.h> #define header_H 0x55 //帧头 #define header_L 0xAA //帧头 #define device_Addr 0x11 //模块地址 #define data_Length 0x00 //数据长度 #define get_Dis_CMD 0x02 //距离测量命令 #define checksum (header_H+header_L+device_Addr+data_Length+get_Dis_CMD) //校验和 unsigned char Rx_DATA[8]; unsigned char CMD[6]={header_H,header_L,device_Addr,data_Length,get_Dis_CMD,checksum}; bool clockwise1=false,clockwise2=false,sendFlag=true,angleFlag=true,Serial1Flag=false,dataFlag=false,drawFlag=false,clearFlag=false; int degree_L=30,degree_S=1,angle=1; int x[181],y[181],Dis[181],num=0,Plflag=0; int x0=239,y0=0,r=239,r1=5; int flag=0; Servo myServo; LCD_R61581 lcd; void flash() { if(Serial1.available()) { Serial1Flag=true; } else { Serial1Flag=false; } /* if(flag>0) { myServo.write(degree_S); Sjudge(); }*/ // moveFan(degree_L,1); // Tjudge(); } void setup() { // put your setup code here, to run once: memset(Dis,0,sizeof(Dis)); Serial.begin(19200); Serial1.begin(19200); lcd.begin(); myServo.attach(9); //计算圆心为(239,0),半径为239的半圆每度对应圆周上的坐标 for(int i=0;i<181;i++) { double d=(3.14/180)*i; x=int(x0-r*cos(d)); y=int(r*sin(d)); } for(int i=0;i<180;i++) { lcd.setFontSize(FONT_SIZE_MEDIUM); //set font size lcd.setColor(RGB16_GREEN); lcd.drawLine(x,y,x[i+1],y[i+1]); } //drawMap(); drawFan(31); FlexiTimer2::set(50,flash); FlexiTimer2::start(); } void drawMap() { lcd.setColor(RGB16_GREEN); lcd.drawCircle(x0,y0,50); lcd.drawCircle(x0,y0,100); lcd.drawCircle(x0,y0,150); lcd.drawCircle(x0,y0,200); for(int i=299;i<319;i++) { lcd.clearLine(i); } for(int i=0;i<=180;i+=30) { lcd.setColor(RGB16_GREEN); lcd.drawLine(x0,y0,x,y); } } void clearMap() { lcd.setColor(0); lcd.drawCircle(x0,y0,50); lcd.drawCircle(x0,y0,100); lcd.drawCircle(x0,y0,150); lcd.drawCircle(x0,y0,200); for(int i=0;i<=180;i+=30) { lcd.setColor(RGB16_GREEN); lcd.drawLine(x0,y0,x,y); } } void clearFan(int i) { if(i<30||i>150) return; for(int j=i+30;j>=i-30;j--) { lcd.setColor(0); lcd.drawLine(x0,y0,x[j],y[j]); } } void drawFan(int i) { if(i<30||i>150) return; for(int j=i-30;j<=i+30;j++) { lcd.setColor(RGB16_GREEN); lcd.drawLine(x0,y0,x[j],y[j]); } } void moveFan(int d) { if((d<30)||(d>150)) return; if(clockwise2) { lcd.setColor(RGB16_GREEN); lcd.drawLine(x0,y0,x[d-30],y[d-30]); lcd.setColor(0); lcd.drawLine(x0,y0,x[d+30],y[d+30]); } else { lcd.setColor(RGB16_GREEN); lcd.drawLine(x0,y0,x[d+30],y[d+30]); lcd.setColor(0); lcd.drawLine(x0,y0,x[d-30],y[d-30]); } /* lcd.setColor(RGB16_GREEN); lcd.drawCircle(x0,y0,50); lcd.drawCircle(x0,y0,100); lcd.drawCircle(x0,y0,150); lcd.drawCircle(x0,y0,200);*/ } void drawPoint(int d)//取值范围d:[1,180] { if(Dis[d]==0) return; unsigned int dis=Dis[d]; double dd=(3.14/180)*d; double d1=(3.14/180)*(d-1); int xd1=int(x0-dis*cos(dd)); int yd1=int(dis*sin(dd)); int xd2=int(x0-dis*cos(d1)); int yd2=int(dis*sin(d1)); int xxx=int((xd1+xd2)/2); int yyy=int((yd1+yd2)/2); lcd.setColor(RGB16_RED); lcd.fillCircle(xxx,yyy,r1); } void clearPoint(int d)//d:[1,180] { if(Dis[d]!=0) { int dis=Dis[d]; double dd=(3.14/180)*d; double d1=(3.14/180)*(d-1); int xd1=int(x0-dis*cos(dd)); int yd1=int(dis*sin(d)); int xd2=int(x0-dis*cos(d1)); int yd2=int(dis*sin(d1)); int xxx=int((xd1+xd2)/2); int yyy=int((yd1+yd2)/2); lcd.setColor(0); lcd.fillCircle(xxx,yyy,r1); } } void sendCmd() { for(int i=0;i<6;i++) { Serial1.write(CMD); } } void angleParse() { if(angle>180) { angle=180; angleFlag=false; } if(angle<1) { angle=1; sendFlag=false; angleFlag=true; dataFlag=true; } } void Anglechange(unsigned int dis) { if(angleFlag) { Dis[angle]=dis; angle+=2; angleParse(); } else { Dis[angle]=dis; angle-=2; angleParse(); } } void dataGet() { if(dataFlag==true) { return; } while(Serial1.available()) { Rx_DATA[num++]=Serial1.read(); if(num==1&&Rx_DATA[num-1]!=0x55) { num=0; Plflag++; } if(num==2&&Rx_DATA[num-1]!=0xAA) { num=0; Plflag++; } if(num==2&&Rx_DATA[num-1]==0xAA&&Rx_DATA[num-2]==0x55) { int v=((Plflag%8>0)?1:0); v+=Plflag/8; for(int j=0;j<v;j++) { Anglechange(0); } } if(num==8) { num=0; unsigned char t=Rx_DATA[0]+Rx_DATA[1]+Rx_DATA[2]+Rx_DATA[3]+Rx_DATA[4]+Rx_DATA[5]+Rx_DATA[6]; if(t==Rx_DATA[7]) { unsigned int dis=((Rx_DATA[5]<<8)|Rx_DATA[6]); if(dis>220||dis<0) dis=0; Anglechange(dis); } else { Anglechange(0); } } } } void Sjudge() { if(clockwise1) { degree_S-=2; if(degree_S<1) { degree_S=1; clockwise1=false; } } else { degree_S+=2; if(degree_S>180) { degree_S=180; clockwise1=true; } } } void Tjudge() { if(clockwise2) { degree_L--; if(degree_L<30) { degree_L=30; clockwise2=false; } } else { degree_L++; if(degree_L>150) { degree_L=150; clockwise2=true; } } } void loop() { // put your main code here, to run repeatedly: switch(flag) { case 0: sendCmd(); myServo.write(degree_S); Sjudge(); moveFan(degree_L); Tjudge(); break; case 1: if(degree_S!=1) { myServo.write(degree_S); Sjudge(); } moveFan(degree_L); Tjudge(); break; case 2: clearFan(30); drawMap(); for(int i=1;i<181;i++) { drawPoint(i); } delay(1000); drawFlag=true; break; case 3: for(int i=1;i<181;i++) { Dis=0; } lcd.clear(0,0,479,319); for(int i=0;i<180;i++) { lcd.setColor(RGB16_GREEN); lcd.drawLine(x,y,x[i+1],y[i+1]); } drawFan(30); clearFlag=true; /*moveFan(degree_L,1) clearPoint(degree_L-30+1) clearPoint(degree_L+30) Tjudge();*/ break; default: break; } if(sendFlag==false) { flag=1; } if(degree_S==1&°ree_L==30&&clockwise2==false&&dataFlag==true) { flag=2; } if(drawFlag==true) { flag=3; } if(clearFlag) { sendFlag=true; drawFlag=false; dataFlag=false; clearFlag=false; flag=0; } if(Serial1Flag) { dataGet(); } } [/mw_shl_code] 将Mega2560控制板的VCC、GND、D9引脚用导线引出,并打上热熔胶,并将SG90舵机固定在Mega2560控制板的背面。 将超声波模块的引脚用杜邦线连接到3.5寸屏的UART1串口(这里要注意超声波的正负极哦~,不要连错了),连接好SG90舵机和Mega2560,SG90的橙、红、棕引线分别对应Mega2560的D9、VCC、GND引脚。 然后插上USB线,就可以测到数据啦,哈哈,已经可以从屏幕上看到障碍物了~ 最后,为雷达制作一个外壳,起保护作用,那就用硬纸板加工吧。扫描的效果看着还是很炫酷哦,本人终于圆梦了啦,哈哈。 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed