-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathuart_win32.cpp
309 lines (265 loc) · 8.2 KB
/
uart_win32.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// 解析后的数据可以在 data_process 分析
// 请根据实际连接方式修改main函数中对应参数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <math.h>
#include <vector>
#include <windows.h>
#include "data.h"
// serial port handle
int uart_talk(HANDLE hCom, int n, const char* cmd,
int nhdr, const char* hdr_str,
int nfetch, char* fetch)
{
printf("send command : %s\n", cmd);
DWORD dw;
WriteFile(hCom, cmd, n, &dw, NULL);
char buf[2048];
DWORD nr = 0;
ReadFile(hCom, buf, sizeof(buf), &nr, NULL);
while (nr < (int)sizeof(buf))
{
DWORD n;
ReadFile(hCom, buf + nr, sizeof(buf) - nr, &n, NULL);
if (n > 0) nr += n;
}
for (int i = 0; i < (int)sizeof(buf) - nhdr - nfetch; i++)
{
if (memcmp(buf + i, hdr_str, nhdr) == 0)
{
memcpy(fetch, buf + i + nhdr, nfetch);
fetch[nfetch] = 0;
return 0;
}
}
char path[256];
sprintf_s(path, 250, "./tmp/%s.dat", hdr_str);
FILE* fp;
if (fopen_s(&fp, path, "wb") == 0)
{
fwrite(buf, 1, sizeof(buf), fp);
fclose(fp);
}
printf("read %d bytes, not found %s\n", nr, hdr_str);
return -1;
}
int setup_lidar(HANDLE hCom, int unit_is_mm, int with_confidence, int resample, int with_deshadow, int with_smooth)
{
//char buf[] = "LUUIDH";
//write(g_port, buf, strlen(buf));
char buf[32];
DWORD nr = 0;
for (int i = 0; i < 300 && nr <= 0; i++) {
Sleep(10);
ReadFile(hCom, buf, sizeof(buf), &nr, NULL);
}
if (nr <= 0) {
printf("serial port seem not working\n");
return -1;
}
//get product sn (Compatible with multiple models)
if (uart_talk(hCom, 6, "LUUIDH", 11, "PRODUCT SN:", 9, g_uuid) == 0)
{
printf("get product SN : %s\n", g_uuid);
}
//Set the lidar returned data unit CM or MM
if (uart_talk(hCom, 6, unit_is_mm == 0 ? "LMDCMH" : "LMDMMH",
10, "SET LiDAR ", 9, buf) == 0)
{
printf("set LiDAR unit to %s\n", buf);
}
//set lidar confidence state LNCONH close LOCONH open
if (uart_talk(hCom, 6, with_confidence == 0 ? "LNCONH" : "LOCONH",
6, "LiDAR ", 5, buf) == 0)
{
printf("set LiDAR confidence to %s\n", buf);
}
//set de-deshadow state LFFF0H:close LFFF1H:open
if (uart_talk(hCom, 6, with_deshadow == 0 ? "LFFF0H" : "LFFF1H",
6, "LiDAR ", 5, buf) == 0)
{
printf("set deshadow to %d\n", with_deshadow);
}
//set de-smooth LSSS0H:close LSSS1H:open
if (uart_talk(hCom, 6, with_smooth == 0 ? "LSSS0H" : "LSSS1H",
6, "LiDAR ", 5, buf) == 0)
{
printf("set smooth to %d\n", with_smooth);
}
//LSRES:000H :set default Angular resolution LSRES:001H :fix Angular resolution
if (resample == 0)
strcpy_s(buf, 30, "LSRES:000H");
else if (resample == 1)
strcpy_s(buf, 30, "LSRES:001H");
else
buf[0] = 0;
if (buf[0]) {
char buf2[32];
if (uart_talk(hCom, 10, buf, 15, "set resolution ", 1, buf2) == 0)
{
printf("set LiDAR resample to %d\n", resample);
}
}
return 0;
}
HANDLE OpenPort(const char* name, int speed)
{
char path[32];
sprintf_s(path, 30, "\\\\.\\%s", name);
// Open the serial port.
HANDLE hPort = CreateFile(path,
GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute
if (hPort == NULL || hPort == INVALID_HANDLE_VALUE)
{
//MessageBox(0, "can not open port", name, MB_OK);
return 0;
}
DCB PortDCB;
// Initialize the DCBlength member.
PortDCB.DCBlength = sizeof(DCB);
// Get the default port setting information.
GetCommState(hPort, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = speed;// 115200; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement
PortDCB.fNull = FALSE; // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on
// error
PortDCB.ByteSize = 8; // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState(hPort, &PortDCB))
{
//MessageBox(0, "Unable to configure the serial port", "error", MB_OK);
CloseHandle(hPort);
return NULL;
}
// Retrieve the timeout parameters for all read and write operations
// on the port.
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(hPort, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;//10;
CommTimeouts.WriteTotalTimeoutConstant = 0;//1000;
// Set the timeout parameters for all read and write operations
// on the port.
if (!SetCommTimeouts(hPort, &CommTimeouts))
{
// Could not set the timeout parameters.
//MessageBox(0, "Unable to set the timeout parameters", "error", MB_OK);
CloseHandle(hPort);
return NULL;
}
return hPort;
}
int main(int argc, char** argv)
{
int with_chk = 1; // 使能数据校验
if (argc < 8) {
printf("usage : ./lidar 串口名称 波特率 单位是毫米 数据中带有强度 分辨率[0,1,200,225,250,300,333...] 去拖点 平滑 数据打包模式\n");
return -1;
}
char* port = argv[1]; //串口名称 "/dev/ttyUSB0";
int baud_rate = atoi(argv[2]); // 串口波特率
int unit_is_mm = atoi(argv[3]); // 数据是毫米为单位,厘米时为0
int with_confidence = atoi(argv[4]); // 数据中带有强度
int resample = atoi(argv[5]); // 分辨率,0:原始数据,1:角度修正数据,200:0.2°,333:0.3°。。。。
int with_deshadow = atoi(argv[6]); // 去拖点,0:关闭,1:开启
int with_smooth = atoi(argv[7]); // 数据平滑, 0:关闭, 1:开启
int data_bytes = 3; // 数据打包模式,2:2字节, 3:3字节
if (argc > 8) data_bytes = atoi(argv[8]);
// open serial port
HANDLE hCom = OpenPort(port, baud_rate);
if (hCom == NULL) {
printf("Open port error ");
return -1;
}
//
setup_lidar(hCom, unit_is_mm, with_confidence, resample, with_deshadow, with_smooth);
unsigned char* buf = new unsigned char[BUF_SIZE];
int buf_len = 0;
FILE* fp_rec = NULL;// fopen("/tmp/rec.dat", "ab");
int fan_span = 360;
while (1)
{
int new_data = -1;
DWORD nr = 0;
if (ReadFile(hCom, buf + buf_len, BUF_SIZE - buf_len, &nr, NULL))
{
if (nr == 0) continue;
if (nr > 0 && fp_rec) {
fwrite(buf + buf_len, 1, nr, fp_rec);
fflush(fp_rec);
}
new_data = nr;
}
if (new_data > 0)
{
buf_len += new_data;
int consume = 0;
RawData dat;
bool is_pack;
//if (unit_is_mm && with_confidence)
if (data_bytes == 3)
{
is_pack = parse_data_x(buf_len, buf,
fan_span, unit_is_mm, with_confidence,
dat, consume, with_chk);
}
else {
is_pack = parse_data(buf_len, buf,
fan_span, unit_is_mm, with_confidence,
dat, consume, with_chk);
}
if (is_pack)
{
data_process(dat);
}
if (consume > 0)
{
if (!is_pack) {
FILE* fp;
if (fopen_s(&fp, "/tmp/bad.dat", "ab") == 0)
{
fwrite(buf, 1, consume, fp);
fclose(fp);
}
printf("drop %d bytes: %02x %02x %02x %02x %02x %02x",
consume,
buf[0], buf[1], buf[2],
buf[3], buf[4], buf[5]);
}
for (int i = consume; i < buf_len; i++)
buf[i - consume] = buf[i];
buf_len -= consume;
}
}
}
//close(fd);
return 0;
}