前一段时间拿到一块板子,上面是一个村田陀螺仪,已经经过硬件接口处理过,上面有一个网口和一个usb口,还有一些串口。我现在需要通过网口来拿到陀螺仪的原始数据。硬件工程师给我的文档如下:
第一步:陀螺仪要供电,该陀螺仪测试为12v直流电!
第二步:设置上位机IP,子网掩码,网关。并连接网络.
其实,上位机就相当于server端,而板子就相当于client端,板子要主动上报,说明client端一直向server端发送数据。
第三步:ping一下板子上的IP,看看能不能ping通,如果ping通了说明连接成功。
第四步:利用命令tcpdump -n -i eth0 host SERVER_IP and CLIENT_IP,看看连接成功后是否有数据传输。
第五步:编写代码实现udp传输数据
1 /************************************************************************* 2 > File Name: client.cpp 3 > Author: 李瀚文 4 > Mail: 18646139976@163.com 5 > Created Time: 2019年10月15日 星期二 08时14分06秒 6 ************************************************************************/ 7 #include <iostream> 8 #include <cstdio> 9 #include <cstdlib> 10 #include <cstring> 11 #include <algorithm> 12 #include <vector> 13 #include <map> 14 #include <cmath> 15 #include <sys/socket.h> 16 #include <netinet/in.h> 17 #include <stdio.h> 18 #include <unistd.h> 19 #include <errno.h> 20 #include <arpa/inet.h> 21 #include "socket_udp.h" 22 #include <sys/time.h> 23 24 using namespace std; 25 26 typedef struct UDP_RECEVE { 27 unsigned char header[2]; 28 unsigned char temp[2]; 29 unsigned char ang[2]; 30 unsigned char sum; 31 } UDP_RECEVE; 32 33 int SocketUdpCreateServer() 34 { 35 struct sockaddr_in server_addr; 36 int nSocket = -1; 37 int nOpt = 1; 38 bzero(&server_addr, sizeof(server_addr)); 39 server_addr.sin_family = AF_INET; 40 server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);//此处填写server端IP 41 server_addr.sin_port = htons(SERVER_PORT);//此处填写SERVER端PORT 42 43 /* 创建socket */ 44 nSocket = socket(AF_INET, SOCK_DGRAM, 0); 45 if(nSocket == -1) 46 { 47 perror("SocketUdpCreateServer Create Socket Failed:"); 48 return -1; 49 } 50 51 /*端口复用*/ 52 if(setsockopt(nSocket ,SOL_SOCKET,SO_REUSEADDR,&nOpt,sizeof(nOpt)) == -1) 53 { 54 perror("setsockopt"); 55 close(nSocket); 56 return -1; 57 } 58 /* 绑定套接口 */ 59 if(bind(nSocket,(struct sockaddr*)&server_addr,sizeof(server_addr)) == -1) 60 { 61 perror("SocketUdpCreateServer Server Bind Failed:"); 62 close(nSocket); 63 return -1; 64 } 65 return nSocket; 66 } 67 int SocketUdpRecv(int sockfd, char *pbyBuf, int nLen) 68 { 69 int nRet = 0; 70 //注意此处:由于板子是定向传送,即向指定上位机发送数据,所以,需要定义如下结构体 71 struct sockaddr_in remote_addr; 72 remote_addr.sin_family = AF_INET; 73 remote_addr.sin_addr.s_addr = inet_addr(CLIENT_IP);//此处填写CLIENT端IP 74 remote_addr.sin_port = htons(CLIENT_PORT);//此处填写CLIENT端PORT 75 76 socklen_t addr_len = sizeof(remote_addr); 77 nRet = recvfrom(sockfd, pbyBuf, nLen, 0, (struct sockaddr*)&remote_addr, &addr_len); 78 if(nRet < 1) 79 { 80 if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) 81 { 82 printf("SocketUdpRecv recv EINTR,EWOULDBLOCK,EAGAIN "); 83 return 0; 84 } 85 else 86 { 87 return -1; 88 } 89 } 90 return nRet; 91 } 92 int main() { 93 int sockfd = SocketUdpCreateServer(); 94 char pbyBuf[1024] = {0}; 95 int nLen = sizeof(pbyBuf); 96 float time_use = 0; 97 struct timeval start; 98 struct timeval end; 99 gettimeofday(&start, NULL); 100 while(1) { 101 if (SocketUdpRecv(sockfd, pbyBuf, nLen) < 0) { 102 gettimeofday(&end, NULL); 103 time_use = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec); 104 if (time_use >= 6000000) { 105 close(sockfd); 106 printf("time out error"); 107 return -1; 108 } 109 } 110 UDP_RECEVE rec_udp; 111 memcpy(&rec_udp, pbyBuf, sizeof(rec_udp) + 1); 112 //%#X是16进制的格式占位符 113 printf("header : %#X--%#X temp : %#X--%#X ang : %#X--%#X sum : %#X ---------------------------------- ", rec_udp.header[0], rec_udp.header[1], rec_udp.temp[0], rec_udp.temp[1], rec_udp.ang[0], rec_udp.ang[1], rec_udp.sum); 114 //printf("%d --------------------- ", (int)(rec_udp.ang[0])); 115 memset(pbyBuf, 0, sizeof(pbyBuf)); 116 } 117 return 0; 118 }
第六步:接下来就是对数据进行处理了,如果想通过实时的角速度获得实时的角度,需要对角速度进行积分。