【chocho精选】报告!前方发现mega2560超声波雷达
小时候看美国电影,那里面经常出现一个黑黑的屏幕上一根绿色的线来回扫描的机器,后来才知道那叫雷达。在那个年代,雷达简直就是我跟小伙伴们心中唯一的“黑科技”。看见网上很多大神都制作了属于自己的超声波雷达,看得我心痒难耐。今天,我不能再压抑天性了——我也要做一台属于自己的超声波雷达,圆童年的梦,哈哈。
实现原理用arduino mega2560作为主控板,控制舵机转动,同时通过超声波采集距离数据,mega2560把这些信息处理后,显示在3.5寸 TFT屏幕上。
所需材料TowerPro SG90舵机 x1购买地址URM07-UART低功耗超声波测距模块x1购买地址Bluno Mega2560控制器x1购买地址3.5 TFT Mega 触摸显示屏x1购买地址
制作在制作之前,请先下载代码到Bluno Mega2560开发板上,点击下载程序源码,源码如下:#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;
unsigned char CMD={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,y,Dis,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,y);
}
//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,y);
}
}
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,y);
}
}
void moveFan(int d)
{
if((d<30)||(d>150))
return;
if(clockwise2)
{
lcd.setColor(RGB16_GREEN);
lcd.drawLine(x0,y0,x,y);
lcd.setColor(0);
lcd.drawLine(x0,y0,x,y);
}
else
{
lcd.setColor(RGB16_GREEN);
lcd.drawLine(x0,y0,x,y);
lcd.setColor(0);
lcd.drawLine(x0,y0,x,y);
}
/* 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:
{
if(Dis==0)
return;
unsigned int dis=Dis;
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:
{
if(Dis!=0)
{
int dis=Dis;
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=dis;
angle+=2;
angleParse();
}
else
{
Dis=dis;
angle-=2;
angleParse();
}
}
void dataGet()
{
if(dataFlag==true)
{
return;
}
while(Serial1.available())
{
Rx_DATA=Serial1.read();
if(num==1&&Rx_DATA!=0x55)
{
num=0;
Plflag++;
}
if(num==2&&Rx_DATA!=0xAA)
{
num=0;
Plflag++;
}
if(num==2&&Rx_DATA==0xAA&&Rx_DATA==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+Rx_DATA+Rx_DATA+Rx_DATA+Rx_DATA+Rx_DATA+Rx_DATA;
if(t==Rx_DATA)
{
unsigned int dis=((Rx_DATA<<8)|Rx_DATA);
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,y);
}
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();
}
}
将Mega2560控制板的VCC、GND、D9引脚用导线引出,并打上热熔胶,并将SG90舵机固定在Mega2560控制板的背面。
将超声波模块的引脚用杜邦线连接到3.5寸屏的UART1串口(这里要注意超声波的正负极哦~,不要连错了),连接好SG90舵机和Mega2560,SG90的橙、红、棕引线分别对应Mega2560的D9、VCC、GND引脚。
然后插上USB线,就可以测到数据啦,哈哈,已经可以从屏幕上看到障碍物了~
最后,为雷达制作一个外壳,起保护作用,那就用硬纸板加工吧。扫描的效果看着还是很炫酷哦,本人终于圆梦了啦,哈哈。
超炫酷的,用激光测距是不是能得到更高的精度和刷新率 Forgotten 发表于 2018-4-27 17:56
超炫酷的,用激光测距是不是能得到更高的精度和刷新率
我觉得是的,不过需要频率更高一些。 青夏 发表于 2018-4-28 16:18
我觉得是的,不过需要频率更高一些。
可以用这种低成本ToF方案https://www.dfrobot.com.cn/goods-1643.html 满足儿时梦想!{:5_157:} 炫酷的科技。。。。。。。。。。。。。。 {:5_118:}{:5_118:}{:5_118:} Forgotten 发表于 2018-4-27 17:56
超炫酷的,用激光测距是不是能得到更高的精度和刷新率
对的,但是激光的贵一些。 {:5_148:}碉 碉 碉 安卓机器人 发表于 2018-5-14 21:38
碉 碉 碉
谢谢。 真精华!!!!!!
大佬的梦早的都完成了,我还在发梦
页:
[1]