1、项目介绍
本次参加‘第二届“2024 汽车应用创意挑战赛”’,由DigiKey得捷&ADI赞助。本次主要参与的方向是安全技术。
使用检测器模块时刻检测周边的物体距离和相对速度,并展示到上位机。
2、硬件介绍
距离检测模块,使用激光来回时间差检测距离,测试距离快且准确。具有30°左右的视界,可以测试各个角度的物体距离。内部具有一个arm m0核,用于快速检测距离,并具有一个可信寄存器,用于决定是否取用距离值的可信度。
树莓派5采用运行频率为2.4GHz的64位四核Arm Cortex-A76处理器,用了新的四核2.4 GHz Cortex-A76 Arm CPU(旧型号最初是Cortex-A72,主频为1.5 GHz,但固件更新将其提升到1.8 GHz),新的南桥承载板承诺提高USB 3的吞吐量,并搭载了新的VideoCore VII GPU(树莓派4上的VideoCore VI主频为500 MHz,而VideoCore VII主频为800 MHz)。整个板子上还有许多小的改进,包括带有安装孔的内置风扇连接器、双摄像头连接器,以及与更高速卡兼容的MicroSD卡读卡器。
3 项目框图
距离检测模块,已按照100ms的时间差,计算距离值,并于上次的距离值进行计算,获取即时速度。
树莓派作为数据中心,等待网路的数据,用于展示。
4、代码讲解
连接树莓派服务器
static EventGroupHandle_t s_wifi_event_group;
#define HOST_IP_ADDR "192.168.2.137"
#define HOST_PORT 6666
static int s_retry_num = 0;
static char payload[256] = "Message from car race: 'hello'!!";
int car_sock = 0;
void tcp_client_task()
{
struct sockaddr_in dest_addr;
inet_pton(AF_INET, HOST_IP_ADDR, &dest_addr.sin_addr);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(HOST_PORT);
car_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (car_sock < 0) {
printf("[%s.%d] Unable to create socket: errno %dn",__func__,__LINE__, errno);
return;
}
printf("[%s.%d]Socket created, connecting to %s:%dn",__func__,__LINE__, HOST_IP_ADDR, HOST_PORT);
char rx_buffer[128];
int err = connect(car_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err != 0) {
printf("[%s.%d] Socket unable to connect: errno %dn",__func__,__LINE__, errno);
return;
}
printf("[%s.%d] Successfully connectedn",__func__,__LINE__);
err = send(car_sock, payload, strlen(payload), 0);
if (err < 0) {
printf("[%s.%d] Error occurred during sending: errno %dn",__func__,__LINE__, errno);
return;
}
memset(rx_buffer, 0, sizeof(rx_buffer));
int len = recv(car_sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if (len < 0) {
printf("[%s.%d]recv failed: errno %dn",__func__,__LINE__, errno);
} else {
printf("[%s.%d]Received %d bytes from %s:n",__func__,__LINE__, len, HOST_IP_ADDR);
printf("[%s.%d]data: %sn",__func__,__LINE__, rx_buffer);
}
}
发送数据给数据中心
void sock_send_data(char *payload,int len)
{
if(!car_sock) return;
int err = send(car_sock, payload, len, 0);
if (err < 0) {
printf("[%s.%d] Error occurred during sending: errno %dn",__func__,__LINE__, errno);
}
}
等待客户端连接,并读取数据
while(1){
addrlen=sizeof(struct sockaddr_in);
connfd = accept(sockfd, (struct sockaddr *)&client_addr,&addrlen);
if(connfd < 0){
perror("accept:");
goto err;
}
printf("连接的客户端IP地址:%sn",inet_ntoa(client_addr.sin_addr));
printf("连接的客户端端口号:%dn",ntohs(client_addr.sin_port));
write(connfd,"hello you!",10);
while(1){
memset(buf,0,sizeof(buf));
ret = read(connfd,buf,sizeof(buf));
if(ret < 0){
perror("read:");
break;
}else if(ret == 0){
printf("write close!n");
break;
}else{
printf("recv:%sn",buf);
}
}
close(connfd);
}
根据数据计算可用的距离值
uint16_t cal_distance(uint16_t *data)
{
uint8_t cnts = 0;
uint8_t max = 0;
uint16_t valall = 0;
uint16_t maxval = 0;
uint16_t minval = 0xffff;
while(max < 5){
if(data[max]){
valall+=data[max];
if(maxval < data[max]){
maxval = data[max];
}
if(data[max] < minval){
minval = data[max];
}
cnts++;
}
max++;
}
if(3 <= cnts){
valall = valall-maxval-minval;
valall = valall/(cnts-2);
}else{
valall = 0;
}
return valall;
}
计算速度
double preDis = 0;
double cuDis = 0;
double cuSudu = 0;
cuDis = cal_distance(spadz5);
cuSudu = (preDis - cuDis)*10;
preDis = cuDis;
5、效果展示
计算结果 有当前物体与我距离,当前物体的速度数据。
6、结言
非常开心能够参加本次活动,项目设计有点简单,初次使用树莓派,很多细节不太了解,会持续使用树莓派,学习更多知识。
本次活动学习到了很多知识,群里大佬们的知识很丰富,让人心向往之。祝与非网论坛和得捷合作更多更好,提供更多更好的竞赛活动,再次感谢与非网论坛和得捷。
7、代码
参考附件