aboutsummaryrefslogtreecommitdiffstats
path: root/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'serial.c')
-rw-r--r--serial.c196
1 files changed, 29 insertions, 167 deletions
diff --git a/serial.c b/serial.c
index 43506ec..6251675 100644
--- a/serial.c
+++ b/serial.c
@@ -1,50 +1,46 @@
1/* 1#include "path/path_ctrl_t.h"
2 * 在OpenHarmony系统下开发串口通信的应用与在Linux系统中类似,
3 * 但需要确保你的设备支持串口操作,并且有适当的驱动支持。
4 *
5 * 以下是一个用C++编写的示例,展示如何在OpenHarmony中打开串口,
6 * 设置波特率为115200,并发送指定的16进制数。
7 * - 打开串口:使用open()函数打开指定的串口设备。
8 * - 配置串口:使用termios结构体配置串口参数如波特率、字符大小、奇偶校验等。
9 * - 发送数据:使用write()函数将数据写入串口。
10 * - 关闭串口:操作完成后,使用close()函数关闭串口。
11 * 确保你的OpenHarmony设备有对应的串口设备文件/dev/ttyS1,
12 * 并且你的应用有足够的权限来访问这个设备。根据你的硬件和操作系统配置,设备文件的路径可能不同。
13 */
14
15#include <arpa/inet.h>
16#include <errno.h> 2#include <errno.h>
17#include <fcntl.h> 3#include <fcntl.h>
18#include <netinet/in.h>
19#include <poll.h>
20#include <pthread.h>
21#include <stdbool.h> 4#include <stdbool.h>
22#include <stdio.h> 5#include <stdio.h>
23#include <stdlib.h> 6#include <stdlib.h>
24#include <string.h> 7#include <string.h>
25#include <sys/socket.h>
26#include <termios.h> 8#include <termios.h>
27#include <unistd.h> 9#include <unistd.h>
28 10
29#define FULL_SPEED 1.0f // 全速前进的速度
30#define R 0.15f // 轮距的一半
31
32typedef unsigned char byte; 11typedef unsigned char byte;
33int fd; 12#define MAX_BUFFER_SIZE 1024
34int port = 5001; 13
14int fd; // 轮子的串口文件描述符
35char portname[50] = "/dev/ttyUSB0"; // 串口设备名 15char portname[50] = "/dev/ttyUSB0"; // 串口设备名
36char clientIP[20] = ""; 16char clientIP[20] = "";
37
38struct termios tty; 17struct termios tty;
39pthread_t udpSend, udpRecv;
40const int MAX_BUFFER_SIZE = 1024;
41struct sockaddr_in clientAddr;
42 18
43int whellInit() { 19bool whellInit();
20bool wheelSend(byte a, byte a_v, byte b, byte b_v);
21void speedControl(byte status, byte speed);
22void parseCmd(const path_ctrl_t *msg, void *user);
23
24int main() {
25 if (!whellInit()) {
26 goto err;
27 }
28 lcm *path_lcm = lcm_create(NULL);
29 if (!path_lcm) {
30 fprintf(stderr, "Failed to create LCM\n");
31 goto err;
32 }
33 path_ctrl_t_subscribe(path_lcm, "PATH_CTRL", parseCmd);
34
35err:
36 close(fd);
37 return 0;
38}
39
40bool whellInit() {
44 // 打开串口 41 // 打开串口
45 fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); 42 fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
46 if (fd < 0) { 43 if (fd < 0) {
47 // C语言报error
48 fprintf(stderr, "Error opening %s: %s\n", portname, strerror(errno)); 44 fprintf(stderr, "Error opening %s: %s\n", portname, strerror(errno));
49 return false; 45 return false;
50 } 46 }
@@ -52,7 +48,6 @@ int whellInit() {
52 // 设置串口参数 48 // 设置串口参数
53 memset(&tty, 0, sizeof tty); 49 memset(&tty, 0, sizeof tty);
54 if (tcgetattr(fd, &tty) != 0) { 50 if (tcgetattr(fd, &tty) != 0) {
55 // cerr << "Error from tcgetattr: " << strerror(errno) << endl;
56 fprintf(stderr, "Error from tcgetattr: %s\n", strerror(errno)); 51 fprintf(stderr, "Error from tcgetattr: %s\n", strerror(errno));
57 return false; 52 return false;
58 } 53 }
@@ -77,7 +72,6 @@ int whellInit() {
77 tty.c_cflag &= ~CRTSCTS; 72 tty.c_cflag &= ~CRTSCTS;
78 73
79 if (tcsetattr(fd, TCSANOW, &tty) != 0) { 74 if (tcsetattr(fd, TCSANOW, &tty) != 0) {
80 // cerr << "Error from tcsetattr: " << strerror(errno) << endl;
81 fprintf(stderr, "Error from tcsetattr: %s\n", strerror(errno)); 75 fprintf(stderr, "Error from tcsetattr: %s\n", strerror(errno));
82 return false; 76 return false;
83 } 77 }
@@ -108,7 +102,8 @@ bool wheelSend(byte a, byte a_v, byte b, byte b_v) {
108 return true; 102 return true;
109} 103}
110 104
111void speedControl(byte status, byte speed) { 105void parseCmd(const path_ctrl_t *msg, void *user) {
106 byte status = msg->cmd, speed = msg->speed;
112 switch (status) { 107 switch (status) {
113 case 1: 108 case 1:
114 wheelSend(0x01, speed, 0x01, speed); 109 wheelSend(0x01, speed, 0x01, speed);
@@ -124,137 +119,4 @@ void speedControl(byte status, byte speed) {
124 wheelSend(0x00, 0x00, 0x00, 0x00); 119 wheelSend(0x00, 0x00, 0x00, 0x00);
125 break; 120 break;
126 } 121 }
127} 122} \ No newline at end of file
128
129void udpSendThread() {
130 // 创建UDP套接字
131 int sockfd = -1;
132 struct sockaddr_in serverAddr;
133 if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
134 fprintf(stderr, "Error: Failed to create socket\n");
135 return;
136 }
137
138 memset((char *)&serverAddr, 0, sizeof(serverAddr));
139 serverAddr.sin_family = AF_INET; // 设置地址族为IPv4
140 serverAddr.sin_port = htons(port); // 设置端口号
141 if (inet_aton(clientIP, &serverAddr.sin_addr) == 0) {
142 fprintf(stderr, "Error: Failed to convert IP address\n");
143 close(sockfd);
144 return;
145 }
146 while (true) {
147 // 每秒向socket发送一次0x30
148 byte a = 0x39;
149 // 发送消息
150 sendto(sockfd, (const char *)&a, 1, 0, (struct sockaddr *)&serverAddr,
151 sizeof(serverAddr));
152 printf("Send: Data %02X udpSend successfully!\n", a);
153 sleep(1);
154 }
155}
156
157void udpRecvThread() {
158 int socketfd = -1;
159 char buffer[MAX_BUFFER_SIZE];
160 struct sockaddr_in serverAddr;
161 socklen_t addrLen = sizeof(serverAddr);
162 int bytesReceived;
163
164 // fd_set readfds;
165 // struct timeval tv;
166 int retval;
167 struct pollfd fds;
168
169 if ((socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
170 fprintf(stderr, "Error: Failed to create socket\n");
171 return;
172 }
173 memset((char *)&serverAddr, 0, sizeof(serverAddr));
174 memset(buffer, 0, sizeof(buffer));
175 serverAddr.sin_family = AF_INET;
176 serverAddr.sin_port = htons(port);
177 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
178
179 if (bind(socketfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) ==
180 -1) {
181 // cerr << "Error: Bind failed" << endl;
182 fprintf(stderr, "Error: Bind failed\n");
183 close(socketfd);
184 return;
185 }
186
187 bytesReceived = recvfrom(socketfd, buffer, MAX_BUFFER_SIZE, 0,
188 (struct sockaddr *)&clientAddr, &addrLen);
189 if (bytesReceived == -1) {
190 fprintf(stderr, "Error: Failed to receive data\n");
191 close(socketfd);
192 return;
193 }
194 printf("Received start message from %s: %s\n",
195 inet_ntoa(clientAddr.sin_addr), buffer);
196 strcpy(clientIP, inet_ntoa(clientAddr.sin_addr));
197
198 if (pthread_create(&udpSend, NULL, udpSendThread, NULL) != 0) {
199 fprintf(stderr, "Error creating udpSend thread\n");
200 close(socketfd);
201 return;
202 }
203
204 fds.fd = socketfd;
205 fds.events = POLLIN;
206
207 while (true) {
208 // /* Watch sock to see when it has input. */
209 // FD_ZERO(&readfds);
210 // FD_SET(socketfd, &readfds);
211 // /* Wait up to three seconds. */
212 // tv.tv_sec = 3;
213 // tv.tv_usec = 0;
214
215 // retval = select(socketfd + 1, &readfds, NULL, NULL, &tv);
216 retval = poll(&fds, 1, 3000);
217 if (retval == -1) {
218 fprintf(stderr, "Error: select failed\n");
219 break;
220 } else if (retval == 0) {
221 printf("No data within three seconds.\n");
222 speedControl(0, 0);
223 // break;
224 } else {
225 bytesReceived = recvfrom(socketfd, buffer, MAX_BUFFER_SIZE, 0,
226 (struct sockaddr *)&clientAddr, &addrLen);
227 if (bytesReceived == -1) {
228 fprintf(stderr, "Error: Failed to receive data\n");
229 continue;
230 }
231 printf("Received Message from %s: %2x %2x\n",
232 inet_ntoa(clientAddr.sin_addr), buffer[0], buffer[1]);
233 speedControl(buffer[0], buffer[1]);
234 }
235 }
236}
237
238int main() {
239 // 关闭1号和2号文件描述符
240 // close(1);
241 // close(2);
242 // // 打开serial.log文件,并将其复制到1号和2号文件描述符
243 // open("serial.log", O_RDWR | O_CREAT, 0666);
244 // dup(1);
245 // dup(2);
246
247 if (!whellInit()) {
248 goto err;
249 }
250
251 if (pthread_create(&udpRecv, NULL, udpRecvThread, NULL) != 0) {
252 fprintf(stderr, "Error creating udpRecv thread\n");
253 goto err;
254 }
255 pthread_join(udpRecv, NULL);
256
257err:
258 close(fd);
259 return 0;
260}