diff options
Diffstat (limited to 'serial/serial.c')
-rw-r--r-- | serial/serial.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/serial/serial.c b/serial/serial.c new file mode 100644 index 0000000..db45fac --- /dev/null +++ b/serial/serial.c | |||
@@ -0,0 +1,130 @@ | |||
1 | #include "path_ctrl_t.h" | ||
2 | #include <errno.h> | ||
3 | #include <fcntl.h> | ||
4 | #include <stdbool.h> | ||
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | ||
8 | #include <termios.h> | ||
9 | #include <unistd.h> | ||
10 | |||
11 | typedef unsigned char byte; | ||
12 | #define MAX_BUFFER_SIZE 1024 | ||
13 | #define DEFAULT_SPEED 0x15 | ||
14 | |||
15 | int fd; // 轮子的串口文件描述符 | ||
16 | char portname[50] = "/dev/ttyUSB0"; // 串口设备名 | ||
17 | char clientIP[20] = ""; | ||
18 | struct termios tty; | ||
19 | |||
20 | bool whellInit(); | ||
21 | bool wheelSend(byte a, byte a_v, byte b, byte b_v); | ||
22 | void speedControl(byte status, byte speed); | ||
23 | void parseCmd(const lcm_recv_buf_t *rbuf, const char *channel, | ||
24 | const path_ctrl_t *msg, void *userdata); | ||
25 | |||
26 | int main() { | ||
27 | if (!whellInit()) { | ||
28 | goto err; | ||
29 | } | ||
30 | lcm_t *path_lcm = lcm_create(NULL); | ||
31 | if (!path_lcm) { | ||
32 | fprintf(stderr, "Failed to create LCM\n"); | ||
33 | goto err; | ||
34 | } | ||
35 | path_ctrl_t cmd; | ||
36 | path_ctrl_t_subscribe(path_lcm, "wheel_ctrl", parseCmd, &cmd); | ||
37 | |||
38 | while (true) { | ||
39 | lcm_handle(path_lcm); | ||
40 | } | ||
41 | |||
42 | err: | ||
43 | close(fd); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | bool whellInit() { | ||
48 | // 打开串口 | ||
49 | fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); | ||
50 | if (fd < 0) { | ||
51 | fprintf(stderr, "Error opening %s: %s\n", portname, strerror(errno)); | ||
52 | return false; | ||
53 | } | ||
54 | |||
55 | // 设置串口参数 | ||
56 | memset(&tty, 0, sizeof tty); | ||
57 | if (tcgetattr(fd, &tty) != 0) { | ||
58 | fprintf(stderr, "Error from tcgetattr: %s\n", strerror(errno)); | ||
59 | return false; | ||
60 | } | ||
61 | |||
62 | cfsetospeed(&tty, B115200); // 设置输出波特率为115200 | ||
63 | cfsetispeed(&tty, B115200); // 设置输入波特率为115200 | ||
64 | |||
65 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars | ||
66 | tty.c_iflag &= ~IGNBRK; // ignore break signal | ||
67 | tty.c_lflag = 0; // no signaling chars, no echo, | ||
68 | // no canonical processing | ||
69 | tty.c_oflag = 0; // no remapping, no delays | ||
70 | tty.c_cc[VMIN] = 0; // read doesn't block | ||
71 | tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout | ||
72 | |||
73 | tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl | ||
74 | tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls, | ||
75 | // enable reading | ||
76 | tty.c_cflag &= ~(PARENB | PARODD); // shut off parity | ||
77 | tty.c_cflag |= 0; | ||
78 | tty.c_cflag &= ~CSTOPB; | ||
79 | tty.c_cflag &= ~CRTSCTS; | ||
80 | |||
81 | if (tcsetattr(fd, TCSANOW, &tty) != 0) { | ||
82 | fprintf(stderr, "Error from tcsetattr: %s\n", strerror(errno)); | ||
83 | return false; | ||
84 | } | ||
85 | return true; | ||
86 | } | ||
87 | |||
88 | bool wheelSend(byte a, byte a_v, byte b, byte b_v) { | ||
89 | unsigned char data[7] = {0x53, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
90 | byte checksum = 0; | ||
91 | data[2] = a; | ||
92 | data[3] = a_v; | ||
93 | data[4] = b; | ||
94 | data[5] = b_v; | ||
95 | |||
96 | for (int i = 0; i < 6; i++) { | ||
97 | checksum ^= data[i]; | ||
98 | } | ||
99 | data[6] = checksum; | ||
100 | |||
101 | // 发送数据 | ||
102 | if (write(fd, data, 7) != 7) { | ||
103 | fprintf(stderr, "Failed to write to the serial port\n"); | ||
104 | return false; | ||
105 | } | ||
106 | |||
107 | printf("Data %02X %02X %02X %02X %02X %02X %02X wheelSend successfully!\n", | ||
108 | data[0], data[1], data[2], data[3], data[4], data[5], data[6]); | ||
109 | return true; | ||
110 | } | ||
111 | |||
112 | void parseCmd(const lcm_recv_buf_t *rbuf, const char *channel, | ||
113 | const path_ctrl_t *msg, void *userdata) { | ||
114 | byte status = msg->cmd, speed = msg->speed; | ||
115 | switch (status) { | ||
116 | case 1: | ||
117 | wheelSend(0x01, speed, 0x01, speed); | ||
118 | break; | ||
119 | case 2: | ||
120 | wheelSend(0x02, DEFAULT_SPEED, 0x01, DEFAULT_SPEED); | ||
121 | break; | ||
122 | case 3: | ||
123 | wheelSend(0x01, DEFAULT_SPEED, 0x02, DEFAULT_SPEED); | ||
124 | break; | ||
125 | case 0: | ||
126 | default: | ||
127 | wheelSend(0x00, 0x00, 0x00, 0x00); | ||
128 | break; | ||
129 | } | ||
130 | } \ No newline at end of file | ||