鸣涧 发表于 2022-7-19 16:18:31

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

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°的往复运动。void pwm3_rotor_entry(void *parameter)
{
    angle = 1500;
    int16_t increase = SCAN_STEP;
    while(1)
    {
      if (myapp_isrunning)
      {
            rotor_set_angle(angle);
            if (angle == 500)
            {
                increase = SCAN_STEP;
            }
            else if (angle == 2500)
            {
                increase = -SCAN_STEP;
            }
            angle += increase;
      }
      else
      {
            rt_thread_mdelay(150);
            rotor_set_angle(1500);
      }
      rt_thread_mdelay(SCAN_PERIOD);
    }
}
2.2超声波测距模块
需要使用PWM模块和GPT模块配合控制,PWM模块用于产生10us的启动脉冲,GPT模块用于接收超声波模块返回的echo信号,具体的实现在上一篇文章进行了描述。
2.3UDP通信
下位机和上位机采用服务器/客户端的方式进行通信,下位机作为服务器,上位机作为客户端
数据包分为两种,一种为指令包,上位机发给下位机;一种为数据包,下位机发给上位机。下位机在接收到开始指令后,启动扫描,并开始向上位机发送扫描数据,接收到停止指令时,停止扫描,并停止数据发送。
下位机使用UDP server的方式,参考rt-smart自带example的UDP server,绑定IP和端口。因为需要同时发送和接收,采用了两个线程,一个线程用于循环接收上位机的指令,一个线程用于循环发送扫描数据。* 接收线程 */
hile (1)

   /* 接收数据,并获取客户端地址 */
   lwip_recvfrom(transfer.sockfd, (void *)recv_buffer, BUFSZ -1, 0,
                   (struct sockaddr *)&client_addr, &addr_len);
   /* 分析数据 */
   if (recv_buffer == 1)
   {
      if (recv_buffer == 1 && transfer.is_running == 0)
      {
            transfer.is_running = 1;
            transfer.radar_control(1);
      }
      else if (recv_buffer == 2 && transfer.is_running == 1)
      {
            transfer.is_running = 0;
            transfer.radar_control(0);
      }
    }      
}
/* 发送线程 */
while (1)
{
    if (transfer.is_running)
    {
      /* 【5】获取数据 */
      transfer.get_data(&angle, &distance);
      /* 【6】整合数据 */
      /*angle = htons(angle);
      distance = htonl(distance);*/
      tran_data = 0xff & angle;
      tran_data = 0xff & (angle >> 8);
      tran_data = 0xff & distance;
      tran_data = 0xff & (distance >> 8);
      tran_data = 0xff & (distance >> 16);
      tran_data = 0xff & (distance >> 24);
      /* 【7】发送数据 */
      lwip_sendto(transfer.sockfd, tran_data, BUFSZ, 0, (struct sockaddr *)&client_addr, sizeof(struct sockaddr));
    }
    rt_thread_mdelay(100);
}
2.4总结
程序入口int myapp(void)
{
    rotor_init();
    /*控制舵机转动*/
    rt_thread_t pwm3_rotor_thread = rt_thread_create(
      "pwm3_rotor",
      pwm3_rotor_entry,
      RT_NULL,
      1024,
      25,
      5
    );
    if (pwm3_rotor_thread != RT_NULL)
    {
      rt_thread_startup(pwm3_rotor_thread);
    }
    hr04_enable();
    /*定时获取角度值*/
    rt_thread_t test_thread = rt_thread_create(
      "hr04",
      test_fun_entry,
      RT_NULL,
      1024,
      25,
      5
    );
    if (test_thread != RT_NULL)
    {
      rt_thread_startup(test_thread);
    }
    /*监控上位机指令*/
    rt_thread_t control_thread = rt_thread_create(
      "myapp",
      myapp_entry,
      RT_NULL,
      1024,
      25,
      5
    );
    if (control_thread != RT_NULL)
    {
      rt_thread_startup(control_thread);
    }
    return 0;
}

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

三、效果
舵机+超声波测距

上位机界面
页: [1]
查看完整版本: rt-smart学习笔记——小实验:实现“扫描雷达”