101浏览
查看: 101|回复: 4

[项目] 【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达

[复制链接]
这是一个非常简单、易于制作、视觉效果好且独立的设备,适合初学者和更高级的 DIY 爱好者。

超声波声纳是一种利用频率高于人耳听觉上限(通常高于 20 kHz)的声波来测量物体距离的设备。其工作原理是发出声波,然后测量声波撞击物体后反弹所需的时间。通过计算声波发射和接收之间的时间差,可以根据空气中的声速确定物体的距离。在我之前的一些视频中,您可以看到这种设备具有特殊功能的几种不同版本。所有这些设备都使用 Processing 应用程序中编写的附加程序将结果显示在电脑显示器上。

这次我将向您描述一种制作独立声纳的简单方法,其中结果以雷达图像的形式显示在 TFT 彩色显示屏上,这就是为什么它经常被错误地称为雷达而不是声纳。


这个想法是偶然从网上的一张图片中萌生的,后来经过一番研究,我在 Github 上找到了这个项目。最初的项目是在 1.8 英寸的显示屏上制作的,对于这个用途来说,这个尺寸实在太小了。所以我重新编写了代码,使其适用于更大的 3.2 英寸 TFT 显示屏,这样图像会清晰得多。

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图1

驴友花雕  中级技神
 楼主|

发表于 昨天 06:35

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达

该装置制作非常简单,仅由几个部件组成

Arduino Nano微控制器板
TFT显示屏,分辨率为240 x 320像素,配备ILI9341驱动芯片
HC-SR04型超声波传感器
小型9G舵机
以及几个电阻器,用于将显示信号从 5V 转换为 3.3V 电平
伺服器和超声波传感器安装在一个单独的盒子里,这是我在之前的项目中使用过的,并通过扁平电缆连接到主盒子。

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 06:36

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达

现在让我们看看该设备在实际条件下是如何工作的:

一开始,我将超声波传感器与伺服器分离,以便根据物体的实际距离校准图形显示。如您所见,实际距离与显示屏上显示的距离完全一致。

现在我们将传感器安装在舵机上,并放置需要检测的障碍物。通电后,首先测试舵机,然后显示屏上会显示类似雷达的画面,并开始扫描。

障碍物用红点标记。左下角显示扫描区域,右侧显示传感器与障碍物之间的距离(以厘米为单位)。三条绿色圆弧标示距离,方便我们观察并了解实际距离。如果最近的障碍物大于 1 米,则在最后一条圆弧上绘制黄点,表示超出范围。扫描首先从 180 度扫描至 0 度,然后反之,从 0 度扫描至 180 度。

为了确保运行稳定性,该设备最好使用外部电源供电,但也可以通过 Arduino 上的 USB 供电。所有显示颜色均可根据用户的喜好在代码中轻松更改。

最后,简短总结一下。大多数此类设备会在电脑显示器上显示扫描结果,这需要额外的应用程序和代码。这款设备非常简单易做,视觉效果出色,功能齐全,适合初学者和高级 DIY 爱好者。我之前的项目也用过类似的设备,但希望将所有功能集成到一个设备中,并配备一个倾斜的正面显示屏,以便在视觉上模拟真实的雷达系统。

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图1

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图2

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图3

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图4

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图5

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 06:39

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达

