1 #if 0
2 LX200 Astro - Physics Driver
3 Copyright (C) 2007 Markus Wildi
4
5 This library is free software;
6 you can redistribute it and / or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation;
9 either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY;
14 without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library;
20 if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301 USA
22
23 #endif
24
25 #include <cmath>
26 #include "lx200apdriver.h"
27
28 #include "indicom.h"
29 #include "indilogger.h"
30 #include "lx200driver.h"
31
32 #include <cstring>
33 #include <unistd.h>
34
35 #ifndef _WIN32
36 #include <termios.h>
37 #endif
38
39 #define LX200_TIMEOUT 5 /* FD timeout in seconds */
40
41 // maximum guide pulse request to send to controller
42 #define MAX_LX200AP_PULSE_LEN 999
43
44 char lx200ap_name[MAXINDIDEVICE];
45 unsigned int AP_DBG_SCOPE;
46
set_lx200ap_name(const char * deviceName,unsigned int debug_level)47 void set_lx200ap_name(const char *deviceName, unsigned int debug_level)
48 {
49 strncpy(lx200ap_name, deviceName, MAXINDIDEVICE);
50 AP_DBG_SCOPE = debug_level;
51 }
52
check_lx200ap_connection(int fd)53 int check_lx200ap_connection(int fd)
54 {
55 const struct timespec timeout = {0, 50000000L};
56 int i = 0;
57 char temp_string[64];
58 int error_type;
59 int nbytes_write = 0;
60 int nbytes_read = 0;
61
62 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "Testing telescope's connection using #:GG#...");
63
64 if (fd <= 0)
65 {
66 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR,
67 "check_lx200ap_connection: not a valid file descriptor received");
68
69 return -1;
70 }
71 for (i = 0; i < 2; i++)
72 {
73 if ((error_type = tty_write_string(fd, "#:GG#", &nbytes_write)) != TTY_OK)
74 {
75 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR,
76 "check_lx200ap_connection: unsuccessful write to telescope, %d", nbytes_write);
77
78 return error_type;
79 }
80 tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
81 tcflush(fd, TCIFLUSH);
82 if (nbytes_read > 1)
83 {
84 temp_string[nbytes_read - 1] = '\0';
85
86 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "check_lx200ap_connection: received bytes %d, [%s]",
87 nbytes_write, temp_string);
88
89 return 0;
90 }
91 nanosleep(&timeout, nullptr);
92 }
93
94 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "check_lx200ap_connection: wrote, but nothing received.");
95
96 return -1;
97 }
getAPUTCOffset(int fd,double * value)98 int getAPUTCOffset(int fd, double *value)
99 {
100 int error_type;
101 int nbytes_write = 0;
102 int nbytes_read = 0;
103
104 char temp_string[16];
105
106 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:GG#");
107
108 if ((error_type = tty_write_string(fd, "#:GG#", &nbytes_write)) != TTY_OK)
109 return error_type;
110
111 if ((error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read)) != TTY_OK)
112 {
113 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "getAPUTCOffset: saying good bye %d, %d", error_type,
114 nbytes_read);
115 return error_type;
116 }
117
118 tcflush(fd, TCIFLUSH);
119
120 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "RES <%s>", temp_string);
121
122 /* Negative offsets, see AP keypad manual p. 77 */
123 if ((temp_string[0] == 'A') || ((temp_string[0] == '0') && (temp_string[1] == '0')) || (temp_string[0] == '@'))
124 {
125 int i;
126 for (i = nbytes_read; i > 0; i--)
127 {
128 temp_string[i] = temp_string[i - 1];
129 }
130 temp_string[0] = '-';
131 temp_string[nbytes_read + 1] = '\0';
132
133 if (temp_string[1] == 'A')
134 {
135 temp_string[1] = '0';
136 switch (temp_string[2])
137 {
138 case '5':
139
140 temp_string[2] = '1';
141 break;
142 case '4':
143
144 temp_string[2] = '2';
145 break;
146 case '3':
147
148 temp_string[2] = '3';
149 break;
150 case '2':
151
152 temp_string[2] = '4';
153 break;
154 case '1':
155
156 temp_string[2] = '5';
157 break;
158 default:
159 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "getAPUTCOffset: string not handled %s",
160 temp_string);
161 return -1;
162 break;
163 }
164 }
165 else if (temp_string[1] == '0')
166 {
167 temp_string[1] = '0';
168 temp_string[2] = '6';
169 }
170 else if (temp_string[1] == '@')
171 {
172 temp_string[1] = '0';
173 switch (temp_string[2])
174 {
175 case '9':
176
177 temp_string[2] = '7';
178 break;
179 case '8':
180
181 temp_string[2] = '8';
182 break;
183 case '7':
184
185 temp_string[2] = '9';
186 break;
187 case '6':
188
189 temp_string[2] = '0';
190 break;
191 case '5':
192 temp_string[1] = '1';
193 temp_string[2] = '1';
194 break;
195 case '4':
196
197 temp_string[1] = '1';
198 temp_string[2] = '2';
199 break;
200 default:
201 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "getAPUTCOffset: string not handled %s",
202 temp_string);
203 return -1;
204 break;
205 }
206 }
207 else
208 {
209 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "getAPUTCOffset: string not handled %s", temp_string);
210 }
211 }
212 else
213 {
214 temp_string[nbytes_read - 1] = '\0';
215 }
216
217 if (f_scansexa(temp_string, value))
218 {
219 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "getAPUTCOffset: unable to process %s", temp_string);
220 return -1;
221 }
222 return 0;
223 }
224
setAPObjectAZ(int fd,double az)225 int setAPObjectAZ(int fd, double az)
226 {
227 int h, m, s;
228 char temp_string[16];
229
230 getSexComponents(az, &h, &m, &s);
231
232 snprintf(temp_string, sizeof(temp_string), "#:Sz %03d*%02d:%02d#", h, m, s);
233
234 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
235
236 return (setStandardProcedure(fd, temp_string));
237 }
238
239 /* wildi Valid set Values are positive, add error condition */
240
setAPObjectAlt(int fd,double alt)241 int setAPObjectAlt(int fd, double alt)
242 {
243 int d, m, s;
244 char temp_string[16];
245
246 getSexComponents(alt, &d, &m, &s);
247
248 /* case with negative zero */
249 if (!d && alt < 0)
250 {
251 snprintf(temp_string, sizeof(temp_string), "#:Sa -%02d*%02d:%02d#", d, m, s);
252 }
253 else
254 {
255 snprintf(temp_string, sizeof(temp_string), "#:Sa %+02d*%02d:%02d#", d, m, s);
256 }
257
258 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
259
260 return (setStandardProcedure(fd, temp_string));
261 }
setAPUTCOffset(int fd,double hours)262 int setAPUTCOffset(int fd, double hours)
263 {
264 int h, m, s;
265
266 char temp_string[16];
267
268 getSexComponents(hours, &h, &m, &s);
269
270 snprintf(temp_string, sizeof(temp_string), "#:SG %+03d:%02d:%02d#", h, m, s);
271
272 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
273
274 return (setStandardProcedure(fd, temp_string));
275 }
APSyncCM(int fd,char * matchedObject)276 int APSyncCM(int fd, char *matchedObject)
277 {
278 const struct timespec timeout = {0, 10000000L};
279 int error_type;
280 int nbytes_write = 0;
281 int nbytes_read = 0;
282
283 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:CM#");
284
285 if ((error_type = tty_write_string(fd, "#:CM#", &nbytes_write)) != TTY_OK)
286 return error_type;
287
288 if ((error_type = tty_read_section(fd, matchedObject, '#', LX200_TIMEOUT, &nbytes_read)) != TTY_OK)
289 return error_type;
290
291 matchedObject[nbytes_read - 1] = '\0';
292
293 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "RES <%s>", matchedObject);
294
295 /* Sleep 10ms before flushing. This solves some issues with LX200 compatible devices. */
296 nanosleep(&timeout, nullptr);
297
298 tcflush(fd, TCIFLUSH);
299
300 return 0;
301 }
302
APSyncCMR(int fd,char * matchedObject)303 int APSyncCMR(int fd, char *matchedObject)
304 {
305 const struct timespec timeout = {0, 10000000L};
306 int error_type;
307 int nbytes_write = 0;
308 int nbytes_read = 0;
309
310 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:CMR#");
311
312 if ((error_type = tty_write_string(fd, "#:CMR#", &nbytes_write)) != TTY_OK)
313 return error_type;
314
315 /* read_ret = portRead(matchedObject, -1, LX200_TIMEOUT); */
316 if ((error_type = tty_read_section(fd, matchedObject, '#', LX200_TIMEOUT, &nbytes_read)) != TTY_OK)
317 return error_type;
318
319 matchedObject[nbytes_read - 1] = '\0';
320
321 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "RES <%s>", matchedObject);
322
323 /* Sleep 10ms before flushing. This solves some issues with LX200 compatible devices. */
324 nanosleep(&timeout, nullptr);
325
326 tcflush(fd, TCIFLUSH);
327
328 return 0;
329 }
330
selectAPPECState(int fd,int pecstate)331 int selectAPPECState(int fd, int pecstate)
332 {
333 int error_type;
334 int nbytes_write = 0;
335
336 switch (pecstate)
337 {
338 // PEC OFF
339 case 0:
340 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPPECState: Setting PEC OFF");
341 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:p#");
342
343 if ((error_type = tty_write_string(fd, "#:p#", &nbytes_write)) != TTY_OK)
344 return error_type;
345
346 break;
347
348 // PEC ON
349 case 1:
350 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPPECState: Setting PEC ON");
351 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:pP#");
352
353 if ((error_type = tty_write_string(fd, "#:pP#", &nbytes_write)) != TTY_OK)
354 return error_type;
355
356 break;
357
358 default:
359 return -1;
360 break;
361 }
362
363 return 0;
364 }
365
selectAPMoveToRate(int fd,int moveToRate)366 int selectAPMoveToRate(int fd, int moveToRate)
367 {
368 int error_type;
369 int nbytes_write = 0;
370
371 switch (moveToRate)
372 {
373 /* 12x*/
374 case 0:
375 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 12x");
376 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC0#");
377
378 if ((error_type = tty_write_string(fd, "#:RC0#", &nbytes_write)) != TTY_OK)
379 return error_type;
380 break;
381
382 /* 64x */
383 case 1:
384 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 64x");
385 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC1#");
386
387 if ((error_type = tty_write_string(fd, "#:RC1#", &nbytes_write)) != TTY_OK)
388 return error_type;
389 break;
390
391 /* 600x */
392 case 2:
393 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 600x");
394 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC2#");
395 if ((error_type = tty_write_string(fd, "#:RC2#", &nbytes_write)) != TTY_OK)
396 return error_type;
397 break;
398
399 /* 1200x */
400 case 3:
401 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 1200x");
402 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC3#");
403
404 if ((error_type = tty_write_string(fd, "#:RC3#", &nbytes_write)) != TTY_OK)
405 return error_type;
406 break;
407
408 default:
409 return -1;
410 break;
411 }
412 return 0;
413 }
414
selectAPSlewRate(int fd,int slewRate)415 int selectAPSlewRate(int fd, int slewRate)
416 {
417 int error_type;
418 int nbytes_write = 0;
419 switch (slewRate)
420 {
421 /* 600x */
422 case 0:
423
424 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPSlewRate: Setting slew to rate to 600x");
425 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RS0#");
426
427 if ((error_type = tty_write_string(fd, "#:RS0#", &nbytes_write)) != TTY_OK)
428 return error_type;
429 break;
430
431 /* 900x */
432 case 1:
433
434 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPSlewRate: Setting slew to rate to 900x");
435 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RS1#");
436
437 if ((error_type = tty_write_string(fd, "#:RS1#", &nbytes_write)) != TTY_OK)
438 return error_type;
439 break;
440
441
442 /* 1200x */
443 case 2:
444
445 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPSlewRate: Setting slew to rate to 1200x");
446 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RS2#");
447
448 if ((error_type = tty_write_string(fd, "#:RS2#", &nbytes_write)) != TTY_OK)
449 return error_type;
450 break;
451
452 default:
453 return -1;
454 break;
455 }
456 return 0;
457 }
458
selectAPTrackingMode(int fd,int trackMode)459 int selectAPTrackingMode(int fd, int trackMode)
460 {
461 int error_type;
462 int nbytes_write = 0;
463
464 switch (trackMode)
465 {
466 /* Sidereal */
467 case AP_TRACKING_SIDEREAL:
468
469 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG,
470 "selectAPTrackingMode: Setting tracking mode to sidereal.");
471 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RT2#");
472
473 if ((error_type = tty_write_string(fd, "#:RT2#", &nbytes_write)) != TTY_OK)
474 return error_type;
475 break;
476
477 /* Solar */
478 case AP_TRACKING_SOLAR:
479
480 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPTrackingMode: Setting tracking mode to solar.");
481 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RT1#");
482
483 if ((error_type = tty_write_string(fd, "#:RT1#", &nbytes_write)) != TTY_OK)
484 return error_type;
485 break;
486
487 /* Lunar */
488 case AP_TRACKING_LUNAR:
489
490 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPTrackingMode: Setting tracking mode to lunar.");
491 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RT0#");
492
493 if ((error_type = tty_write_string(fd, "#:RT0#", &nbytes_write)) != TTY_OK)
494 return error_type;
495 break;
496
497 case AP_TRACKING_CUSTOM:
498 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPTrackingMode: Setting tracking mode to Custom.");
499 break;
500
501 /* Zero */
502 case AP_TRACKING_OFF:
503
504 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPTrackingMode: Setting tracking mode to Zero.");
505 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RT9#");
506
507 if ((error_type = tty_write_string(fd, "#:RT9#", &nbytes_write)) != TTY_OK)
508 return error_type;
509 break;
510
511 default:
512 return -1;
513 break;
514 }
515 return 0;
516 }
517
selectAPGuideRate(int fd,int guideRate)518 int selectAPGuideRate(int fd, int guideRate)
519 {
520 int error_type;
521 int nbytes_write = 0;
522 switch (guideRate)
523 {
524 /* 0.25x */
525 case 0:
526
527 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPGuideRate: Setting guide to rate to 0.25x");
528 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RG0#");
529
530 if ((error_type = tty_write_string(fd, "#:RG0#", &nbytes_write)) != TTY_OK)
531 return error_type;
532 break;
533
534 /* 0.50x */
535 case 1:
536
537 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPGuideRate: Setting guide to rate to 0.50x");
538 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RG1#");
539
540 if ((error_type = tty_write_string(fd, "#:RG1#", &nbytes_write)) != TTY_OK)
541 return error_type;
542 break;
543
544
545 /* 1.00x */
546 case 2:
547
548 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPGuideRate: Setting guide to rate to 1.00x");
549 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RG2#");
550
551 if ((error_type = tty_write_string(fd, "#:RG2#", &nbytes_write)) != TTY_OK)
552 return error_type;
553 break;
554
555 default:
556 return -1;
557 break;
558 }
559 return 0;
560 }
561
swapAPButtons(int fd,int currentSwap)562 int swapAPButtons(int fd, int currentSwap)
563 {
564 int error_type;
565 int nbytes_write = 0;
566
567 switch (currentSwap)
568 {
569 case 0:
570
571 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:NS#");
572 if ((error_type = tty_write_string(fd, "#:NS#", &nbytes_write)) != TTY_OK)
573 return error_type;
574 break;
575
576 case 1:
577 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:EW#");
578 if ((error_type = tty_write_string(fd, "#:EW#", &nbytes_write)) != TTY_OK)
579 return error_type;
580 break;
581
582 default:
583 return -1;
584 break;
585 }
586 return 0;
587 }
588
setAPObjectRA(int fd,double ra)589 int setAPObjectRA(int fd, double ra)
590 {
591 /*ToDo AP accepts "#:Sr %02d:%02d:%02d.%1d#"*/
592 int h, m, s;
593 char temp_string[16];
594
595 getSexComponents(ra, &h, &m, &s);
596
597 snprintf(temp_string, sizeof(temp_string), "#:Sr %02d:%02d:%02d#", h, m, s);
598
599 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
600
601 return (setStandardProcedure(fd, temp_string));
602 }
603
setAPObjectDEC(int fd,double dec)604 int setAPObjectDEC(int fd, double dec)
605 {
606 int d, m, s;
607 char temp_string[16];
608
609 getSexComponents(dec, &d, &m, &s);
610 /* case with negative zero */
611 if (!d && dec < 0)
612 {
613 snprintf(temp_string, sizeof(temp_string), "#:Sd -%02d*%02d:%02d#", d, m, s);
614 }
615 else
616 {
617 snprintf(temp_string, sizeof(temp_string), "#:Sd %+03d*%02d:%02d#", d, m, s);
618 }
619
620 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
621
622 return (setStandardProcedure(fd, temp_string));
623 }
624
setAPSiteLongitude(int fd,double Long)625 int setAPSiteLongitude(int fd, double Long)
626 {
627 int d, m, s;
628 char temp_string[32];
629
630 getSexComponents(Long, &d, &m, &s);
631 snprintf(temp_string, sizeof(temp_string), "#:Sg %03d*%02d:%02d#", d, m, s);
632
633 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
634
635 return (setStandardProcedure(fd, temp_string));
636 }
637
setAPSiteLatitude(int fd,double Lat)638 int setAPSiteLatitude(int fd, double Lat)
639 {
640 int d, m, s;
641 char temp_string[32];
642
643 getSexComponents(Lat, &d, &m, &s);
644 snprintf(temp_string, sizeof(temp_string), "#:St %+03d*%02d:%02d#", d, m, s);
645
646 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", temp_string);
647
648 return (setStandardProcedure(fd, temp_string));
649 }
650
setAPRATrackRate(int fd,double rate)651 int setAPRATrackRate(int fd, double rate)
652 {
653 char cmd[16];
654 char sign;
655 int errcode = 0;
656 char errmsg[MAXRBUF];
657 char response[8];
658 int nbytes_read = 0;
659 int nbytes_written = 0;
660
661 if (rate < 0)
662 sign = '-';
663 else
664 sign = '+';
665
666 snprintf(cmd, 16, ":RR%c%03.4f#", sign, fabs(rate));
667
668 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "CMD (%s)", cmd);
669
670 tcflush(fd, TCIFLUSH);
671
672 if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
673 {
674 tty_error_msg(errcode, errmsg, MAXRBUF);
675 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "%s", errmsg);
676 return errcode;
677 }
678
679 if ((errcode = tty_read(fd, response, 1, LX200_TIMEOUT, &nbytes_read)))
680 {
681 tty_error_msg(errcode, errmsg, MAXRBUF);
682 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "%s", errmsg);
683 return errcode;
684 }
685
686 if (nbytes_read > 0)
687 {
688 response[nbytes_read] = '\0';
689 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "RES (%s)", response);
690
691 tcflush(fd, TCIFLUSH);
692 return 0;
693 }
694
695 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
696 return -1;
697 }
698
setAPDETrackRate(int fd,double rate)699 int setAPDETrackRate(int fd, double rate)
700 {
701 char cmd[16];
702 char sign;
703 int errcode = 0;
704 char errmsg[MAXRBUF];
705 char response[8];
706 int nbytes_read = 0;
707 int nbytes_written = 0;
708
709 if (rate < 0)
710 sign = '-';
711 else
712 sign = '+';
713
714 snprintf(cmd, 16, ":RD%c%03.4f#", sign, fabs(rate));
715
716 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "CMD (%s)", cmd);
717
718
719 tcflush(fd, TCIFLUSH);
720
721 if ((errcode = tty_write(fd, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
722 {
723 tty_error_msg(errcode, errmsg, MAXRBUF);
724 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "%s", errmsg);
725 return errcode;
726 }
727
728 if ((errcode = tty_read(fd, response, 1, LX200_TIMEOUT, &nbytes_read)))
729 {
730 tty_error_msg(errcode, errmsg, MAXRBUF);
731 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "%s", errmsg);
732 return errcode;
733 }
734
735 if (nbytes_read > 0)
736 {
737 response[nbytes_read] = '\0';
738 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "RES (%s)", response);
739
740 tcflush(fd, TCIFLUSH);
741 return 0;
742 }
743
744 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
745 return -1;
746 }
747
APSendPulseCmd(int fd,int direction,int duration_msec)748 int APSendPulseCmd(int fd, int direction, int duration_msec)
749 {
750 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "<%s>", __FUNCTION__);
751 int nbytes_write = 0;
752 char cmd[20];
753
754 // GTOCP3 supports 3 digits for msec duration
755 if (duration_msec > MAX_LX200AP_PULSE_LEN)
756 {
757 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "APSendPulseCmd requested %d msec limited to 999 msec!", duration_msec);
758 duration_msec = 999;
759 }
760
761 switch (direction)
762 {
763 case LX200_NORTH:
764 sprintf(cmd, ":Mn%03d#", duration_msec);
765 break;
766 case LX200_SOUTH:
767 sprintf(cmd, ":Ms%03d#", duration_msec);
768 break;
769 case LX200_EAST:
770 sprintf(cmd, ":Me%03d#", duration_msec);
771 break;
772 case LX200_WEST:
773 sprintf(cmd, ":Mw%03d#", duration_msec);
774 break;
775 default:
776 return 1;
777 }
778
779 DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", cmd);
780
781 tty_write_string(fd, cmd, &nbytes_write);
782
783 tcflush(fd, TCIFLUSH);
784 return 0;
785 }
786
787 #if 0
788 // experimental function!!!
789 int check_lx200ap_status(int fd, char *parkStatus, char *slewStatus)
790 {
791 char temp_string[64];
792 int error_type;
793 int nbytes_write = 0;
794 int nbytes_read = 0;
795
796 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "EXPERIMENTAL: check status...");
797
798 if (fd <= 0)
799 {
800 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR,
801 "check_lx200ap_connection: not a valid file descriptor received");
802
803 return -1;
804 }
805
806 if ((error_type = tty_write_string(fd, "#:GOS#", &nbytes_write)) != TTY_OK)
807 {
808 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR,
809 "check_lx200ap_connection: unsuccessful write to telescope, %d", nbytes_write);
810
811 return error_type;
812 }
813 tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
814 tcflush(fd, TCIFLUSH);
815 if (nbytes_read > 1)
816 {
817 temp_string[nbytes_read - 1] = '\0';
818
819 DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "check_lx200ap_status: received bytes %d, [%s]",
820 nbytes_write, temp_string);
821
822 *parkStatus = temp_string[0];
823 *slewStatus = temp_string[3];
824
825 return 0;
826 }
827
828
829 DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "check_lx200ap_status: wrote, but nothing received.");
830
831 return -1;
832 }
833 #endif
834