谷动谷力

 找回密码
 立即注册
查看: 2223|回复: 0
打印 上一主题 下一主题
收起左侧

rt-smart学习笔记——小实验:实现“扫描雷达”

[复制链接]
跳转到指定楼层
楼主
发表于 2022-7-19 16:18:31 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
rt-smart学习笔记——小实验:实现“扫描雷达”
作者:ledoen
原文链接:
https://club.rt-thread.org/ask/article/cd6df3872ac4461d.html


一、功能描述

使用控制舵机带动超声波测距模块转动,同时进行测距,完成对0-180°范围内的障碍检测。

使用到了PWM模块、GPT模块和ENET模块

硬件
  • imx6ul开发板
  • 舵机
  • 超声波测距模块
  • 网口


软件
  • 下位机基于rt-smart实现

  • 控制舵机转动
  • 控制测距模块进行测距
  • 使用UDP协议和上位机进行通讯

  • 上位机程序

  • 向下位机发送指令,控制设备运行和停止
  • 接收扫描数据
  • 以雷达图的形式展示扫描结果

二、功能实现

2.1 舵机控制

舵机控制只使用到了PWM模块,代码上使用一个循环,实现舵机从0-180°的往复运动。
  1. void pwm3_rotor_entry(void *parameter)
  2. {
  3.     angle = 1500;
  4.     int16_t increase = SCAN_STEP;
  5.     while(1)
  6.     {
  7.         if (myapp_isrunning)
  8.         {
  9.             rotor_set_angle(angle);
  10.             if (angle == 500)
  11.             {
  12.                 increase = SCAN_STEP;
  13.             }
  14.             else if (angle == 2500)
  15.             {
  16.                 increase = -SCAN_STEP;
  17.             }
  18.             angle += increase;
  19.         }
  20.         else
  21.         {
  22.             rt_thread_mdelay(150);
  23.             rotor_set_angle(1500);
  24.         }
  25.         rt_thread_mdelay(SCAN_PERIOD);
  26.     }
  27. }
复制代码

2.2超声波测距模块

需要使用PWM模块和GPT模块配合控制,PWM模块用于产生10us的启动脉冲,GPT模块用于接收超声波模块返回的echo信号,具体的实现在上一篇文章进行了描述。

2.3UDP通信

下位机和上位机采用服务器/客户端的方式进行通信,下位机作为服务器,上位机作为客户端

数据包分为两种,一种为指令包,上位机发给下位机;一种为数据包,下位机发给上位机。下位机在接收到开始指令后,启动扫描,并开始向上位机发送扫描数据,接收到停止指令时,停止扫描,并停止数据发送。

下位机使用UDP server的方式,参考rt-smart自带example的UDP server,绑定IP和端口。因为需要同时发送和接收,采用了两个线程,一个线程用于循环接收上位机的指令,一个线程用于循环发送扫描数据。
  1. * 接收线程 */
  2. hile (1)

  3.    /* 接收数据,并获取客户端地址 */
  4.    lwip_recvfrom(transfer.sockfd, (void *)recv_buffer, BUFSZ -1, 0,
  5.                    (struct sockaddr *)&client_addr, &addr_len);
  6.    /* 分析数据 */
  7.    if (recv_buffer[0] == 1)
  8.    {
  9.         if (recv_buffer[1] == 1 && transfer.is_running == 0)
  10.         {
  11.             transfer.is_running = 1;
  12.             transfer.radar_control(1);
  13.         }
  14.         else if (recv_buffer[1] == 2 && transfer.is_running == 1)
  15.         {
  16.             transfer.is_running = 0;
  17.             transfer.radar_control(0);
  18.         }
  19.     }        
  20. }
  21. /* 发送线程 */
  22. while (1)
  23. {
  24.     if (transfer.is_running)
  25.     {
  26.         /* 【5】获取数据 */
  27.         transfer.get_data(&angle, &distance);
  28.         /* 【6】整合数据 */
  29.         /*angle = htons(angle);
  30.         distance = htonl(distance);*/
  31.         tran_data[1] = 0xff & angle;
  32.         tran_data[2] = 0xff & (angle >> 8);
  33.         tran_data[3] = 0xff & distance;
  34.         tran_data[4] = 0xff & (distance >> 8);
  35.         tran_data[5] = 0xff & (distance >> 16);
  36.         tran_data[6] = 0xff & (distance >> 24);
  37.         /* 【7】发送数据 */
  38.         lwip_sendto(transfer.sockfd, tran_data, BUFSZ, 0, (struct sockaddr *)&client_addr, sizeof(struct sockaddr));
  39.     }
  40.     rt_thread_mdelay(100);
  41. }
复制代码

2.4总结

程序入口
  1. int myapp(void)
  2. {
  3.     rotor_init();
  4.     /*控制舵机转动*/
  5.     rt_thread_t pwm3_rotor_thread = rt_thread_create(
  6.         "pwm3_rotor",
  7.         pwm3_rotor_entry,
  8.         RT_NULL,
  9.         1024,
  10.         25,
  11.         5
  12.     );
  13.     if (pwm3_rotor_thread != RT_NULL)
  14.     {
  15.         rt_thread_startup(pwm3_rotor_thread);
  16.     }
  17.     hr04_enable();
  18.     /*定时获取角度值*/
  19.     rt_thread_t test_thread = rt_thread_create(
  20.         "hr04",
  21.         test_fun_entry,
  22.         RT_NULL,
  23.         1024,
  24.         25,
  25.         5
  26.     );
  27.     if (test_thread != RT_NULL)
  28.     {
  29.         rt_thread_startup(test_thread);
  30.     }
  31.     /*监控上位机指令*/
  32.     rt_thread_t control_thread = rt_thread_create(
  33.         "myapp",
  34.         myapp_entry,
  35.         RT_NULL,
  36.         1024,
  37.         25,
  38.         5
  39.     );
  40.     if (control_thread != RT_NULL)
  41.     {
  42.         rt_thread_startup(control_thread);
  43.     }
  44.     return 0;
  45. }
复制代码

下位机程序一共使用了4个线程
  • 一个用于控制舵机
  • 一个用于获取距离信息
  • 一个用于监听上位机指令
  • 一个用于发送扫描数据


三、效果

舵机+超声波测距


上位机界面

+10
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-12-28 18:00 , Processed in 0.091767 second(s), 45 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表