项目代码

  1. #include <Servo.h>
  2. #include <SPI.h>
  3. #include "Ucglib.h"           
  4. #define  trigPin   6      
  5. #define  echoPin   5        
  6. #define  ServoPin  3         
  7. int Ymax = 240;              
  8. int Xmax = 320;              
  9. int Xcent = Xmax / 2;      
  10. int base = 210;              
  11. int scanline = 185;         
  12. Servo baseServo;
  13. //Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);
  14. Ucglib_ILI9341_18x240x320_HWSPI ucg(/*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);
  15. void setup(void)
  16. {
  17.       ucg.begin(UCG_FONT_MODE_SOLID);
  18.       ucg.setRotate90();            
  19.       
  20.       pinMode(trigPin, OUTPUT);      
  21.       pinMode(echoPin, INPUT);      
  22.       Serial.begin(115200);            
  23.       baseServo.attach(ServoPin);   
  24.    
  25.       
  26.       ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
  27.       ucg.setColor(0, 0, 100, 0);
  28.       ucg.setColor(1, 0, 100, 0);
  29.       ucg.setColor(2, 20, 20,20);
  30.       ucg.setColor(3, 20, 20, 20);
  31.       ucg.drawGradientBox(0, 0, 320, 240);
  32.       ucg.setPrintDir(0);
  33.       ucg.setColor(0, 5, 0);
  34.       ucg.setPrintPos(70,120);
  35.       ucg.setFont(ucg_font_logisoso32_tf);  
  36.       ucg.print("Mini Radar");
  37.       ucg.setColor(0, 255, 0);
  38.       ucg.setPrintPos(70,120);
  39.       ucg.print("Mini Radar");
  40.       ucg.setFont(ucg_font_courB14_tf);
  41.       ucg.setColor(20, 255, 20);
  42.       ucg.setPrintPos(90,200);
  43.       ucg.print("Testing...");
  44.       baseServo.write(90);
  45.    
  46.    
  47.       for(int x=0;x<180;x+=5)
  48.           { baseServo.write(x);
  49.             delay(50);
  50.            }
  51.       ucg.print("OK!");
  52.       delay(500);
  53.       ucg.setColor(0,0, 0, 0);
  54.       ucg.setColor(1,0, 0, 0);
  55.       ucg.setColor(2,0, 0, 0);
  56.       ucg.setColor(3,0, 0, 0);
  57.       ucg.drawGradientBox(0, 0, 320, 240);
  58.       delay(10);
  59.    
  60.    
  61.       //ucg.clearScreen();
  62.       cls();
  63.       ucg.setFontMode(UCG_FONT_MODE_SOLID);
  64.       ucg.setFont(ucg_font_helvR08_hr);   // or freedoomr10_tr
  65.   
  66. }
  67. void cls()
  68. {
  69.   ucg.setColor(0, 0, 0, 0);
  70.   for(int s=0;s<240;s++)
  71.   {
  72.     ucg.drawHLine(0,s,320);
  73.     delay(1);
  74.   }
  75.    
  76.   //ucg.drawBox(0, 0, 160, 60);
  77. }
  78. int calculateDistance()
  79. {
  80.       long duration;
  81.    
  82.       digitalWrite(trigPin, LOW);
  83.       delayMicroseconds(2);
  84.       
  85.       digitalWrite(trigPin, HIGH);
  86.       delayMicroseconds(10);
  87.       digitalWrite(trigPin, LOW);
  88.       
  89.       duration = pulseIn(echoPin, HIGH);
  90.      
  91.       return duration*0.034/2;
  92. }
  93. void fix_font()
  94. {
  95.       ucg.setColor(0, 180, 0);
  96.       ucg.setPrintPos(144,44);
  97.       ucg.print("1.00");
  98.       ucg.setPrintPos(144,100);
  99.       ucg.print("0.60");
  100.       ucg.setPrintPos(144,165);
  101.       ucg.print("0.30");
  102. }
  103. void fix()
  104. {
  105.       ucg.setColor(0, 180, 0);
  106.    
  107.       ucg.drawDisc(Xcent, base+1, 3, UCG_DRAW_ALL);
  108.       ucg.drawCircle(Xcent, base+1, 210, UCG_DRAW_UPPER_LEFT);
  109.       ucg.drawCircle(Xcent, base+1, 210, UCG_DRAW_UPPER_RIGHT);
  110.       ucg.drawCircle(Xcent, base+1, 135, UCG_DRAW_UPPER_LEFT);
  111.       ucg.drawCircle(Xcent, base+1, 135, UCG_DRAW_UPPER_RIGHT);
  112.       ucg.drawCircle(Xcent, base+1, 70, UCG_DRAW_UPPER_LEFT);
  113.       ucg.drawCircle(Xcent, base+1, 70, UCG_DRAW_UPPER_RIGHT);
  114.       ucg.drawLine(0, base+1, Xmax,base+1);
  115.      
  116.       ucg.setColor(0, 180, 0);
  117.      
  118.        for(int i= 40;i < 300; i+=2)
  119.        {
  120.         if (i % 10 == 0)
  121.           ucg.drawLine(185*cos(radians(i))+Xcent,base - 185*sin(radians(i)) , 205*cos(radians(i))+Xcent,base - 205*sin(radians(i)));
  122.         
  123.         else
  124.         
  125.          ucg.drawLine(195*cos(radians(i))+Xcent,base - 195*sin(radians(i)) , 205*cos(radians(i))+Xcent,base - 205*sin(radians(i)));
  126.          
  127.        }
  128.          
  129.      
  130.        ucg.setColor(0,200,0);
  131.        ucg.drawLine(0,0,0,36);
  132.        for(int i= 0;i < 5; i++)
  133.        {
  134.           ucg.setColor(0,random(200)+50,0);
  135.           ucg.drawBox(2,i*8,random(28)+3,6);
  136.        }
  137.        ucg.setColor(0,180,0);
  138.        ucg.drawFrame(292,0,28,28);
  139.        ucg.setColor(0,60,0);
  140.        ucg.drawHLine(296,0,20);
  141.        ucg.drawVLine(292,4,20);
  142.        ucg.drawHLine(296,52,20);
  143.        ucg.drawVLine(318,4,20);
  144.         
  145.        ucg.setColor(0,220,0);
  146.        ucg.drawBox(296,4,8,8);
  147.        ucg.drawBox(296,16,8,8);
  148.        ucg.drawBox(308,16,8,8);
  149.        ucg.setColor(0,100,0);
  150.        ucg.drawBox(308,4,8,8);
  151.        ucg.setColor(0,90,0);
  152.        ucg.drawTetragon(124,220,116,230,196,230,204,220);
  153.        ucg.setColor(0,160,0);
  154.        ucg.drawTetragon(134,220,126,230,186,230,194,220);
  155.        ucg.setColor(0,210,0);
  156.        ucg.drawTetragon(144,220,136,230,176,230,184,220);
  157. }
  158. void loop(void)
  159. {
  160.   
  161.   int distance;
  162.   
  163.   fix();
  164.   fix_font();
  165.   for (int x=180; x > 4; x-=2){      
  166.      
  167.       baseServo.write(x);            
  168.       
  169.      
  170.       int f = x - 4;
  171.       ucg.setColor(0, 255, 0);
  172.       ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
  173.       f+=2;
  174.       ucg.setColor(0, 128, 0);
  175.       ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
  176.       f+=2;
  177.       ucg.setColor(0, 0, 0);
  178.       ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
  179.       ucg.setColor(0,200, 0);
  180.      
  181.       distance = calculateDistance();
  182.      
  183.      
  184.       if (distance < 100)
  185.       {
  186.         ucg.setColor(255,0,0);
  187.         ucg.drawDisc(2.2*distance*cos(radians(x))+ Xcent,-2.2*distance*sin(radians(x))+base, 1, UCG_DRAW_ALL);
  188.       }
  189.       else
  190.       {
  191.         ucg.setColor(255,255,0);
  192.         ucg.drawDisc(208*cos(radians(x))+Xcent,-208*sin(radians(x))+base, 1, UCG_DRAW_ALL);
  193.       }
  194.    
  195.            
  196.      
  197.       Serial.print(x);
  198.       Serial.print("    ,   ");
  199.       Serial.println(distance);
  200.      
  201.       if (x > 70 and x < 110)  fix_font();
  202.       ucg.setColor(255,255,  0);
  203.       ucg.setPrintPos(20,230);
  204.       ucg.print("DEG: ");
  205.       ucg.setPrintPos(54,230);
  206.       ucg.print(x);
  207.       ucg.print("  ");
  208.       ucg.setPrintPos(240,230);
  209.       ucg.print("     ");
  210.       ucg.print(distance);
  211.       ucg.print(" cm    ");
  212.       
  213.   }
  214.   //ucg.clearScreen();  
  215.   delay(50);
  216.   cls();   
  217.   fix();
  218.   fix_font();         
  219.   
  220.   for (int  x=1; x < 176; x+=2){     
  221.       baseServo.write(x);            
  222.       
  223.      
  224.       int f = x + 4;
  225.       ucg.setColor(0, 255, 0);
  226.       ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
  227.       f-=2;
  228.       ucg.setColor(0, 128, 0);
  229.       ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
  230.       f-=2;
  231.       ucg.setColor(0, 0, 0);
  232.       ucg.drawLine(Xcent, base, scanline*cos(radians(f))+Xcent,base - scanline*sin(radians(f)));
  233.       ucg.setColor(0, 200, 0);
  234.       
  235.       distance = calculateDistance();
  236.       
  237.       if (distance < 100)
  238.       {
  239.         ucg.setColor(255,0,0);
  240.         ucg.drawDisc(2.2*distance*cos(radians(x))+Xcent,-2.2*distance*sin(radians(x))+base, 1, UCG_DRAW_ALL);
  241.       }
  242.       else
  243.       {
  244.         ucg.setColor(255,255,0);
  245.         ucg.drawDisc(208*cos(radians(x))+Xcent,-208*sin(radians(x))+base, 1, UCG_DRAW_ALL);
  246.       }
  247.            
  248.       
  249.       Serial.print(x);
  250.       Serial.print("    ,   ");
  251.       Serial.println(distance);
  252.      
  253.       if (x > 70 and x < 110)  fix_font();
  254.       
  255.       ucg.setColor(255,255,  0);
  256.       ucg.setPrintPos(20,230);
  257.       ucg.print("DEG: ");
  258.       ucg.setPrintPos(54,230);
  259.       ucg.print(x);
  260.       ucg.print("  ");
  261.       ucg.setPrintPos(240,230);
  262.       ucg.print("     ");
  263.       ucg.print(distance);
  264.       ucg.print(" cm    ");
  265.   
  266.   }
  267. //ucg.clearScreen(); //
  268. delay(50);
  269. cls();
  270. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 06:41

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达

附录
【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达
项目链接:https://www.hackster.io/mircemk/ ... -tft-display-b5dde3
项目作者:北马其顿 米尔塞姆克(Mirko Pavleski)
项目视频 :https://www.youtube.com/watch?v=XOZAGRH_6hA
项目代码:https://www.hackster.io/code_files/653689/download

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图2

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图1

【Arduino 动手做】Arduino 超声波声纳:TFT显示屏上的雷达图3

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail