一、功能描述
使用控制舵机带动超声波测距模块转动,同时进行测距,完成对0-180°范围内的障碍检测。
使用到了PWM模块、GPT模块和ENET模块
硬件
imx6ul开发板
舵机
超声波测距模块
网口
软件
下位机基于rt-smart实现
控制舵机转动
控制测距模块进行测距
使用UDP协议和上位机进行通讯
上位机程序
向下位机发送指令,控制设备运行和停止
接收扫描数据
以雷达图的形式展示扫描结果
二、功能实现
2.1 舵机控制
舵机控制只使用到了PWM模块,代码上使用一个循环,实现舵机从0-180°的往复运动。
1void 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 while (1)
3 {
4 /* 接收数据,并获取客户端地址 */
5 lwip_recvfrom(transfer.sockfd, (void *)recv_buffer, BUFSZ -1, 0,
6 (struct sockaddr *)&client_addr, &addr_len);
7 /* 分析数据 */
8 if (recv_buffer[0] == 1)
9 {
10 if (recv_buffer[1] == 1 && transfer.is_running == 0)
11 {
12 transfer.is_running = 1;
13 transfer.radar_control(1);
14 }
15 else if (recv_buffer[1] == 2 && transfer.is_running == 1)
16 {
17 transfer.is_running = 0;
18 transfer.radar_control(0);
19 }
20 }
21 }
22 /* 发送线程 */
23 while (1)
24 {
25 if (transfer.is_running)
26 {
27 /* 【5】获取数据 */
28 transfer.get_data(&angle, &distance);
29 /* 【6】整合数据 */
30 /*angle = htons(angle);
31 distance = htonl(distance);*/
32 tran_data[1] = 0xff & angle;
33 tran_data[2] = 0xff & (angle >> 8);
34 tran_data[3] = 0xff & distance;
35 tran_data[4] = 0xff & (distance >> 8);
36 tran_data[5] = 0xff & (distance >> 16);
37 tran_data[6] = 0xff & (distance >> 24);
38 /* 【7】发送数据 */
39 lwip_sendto(transfer.sockfd, tran_data, BUFSZ, 0, (struct sockaddr *)&client_addr, sizeof(struct sockaddr));
40 }
41 rt_thread_mdelay(100);
42 }
2.4总结
程序入口
1int 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个线程
一个用于控制舵机
一个用于获取距离信息
一个用于监听上位机指令
一个用于发送扫描数据
三、效果
舵机+超声波测距
上位机界面
全部0条评论
快来发表一下你的评论吧 !