satnogs-rotator-firmware
Loading...
Searching...
No Matches
easycomm.h
Go to the documentation of this file.
1
10#ifndef LIBRARIES_EASYCOMM_H_
11#define LIBRARIES_EASYCOMM_H_
12
13#include <Arduino.h>
14#include <WString.h>
15#if defined(__AVR__)
16#include <avr/wdt.h>
17#endif
18#include "rs485.h"
19#include "rotator_pins.h"
20#include "globals.h"
21
22#define RS485_TX_TIME 9
23#define BUFFER_SIZE 256
24#define BAUDRATE 19200
25
27
28/**************************************************************************/
32/**************************************************************************/
33class easycomm {
34public:
35
36 /**************************************************************************/
40 /**************************************************************************/
43 }
44
45 /**************************************************************************/
49 /**************************************************************************/
51 char buffer[BUFFER_SIZE];
52 char incomingByte;
53 char *Data = buffer;
54 char *rawData;
55 static uint16_t BufferCnt = 0;
56 char data[100];
57 String str1, str2, str3, str4, str5, str6;
58
59 // Read from serial
60 while (rs485.available() > 0) {
61 incomingByte = rs485.read();
62
63 // Read new data, '\n' means new pacakage
64 if (incomingByte == '\n' || incomingByte == '\r') {
65 buffer[BufferCnt] = 0;
66 if (buffer[0] == 'A' && buffer[1] == 'Z') {
67 if (buffer[2] == ' ' && buffer[3] == 'E' &&
68 buffer[4] == 'L') {
69 // Send current absolute position in deg
70 str1 = String("AZ");
71 str2 = String(control_az.input, 1);
72 str3 = String(" EL");
73 str4 = String(control_el.input, 1);
74 str5 = String("\n");
75 rs485.print(str1 + str2 + str3 + str4 + str5);
76 } else {
77 // Get the absolute position in deg for azimuth
79 rawData = strtok_r(Data, " ", &Data);
80 strncpy(data, rawData + 2, 10);
81 if (isNumber(data)) {
82 control_az.setpoint = atof(data);
83 }
84 // Get the absolute position in deg for elevation
85 rawData = strtok_r(Data, " ", &Data);
86 if (rawData[0] == 'E' && rawData[1] == 'L') {
87 strncpy(data, rawData + 2, 10);
88 if (isNumber(data)) {
89 control_el.setpoint = atof(data);
90 }
91 }
92 }
93 } else if (buffer[0] == 'E' && buffer[1] == 'L') {
94 // Get the absolute position in deg for elevation
96 rawData = strtok_r(Data, " ", &Data);
97 if (rawData[0] == 'E' && rawData[1] == 'L') {
98 strncpy(data, rawData + 2, 10);
99 if (isNumber(data)) {
100 control_el.setpoint = atof(data);
101 }
102 }
103 } else if (buffer[0] == 'V' && buffer[1] == 'U') {
104 // Elevation increase speed in mdeg/s
106 strncpy(data, Data + 2, 10);
107 if (isNumber(data)) {
108 // Convert to deg/s
109 control_el.setpoint_speed = atof(data) / 1000;
110 }
111 } else if (buffer[0] == 'V' && buffer[1] == 'D') {
112 // Elevation decrease speed in mdeg/s
114 strncpy(data, Data + 2, 10);
115 if (isNumber(data)) {
116 // Convert to deg/s
117 control_el.setpoint_speed = - atof(data) / 1000;
118 }
119 } else if (buffer[0] == 'V' && buffer[1] == 'L') {
120 // Azimuth increase speed in mdeg/s
122 strncpy(data, Data + 2, 10);
123 if (isNumber(data)) {
124 // Convert to deg/s
125 control_az.setpoint_speed = atof(data) / 1000;
126 }
127 } else if (buffer[0] == 'V' && buffer[1] == 'R') {
128 // Azimuth decrease speed in mdeg/s
130 strncpy(data, Data + 2, 10);
131 if (isNumber(data)) {
132 // Convert to deg/s
133 control_az.setpoint_speed = - atof(data) / 1000;
134 }
135 } else if (buffer[0] == 'S' && buffer[1] == 'A' &&
136 buffer[2] == ' ' && buffer[3] == 'S' &&
137 buffer[4] == 'E') {
138 // Stop Moving
140 str1 = String("AZ");
141 str2 = String(control_az.input, 1);
142 str3 = String(" EL");
143 str4 = String(control_el.input, 1);
144 str5 = String("\n");
145 rs485.print(str1 + str2 + str3 + str4 + str5);
148 } else if (buffer[0] == 'R' && buffer[1] == 'E' &&
149 buffer[2] == 'S' && buffer[3] == 'E' &&
150 buffer[4] == 'T') {
151 // Reset the rotator, go to home position
152 str1 = String("AZ");
153 str2 = String(control_az.input, 1);
154 str3 = String(" EL");
155 str4 = String(control_el.input, 1);
156 str5 = String("\n");
157 rs485.print(str1 + str2 + str3 + str4 + str5);
158 rotator.homing_flag = false;
159 } else if (buffer[0] == 'P' && buffer[1] == 'A' &&
160 buffer[2] == 'R' && buffer[3] == 'K' ) {
161 // Park the rotator
163 str1 = String("AZ");
164 str2 = String(control_az.input, 1);
165 str3 = String(" EL");
166 str4 = String(control_el.input, 1);
167 str5 = String("\n");
168 rs485.print(str1 + str2 + str3 + str4 + str5);
171 } else if (buffer[0] == 'V' && buffer[1] == 'E') {
172 // Get the version if rotator controller
173 str1 = String("VE");
174 str2 = String("SatNOGS-v2.2");
175 str3 = String("\n");
176 rs485.print(str1 + str2 + str3);
177 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
178 buffer[2] == '0') {
179 // Get the inside temperature
180 str1 = String("IP0,");
181 str2 = String(rotator.inside_temperature, DEC);
182 str3 = String("\n");
183 rs485.print(str1 + str2 + str3);
184 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
185 buffer[2] == '1') {
186 // Get the status of end-stop, azimuth
187 str1 = String("IP1,");
188 str2 = String(rotator.switch_az, DEC);
189 str3 = String("\n");
190 rs485.print(str1 + str2 + str3);
191 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
192 buffer[2] == '2') {
193 // Get the status of end-stop, elevation
194 str1 = String("IP2,");
195 str2 = String(rotator.switch_el, DEC);
196 str3 = String("\n");
197 rs485.print(str1 + str2 + str3);
198 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
199 buffer[2] == '3') {
200 // Get the current position of azimuth in deg
201 str1 = String("IP3,");
202 str2 = String(control_az.input, 2);
203 str3 = String("\n");
204 rs485.print(str1 + str2 + str3);
205 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
206 buffer[2] == '4') {
207 // Get the current position of elevation in deg
208 str1 = String("IP4,");
209 str2 = String(control_el.input, 2);
210 str3 = String("\n");
211 rs485.print(str1 + str2 + str3);
212 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
213 buffer[2] == '5') {
214 // Get the load of azimuth, in range of 0-1023
215 str1 = String("IP5,");
216 str2 = String(control_az.load, DEC);
217 str3 = String("\n");
218 rs485.print(str1 + str2 + str3);
219 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
220 buffer[2] == '6') {
221 // Get the load of elevation, in range of 0-1023
222 str1 = String("IP6,");
223 str2 = String(control_el.load, DEC);
224 str3 = String("\n");
225 rs485.print(str1 + str2 + str3);
226 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
227 buffer[2] == '7') {
228 // Get the speed of azimuth in deg/s
229 str1 = String("IP7,");
230 str2 = String(control_az.speed, 2);
231 str3 = String("\n");
232 rs485.print(str1 + str2 + str3);
233 } else if (buffer[0] == 'I' && buffer[1] == 'P' &&
234 buffer[2] == '8') {
235 // Get the speed of elevation in deg/s
236 str1 = String("IP8,");
237 str2 = String(control_el.speed, 2);
238 str3 = String("\n");
239 rs485.print(str1 + str2 + str3);
240 } else if (buffer[0] == 'G' && buffer[1] == 'S') {
241 // Get the status of rotator
242 str1 = String("GS");
243 str2 = String(rotator.rotator_status, DEC);
244 str3 = String("\n");
245 rs485.print(str1 + str2 + str3);
246 } else if (buffer[0] == 'G' && buffer[1] == 'E') {
247 // Get the error of rotator
248 str1 = String("GE");
249 str2 = String(rotator.rotator_error, DEC);
250 str3 = String("\n");
251 rs485.print(str1 + str2 + str3);
252 } else if(buffer[0] == 'C' && buffer[1] == 'R') {
253 // Get Configuration of rotator
254 if (buffer[3] == '1') {
255 // Get Kp Azimuth gain
256 str1 = String("1,");
257 str2 = String(control_az.p, 2);
258 str3 = String("\n");
259 rs485.print(str1 + str2 + str3);
260 } else if (buffer[3] == '2') {
261 // Get Ki Azimuth gain
262 str1 = String("2,");
263 str2 = String(control_az.i, 2);
264 str3 = String("\n");
265 rs485.print(str1 + str2 + str3);
266 } else if (buffer[3] == '3') {
267 // Get Kd Azimuth gain
268 str1 = String("3,");
269 str2 = String(control_az.d, 2);
270 str3 = String("\n");
271 rs485.print(str1 + str2 + str3);
272 } else if (buffer[3] == '4') {
273 // Get Kp Elevation gain
274 str1 = String("4,");
275 str2 = String(control_el.p, 2);
276 str3 = String("\n");
277 rs485.print(str1 + str2 + str3);
278 } else if (buffer[3] == '5') {
279 // Get Ki Elevation gain
280 str1 = String("5,");
281 str2 = String(control_el.i, 2);
282 str3 = String("\n");
283 rs485.print(str1 + str2 + str3);
284 } else if (buffer[3] == '6') {
285 // Get Kd Elevation gain
286 str1 = String("6,");
287 str2 = String(control_el.d, 2);
288 str3 = String("\n");
289 rs485.print(str1 + str2 + str3);
290 } else if (buffer[3] == '7') {
291 // Get Azimuth park position
292 str1 = String("7,");
293 str2 = String(rotator.park_az, 2);
294 str3 = String("\n");
295 rs485.print(str1 + str2 + str3);
296 } else if (buffer[3] == '8') {
297 // Get Elevation park position
298 str1 = String("8,");
299 str2 = String(rotator.park_el, 2);
300 str3 = String("\n");
301 rs485.print(str1 + str2 + str3);
302 } else if (buffer[3] == '9') {
303 // Get control mode
304 str1 = String("9,");
305 str2 = String(rotator.control_mode);
306 str3 = String("\n");
307 rs485.print(str1 + str2 + str3);
308 }
309 } else if (buffer[0] == 'C' && buffer[1] == 'W') {
310 // Set Config
311 if (buffer[2] == '1') {
312 // Set Kp Azimuth gain
313 rawData = strtok_r(Data, ",", &Data);
314 strncpy(data, rawData + 4, 10);
315 if (isNumber(data)) {
316 control_az.p = atof(data);
317 }
318 } else if (buffer[2] == '2') {
319 // Set Ki Azimuth gain
320 rawData = strtok_r(Data, ",", &Data);
321 strncpy(data, rawData + 4, 10);
322 if (isNumber(data)) {
323 control_az.i = atof(data);
324 }
325 } else if (buffer[2] == '3') {
326 // Set Kd Azimuth gain
327 rawData = strtok_r(Data, ",", &Data);
328 strncpy(data, rawData + 4, 10);
329 if (isNumber(data)) {
330 control_az.d = atof(data);
331 }
332 } else if (buffer[2] == '4') {
333 // Set Kp Elevation gain
334 rawData = strtok_r(Data, ",", &Data);
335 strncpy(data, rawData + 4, 10);
336 if (isNumber(data)) {
337 control_el.p = atof(data);
338 }
339 } else if (buffer[2] == '5') {
340 // Set Ki Elevation gain
341 rawData = strtok_r(Data, ",", &Data);
342 strncpy(data, rawData + 4, 10);
343 if (isNumber(data)) {
344 control_el.i = atof(data);
345 }
346 } else if (buffer[2] == '6') {
347 // Set Kd Elevation gain
348 rawData = strtok_r(Data, ",", &Data);
349 strncpy(data, rawData + 4, 10);
350 if (isNumber(data)) {
351 control_el.d = atof(data);
352 }
353 } else if (buffer[2] == '7') {
354 // Set the Azimuth park position
355 rawData = strtok_r(Data, ",", &Data);
356 strncpy(data, rawData + 4, 10);
357 if (isNumber(data)) {
358 rotator.park_az = atof(data);
359 }
360 } else if (buffer[2] == '8') {
361 // Set the Elevation park position
362 rawData = strtok_r(Data, ",", &Data);
363 strncpy(data, rawData + 4, 10);
364 if (isNumber(data)) {
365 rotator.park_el = atof(data);
366 }
367 }
368 } else if (buffer[0] == 'R' && buffer[1] == 'S'
369 && buffer[2] == 'T') {
370 // Custom command to test the watchdog timer routine
371 while(1)
372 ;
373 } else if (buffer[0] == 'R' && buffer[1] == 'B') {
374 // Custom command to reboot the uC
375#if defined(__AVR__)
376 wdt_enable(WDTO_2S);
377 while(1);
378#endif
379 }
380 // Reset the buffer an clean the serial buffer
381 BufferCnt = 0;
382 rs485.flush();
383 } else {
384 // Fill the buffer with incoming data
385 buffer[BufferCnt] = incomingByte;
386 BufferCnt++;
387 }
388 }
389 }
390
391private:
392 bool isNumber(char *input) {
393 for (uint16_t i = 0; input[i] != '\0'; i++) {
394 if (isalpha(input[i]))
395 return false;
396 }
397 return true;
398 }
399};
400
401#endif /* LIBRARIES_EASYCOMM_H_ */
Class that functions for easycomm 3 implementation.
Definition easycomm.h:33
bool isNumber(char *input)
Definition easycomm.h:392
void easycomm_proc()
Get the commands from RS485 and response to the client.
Definition easycomm.h:50
void easycomm_init()
Initialize the RS485 bus.
Definition easycomm.h:41
Class that functions for interacting with a RS485 transceiver.
Definition rs485.h:25
uint8_t available(void)
The number of chars/uint8_t that are available in RS485 buffer.
Definition rs485.h:75
void begin(uint16_t baudrate)
Initialize the RS485 transceiver.
Definition rs485.h:40
uint8_t read()
Read a char/uint8_t from RS485 bus.
Definition rs485.h:65
void print(String str)
Print a string to RS485 bus.
Definition rs485.h:52
void flush()
Waits for the transmission of outgoing serial data to complete.
Definition rs485.h:84
#define BUFFER_SIZE
Set the size of serial buffer.
Definition easycomm.h:23
#define BAUDRATE
Set the Baudrate of easycomm 3 protocol.
Definition easycomm.h:24
#define RS485_TX_TIME
Delay "t"ms to write in serial for RS485 implementation.
Definition easycomm.h:22
rs485 rs485(RS485_DIR, RS485_TX_TIME)
@ position
Definition globals.h:26
@ speed
Definition globals.h:26
_control control_az
Definition globals.h:51
_rotator rotator
Definition globals.h:57
_control control_el
Definition globals.h:54
#define RS485_DIR
Digital output, to set the direction of RS485 communication.
double setpoint_speed
Speed set point in deg/s.
Definition globals.h:34
double p
Definition globals.h:37
double setpoint
Position set point in deg.
Definition globals.h:33
double i
Definition globals.h:37
double d
Control gains.
Definition globals.h:37
double speed
Motor Rotation speed in deg/s.
Definition globals.h:32
double input
Motor Position feedback in deg.
Definition globals.h:30
uint16_t load
Motor Load in mA.
Definition globals.h:35
enum _rotator_error rotator_error
Rotator error.
Definition globals.h:42
int8_t inside_temperature
Inside Temperature.
Definition globals.h:45
bool switch_az
Definition globals.h:48
double park_el
Park position for both axis.
Definition globals.h:46
enum _control_mode control_mode
Control mode.
Definition globals.h:43
bool switch_el
End-stop vales.
Definition globals.h:48
double park_az
Definition globals.h:46
enum _rotator_status rotator_status
Rotator status.
Definition globals.h:41
bool homing_flag
Homing flag.
Definition globals.h:44