-
Notifications
You must be signed in to change notification settings - Fork 58
Expand file tree
/
Copy pathURM04Sensor.cpp
More file actions
188 lines (165 loc) · 5.98 KB
/
URM04Sensor.cpp
File metadata and controls
188 lines (165 loc) · 5.98 KB
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
#include "URM04Sensor.h"
// instantiate pin connected to the URM04 URM04Sensor
URM04Sensor::URM04Sensor::URM04Sensor(PinName trig_pin, PinName _RX, PinName _TX, uint8_t default_address)
: m_trigPin(trig_pin), m_startAddr(default_address), m_serial(_TX, _RX, BAUD_RATE) {}
bool URM04Sensor::URM04Sensor::trigger_sensor() {
// turn on transmitting mode for RS485
m_trigPin.write(HIGH);
ThisThread::sleep_for(1ms);
/************ INSTANTIATE COMMANDS TO BE SENT OVER SERIAL*********/
// check sum represents the final bit in command buffer - made by adding all previous bits in command buffer
uint8_t checkSum;
// buffer header
m_cmdst[0] = 0x55;
m_cmdst[1] = 0xAA;
// device address
m_cmdst[2] = m_startAddr;
// length
m_cmdst[3] = 0x00;
// the command itself
m_cmdst[4] = 0x01;
// checksum bit
checkSum = m_cmdst[0] + m_cmdst[1] + m_cmdst[2] + m_cmdst[3] + m_cmdst[4];
// instantiate the last element in the command buffer with checksum value
m_cmdst[5] = checkSum;
/******** SEND COMMANDS OVER SERIAL *********************/
// returns the number of bytes if successful write
int num_bytes = m_serial.write(&m_cmdst[0], 6);
// else if numb_btyes < 0 serial failed or if number of bytes written != 6 (because 6 bytes sent over serial)
if (num_bytes != 6) {
// error occured in trigger step
return false;
} else {
// no error occured in trigger step
// flush the buffer from serial
m_serial.sync();
// wait for at least 30 ms after calling trigger function
ThisThread::sleep_for(35ms);
return true;
}
}
// pass by reference a variable to hold the distance value - will give MAX_FLOAT if out of range
bool URM04Sensor::URM04Sensor::read_distance(float& distance) {
/****************** TRIGGER SENSOR BEFORE READING DISTANCE ********************/
// if trigger fails set distance to -1 and return false
if (trigger_sensor() == false) {
distance = -1;
return false;
}
/************ INSTANTIATE COMMANDS TO BE SENT OVER SERIAL************/
// check sum represents the final bit in command buffer - made by adding all previous bits in command buffer
uint8_t checkSum;
// buffer header
m_cmdst[0] = 0x55;
m_cmdst[1] = 0xAA;
// device address
m_cmdst[2] = m_startAddr;
// command length
m_cmdst[3] = 0x00;
// the command itself
m_cmdst[4] = 0x02;
// checksum bit
checkSum = m_cmdst[0] + m_cmdst[1] + m_cmdst[2] + m_cmdst[3] + m_cmdst[4];
// instantiate the last element in the command buffer with checksum value
m_cmdst[5] = checkSum;
/************** SEND COMMANDS OVER SERIAL***********/
// returns the number of bytes if successful read
int w_num_bytes = m_serial.write(&m_cmdst[0], 6);
// else if numb_btyes < 0 serial failed or if number of bytes read != 6 (because 6 bytes sent over serial)
if (w_num_bytes != 6) {
// return false indicating read command has failed
distance = -1;
return false;
}
// flush buffer from serial
m_serial.sync();
/******* READ RETURN VALUE FROM SERIAL**************/
// turn on reading mode for RS485
m_trigPin.write(LOW);
ThisThread::sleep_for(1ms);
// returns the number of bytes if successful read
int r_num_bytes = m_serial.read(&m_cmdst[0], 8);
// else if numb_btyes < 0 serial failed or if number of bytes read != 8 (because 8 bytes sent over serial)
if (r_num_bytes != 8) {
distance = -1;
return false;
}
/******** PARSE THROUGH THE DATA READ FROM SERIAL*********/
else {
// check if the checksum is incorrect
if (m_cmdst[7] != m_cmdst[0] + m_cmdst[1] + m_cmdst[2] + m_cmdst[3] + m_cmdst[4] + m_cmdst[5] + m_cmdst[6]) {
// return false if checksum failed
distance = -1;
return false;
} else {
// get distance from sensor
distance = (float)(m_cmdst[5] << 8) + (float)m_cmdst[6];
// --------------------- or --------------------------
// distance = (float)(m_cmdst[5]*256) + (float)m_cmdst[6];
// check if distance is out of range - if so return maximum float value
if (m_cmdst[5] == 0xFF && m_cmdst[6] == 0xFF) {
distance = MAX_FLOAT;
}
// flush serial
m_serial.sync();
return true;
}
}
}
bool URM04Sensor::URM04Sensor::set_address(uint8_t _address) {
// turn on RS485 transmit mode
m_trigPin.write(HIGH);
ThisThread::sleep_for(1ms);
/************ INSTANTIATE COMMANDS TO BE SENT OVER SERIAL************/
// check sum represents the final bit in command buffer - made by adding all previous bits in command buffer
uint8_t checkSum;
// buffer header
m_cmdst[0] = 0x55;
m_cmdst[1] = 0xAA;
// device address
m_cmdst[2] = 0xAB;
// command length
m_cmdst[3] = 0x01;
// the command itself
m_cmdst[4] = 0x55;
// set new Address
m_cmdst[5] = _address;
// compute checksum bit
checkSum = m_cmdst[0] + m_cmdst[1] + m_cmdst[2] + m_cmdst[3] + m_cmdst[4] + m_cmdst[5];
// instantiate the last element in the command buffer with checksum value
m_cmdst[6] = checkSum;
/************** SEND COMMANDS OVER SERIAL***********/
// send command over serial - write
int w_num_bytes = m_serial.write(&m_cmdst[0], 7);
// check if command was successfully written to the serial
if (w_num_bytes != 7) {
return false;
}
// flush the serial
m_serial.sync();
/************* PARSE THROUGH DATA RECIEVED***********/
// turn on RS485 reading mode
m_trigPin.write(LOW);
ThisThread::sleep_for(1ms);
// read return value from serial
int r_num_bytes = m_serial.read(&m_cmdst[0], 7);
// check if read is successful
if (r_num_bytes != 7) {
return false;
}
// check if the checksum is incorrect
if (m_cmdst[6] != m_cmdst[0] + m_cmdst[1] + m_cmdst[2] + m_cmdst[3] + m_cmdst[4] + m_cmdst[5]) {
return false;
} else {
// check if the command went through successfully by checking if the
// 6th element of the return buffer array == 0x01
if (m_cmdst[5] == 0x01) {
// new address is set
m_startAddr = _address;
// clean up
m_serial.sync();
return true;
}
return false;
}
}