【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
这是一个非常简单、易于制作、视觉效果好且独立的设备,适合初学者和更高级的 DIY 爱好者。超声波声纳是一种利用频率高于人耳听觉上限(通常高于 20 kHz)的声波来测量物体距离的设备。其工作原理是发出声波,然后测量声波撞击物体后反弹所需的时间。通过计算声波发射和接收之间的时间差,可以根据空气中的声速确定物体的距离。在我之前的一些视频中,您可以看到这种设备具有特殊功能的几种不同版本。所有这些设备都使用 Processing 应用程序中编写的附加程序将结果显示在电脑显示器上。
这次我将向您描述一种制作独立声纳的简单方法,其中结果以雷达图像的形式显示在 TFT 彩色显示屏上,这就是为什么它经常被错误地称为雷达而不是声纳。
这个想法是偶然从网上的一张图片中萌生的,后来经过一番研究,我在 Github 上找到了这个项目。最初的项目是在 1.8 英寸的显示屏上制作的,对于这个用途来说,这个尺寸实在太小了。所以我重新编写了代码,使其适用于更大的 3.2 英寸 TFT 显示屏,这样图像会清晰得多。
【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
该装置制作非常简单,仅由几个部件组成Arduino Nano微控制器板
TFT显示屏,分辨率为240 x 320像素,配备ILI9341驱动芯片
HC-SR04型超声波传感器
小型9G舵机
以及几个电阻器,用于将显示信号从 5V 转换为 3.3V 电平
伺服器和超声波传感器安装在一个单独的盒子里,这是我在之前的项目中使用过的,并通过扁平电缆连接到主盒子。
【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
现在让我们看看该设备在实际条件下是如何工作的:一开始,我将超声波传感器与伺服器分离,以便根据物体的实际距离校准图形显示。如您所见,实际距离与显示屏上显示的距离完全一致。
现在我们将传感器安装在舵机上,并放置需要检测的障碍物。通电后,首先测试舵机,然后显示屏上会显示类似雷达的画面,并开始扫描。
障碍物用红点标记。左下角显示扫描区域,右侧显示传感器与障碍物之间的距离(以厘米为单位)。三条绿色圆弧标示距离,方便我们观察并了解实际距离。如果最近的障碍物大于 1 米,则在最后一条圆弧上绘制黄点,表示超出范围。扫描首先从 180 度扫描至 0 度,然后反之,从 0 度扫描至 180 度。
为了确保运行稳定性,该设备最好使用外部电源供电,但也可以通过 Arduino 上的 USB 供电。所有显示颜色均可根据用户的喜好在代码中轻松更改。
最后,简短总结一下。大多数此类设备会在电脑显示器上显示扫描结果,这需要额外的应用程序和代码。这款设备非常简单易做,视觉效果出色,功能齐全,适合初学者和高级 DIY 爱好者。我之前的项目也用过类似的设备,但希望将所有功能集成到一个设备中,并配备一个倾斜的正面显示屏,以便在视觉上模拟真实的雷达系统。
【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
项目代码#include <Servo.h>
#include <SPI.h>
#include "Ucglib.h"
#definetrigPin 6
#defineechoPin 5
#defineServoPin3
int Ymax = 240;
int Xmax = 320;
int Xcent = Xmax / 2;
int base = 210;
int scanline = 185;
Servo baseServo;
//Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);
Ucglib_ILI9341_18x240x320_HWSPI ucg(/*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);
void setup(void)
{
ucg.begin(UCG_FONT_MODE_SOLID);
ucg.setRotate90();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(115200);
baseServo.attach(ServoPin);
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setColor(0, 0, 100, 0);
ucg.setColor(1, 0, 100, 0);
ucg.setColor(2, 20, 20,20);
ucg.setColor(3, 20, 20, 20);
ucg.drawGradientBox(0, 0, 320, 240);
ucg.setPrintDir(0);
ucg.setColor(0, 5, 0);
ucg.setPrintPos(70,120);
ucg.setFont(ucg_font_logisoso32_tf);
ucg.print("Mini Radar");
ucg.setColor(0, 255, 0);
ucg.setPrintPos(70,120);
ucg.print("Mini Radar");
ucg.setFont(ucg_font_courB14_tf);
ucg.setColor(20, 255, 20);
ucg.setPrintPos(90,200);
ucg.print("Testing...");
baseServo.write(90);
for(int x=0;x<180;x+=5)
{ baseServo.write(x);
delay(50);
}
ucg.print("OK!");
delay(500);
ucg.setColor(0,0, 0, 0);
ucg.setColor(1,0, 0, 0);
ucg.setColor(2,0, 0, 0);
ucg.setColor(3,0, 0, 0);
ucg.drawGradientBox(0, 0, 320, 240);
delay(10);
//ucg.clearScreen();
cls();
ucg.setFontMode(UCG_FONT_MODE_SOLID);
ucg.setFont(ucg_font_helvR08_hr); // or freedoomr10_tr
}
void cls()
{
ucg.setColor(0, 0, 0, 0);
for(int s=0;s<240;s++)
{
ucg.drawHLine(0,s,320);
delay(1);
}
//ucg.drawBox(0, 0, 160, 60);
}
int calculateDistance()
{
long duration;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
return duration*0.034/2;
}
void fix_font()
{
ucg.setColor(0, 180, 0);
ucg.setPrintPos(144,44);
ucg.print("1.00");
ucg.setPrintPos(144,100);
ucg.print("0.60");
ucg.setPrintPos(144,165);
ucg.print("0.30");
}
void fix()
{
ucg.setColor(0, 180, 0);
ucg.drawDisc(Xcent, base+1, 3, UCG_DRAW_ALL);
ucg.drawCircle(Xcent, base+1, 210, UCG_DRAW_UPPER_LEFT);
ucg.drawCircle(Xcent, base+1, 210, UCG_DRAW_UPPER_RIGHT);
ucg.drawCircle(Xcent, base+1, 135, UCG_DRAW_UPPER_LEFT);
ucg.drawCircle(Xcent, base+1, 135, UCG_DRAW_UPPER_RIGHT);
ucg.drawCircle(Xcent, base+1, 70, UCG_DRAW_UPPER_LEFT);
ucg.drawCircle(Xcent, base+1, 70, UCG_DRAW_UPPER_RIGHT);
ucg.drawLine(0, base+1, Xmax,base+1);
ucg.setColor(0, 180, 0);
for(int i= 40;i < 300; i+=2)
{
if (i % 10 == 0)
ucg.drawLine(185*cos(radians(i))+Xcent,base - 185*sin(radians(i)) , 205*cos(radians(i))+Xcent,base - 205*sin(radians(i)));
else
ucg.drawLine(195*cos(radians(i))+Xcent,base - 195*sin(radians(i)) , 205*cos(radians(i))+Xcent,base - 205*sin(radians(i)));
}
ucg.setColor(0,200,0);
ucg.drawLine(0,0,0,36);
for(int i= 0;i < 5; i++)
{
ucg.setColor(0,random(200)+50,0);
ucg.drawBox(2,i*8,random(28)+3,6);
}
ucg.setColor(0,180,0);
ucg.drawFrame(292,0,28,28);
ucg.setColor(0,60,0);
ucg.drawHLine(296,0,20);
ucg.drawVLine(292,4,20);
ucg.drawHLine(296,52,20);
ucg.drawVLine(318,4,20);
ucg.setColor(0,220,0);
ucg.drawBox(296,4,8,8);
ucg.drawBox(296,16,8,8);
ucg.drawBox(308,16,8,8);
ucg.setColor(0,100,0);
ucg.drawBox(308,4,8,8);
ucg.setColor(0,90,0);
ucg.drawTetragon(124,220,116,230,196,230,204,220);
ucg.setColor(0,160,0);
ucg.drawTetragon(134,220,126,230,186,230,194,220);
ucg.setColor(0,210,0);
ucg.drawTetragon(144,220,136,230,176,230,184,220);
}
void loop(void)
{
int distance;
fix();
fix_font();
for (int x=180; x > 4; x-=2){
baseServo.write(x);
int f = x - 4;
ucg.setColor(0, 255, 0);
ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
f+=2;
ucg.setColor(0, 128, 0);
ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
f+=2;
ucg.setColor(0, 0, 0);
ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
ucg.setColor(0,200, 0);
distance = calculateDistance();
if (distance < 100)
{
ucg.setColor(255,0,0);
ucg.drawDisc(2.2*distance*cos(radians(x))+ Xcent,-2.2*distance*sin(radians(x))+base, 1, UCG_DRAW_ALL);
}
else
{
ucg.setColor(255,255,0);
ucg.drawDisc(208*cos(radians(x))+Xcent,-208*sin(radians(x))+base, 1, UCG_DRAW_ALL);
}
Serial.print(x);
Serial.print(" , ");
Serial.println(distance);
if (x > 70 and x < 110)fix_font();
ucg.setColor(255,255,0);
ucg.setPrintPos(20,230);
ucg.print("DEG: ");
ucg.setPrintPos(54,230);
ucg.print(x);
ucg.print("");
ucg.setPrintPos(240,230);
ucg.print(" ");
ucg.print(distance);
ucg.print(" cm ");
}
//ucg.clearScreen();
delay(50);
cls();
fix();
fix_font();
for (intx=1; x < 176; x+=2){
baseServo.write(x);
int f = x + 4;
ucg.setColor(0, 255, 0);
ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
f-=2;
ucg.setColor(0, 128, 0);
ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
f-=2;
ucg.setColor(0, 0, 0);
ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
ucg.setColor(0, 200, 0);
distance = calculateDistance();
if (distance < 100)
{
ucg.setColor(255,0,0);
ucg.drawDisc(2.2*distance*cos(radians(x))+Xcent,-2.2*distance*sin(radians(x))+base, 1, UCG_DRAW_ALL);
}
else
{
ucg.setColor(255,255,0);
ucg.drawDisc(208*cos(radians(x))+Xcent,-208*sin(radians(x))+base, 1, UCG_DRAW_ALL);
}
Serial.print(x);
Serial.print(" , ");
Serial.println(distance);
if (x > 70 and x < 110)fix_font();
ucg.setColor(255,255,0);
ucg.setPrintPos(20,230);
ucg.print("DEG: ");
ucg.setPrintPos(54,230);
ucg.print(x);
ucg.print("");
ucg.setPrintPos(240,230);
ucg.print(" ");
ucg.print(distance);
ucg.print(" cm ");
}
//ucg.clearScreen(); //
delay(50);
cls();
}
【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
附录【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
项目链接:https://www.hackster.io/mircemk/diy-arduino-ultrasonic-sonar-radar-on-tft-display-b5dde3
项目作者:北马其顿 米尔塞姆克(Mirko Pavleski)
项目视频 :https://www.youtube.com/watch?v=XOZAGRH_6hA
项目代码:https://www.hackster.io/code_files/653689/download
页:
[1]