Instrument Neutral Distributed Interface INDI  1.9.5
lx200apdriver.cpp
Go to the documentation of this file.
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 
45 unsigned int AP_DBG_SCOPE;
46 
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 
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  {
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  {
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 }
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 
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 
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 }
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 }
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 
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 
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 
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 
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 
459 int selectAPTrackingMode(int fd, int trackMode)
460 {
461  int error_type;
462  int nbytes_write = 0;
463 
464  switch (trackMode)
465  {
466  /* Sidereal */
468 
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 
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 
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 
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 
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 
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 
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 
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 
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);
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);
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 
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 
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);
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);
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 
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  {
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  {
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 
835 // make this a function with logging instead of a #define like in legacy driver
836 int APParkMount(int fd)
837 {
838  int error_type;
839  int nbytes_write = 0;
840 
841  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "APParkMount: Sending park command.");
842  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:KA");
843 
844  if ((error_type = tty_write_string(fd, "#:KA", &nbytes_write)) != TTY_OK)
845  return error_type;
846 
847  return 0;
848 }
849 
850 // make this a function with logging instead of a #define like in legacy driver
852 {
853  int error_type;
854  int nbytes_write = 0;
855 
856  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "APUnParkMount: Sending unpark command.");
857  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:PO");
858 
859  if ((error_type = tty_write_string(fd, "#:PO", &nbytes_write)) != TTY_OK)
860  return error_type;
861 
862  return 0;
863 }
864 
865 // This is a modified version of selectAPMoveRate() from lx200apdriver.cpp
866 // This version allows changing the rate to GUIDE as well as 12x/64x/600x/1200x
867 // and is required some the experimental AP driver properly handles
868 // pulse guide requests over 999ms by simulated it by setting the move rate
869 // to GUIDE and then starting and halting a move of the correct duration.
870 int selectAPCenterRate(int fd, int centerRate)
871 {
872  int error_type;
873  int nbytes_write = 0;
874 
875  switch (centerRate)
876  {
877  /* Guide */
878  case 0:
879  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to GUIDE");
880  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RG#");
881 
882  if ((error_type = tty_write_string(fd, "#:RG#", &nbytes_write)) != TTY_OK)
883  return error_type;
884  break;
885 
886  /* 12x */
887  case 1:
888  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 12x");
889  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC0#");
890 
891  if ((error_type = tty_write_string(fd, "#:RC0#", &nbytes_write)) != TTY_OK)
892  return error_type;
893  break;
894 
895  /* 64x */
896  case 2:
897  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 64x");
898  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC1#");
899 
900  if ((error_type = tty_write_string(fd, "#:RC1#", &nbytes_write)) != TTY_OK)
901  return error_type;
902  break;
903 
904  /* 600x */
905  case 3:
906  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 600x");
907  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC2#");
908  if ((error_type = tty_write_string(fd, "#:RC2#", &nbytes_write)) != TTY_OK)
909  return error_type;
910  break;
911 
912  /* 1200x */
913  case 4:
914  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "selectAPMoveToRate: Setting move to rate to 1200x");
915  DEBUGFDEVICE(lx200ap_name, AP_DBG_SCOPE, "CMD <%s>", "#:RC3#");
916 
917  if ((error_type = tty_write_string(fd, "#:RC3#", &nbytes_write)) != TTY_OK)
918  return error_type;
919  break;
920 
921  default:
922  return -1;
923  break;
924  }
925  return 0;
926 }
927 
928 // experimental functions!!!
929 
930 
931 int check_lx200ap_status(int fd, char *parkStatus, char *slewStatus)
932 {
933  char temp_string[64];
934  int error_type;
935  int nbytes_write = 0;
936  int nbytes_read = 0;
937 
938  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "Check status...");
939 
940  if (fd <= 0)
941  {
943  "check_lx200ap_connection: not a valid file descriptor received");
944 
945  return -1;
946  }
947 
948  if ((error_type = tty_write_string(fd, "#:GOS#", &nbytes_write)) != TTY_OK)
949  {
951  "check_lx200ap_connection: unsuccessful write to telescope, %d", nbytes_write);
952 
953  return error_type;
954  }
955  tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read);
956  tcflush(fd, TCIFLUSH);
957  if (nbytes_read > 1)
958  {
959  temp_string[nbytes_read - 1] = '\0';
960 
961  DEBUGFDEVICE(lx200ap_name, INDI::Logger::DBG_DEBUG, "check_lx200ap_status: received bytes %d, [%s]",
962  nbytes_write, temp_string);
963 
964  *parkStatus = temp_string[0];
965  *slewStatus = temp_string[3];
966 
967  return 0;
968  }
969 
970  DEBUGDEVICE(lx200ap_name, INDI::Logger::DBG_ERROR, "check_lx200ap_status: wrote, but nothing received.");
971 
972  return -1;
973 }
MAXINDIDEVICE
#define MAXINDIDEVICE
Definition: indiapi.h:192
cmd
__u8 cmd[4]
Definition: pwc-ioctl.h:4
fd
int fd
Definition: indiserver.c:117
Aux::ANY
@ ANY
Definition: celestronauxpacket.h:86
check_lx200ap_connection
int check_lx200ap_connection(int fd)
Definition: lx200apdriver.cpp:53
indicom.h
Implementations for common driver routines.
selectAPGuideRate
int selectAPGuideRate(int fd, int guideRate)
Definition: lx200apdriver.cpp:518
getSexComponents
void getSexComponents(double value, int *d, int *m, int *s)
Definition: indicom.c:250
f_scansexa
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double.
Definition: indicom.c:201
selectAPSlewRate
int selectAPSlewRate(int fd, int slewRate)
Definition: lx200apdriver.cpp:415
lx200apdriver.h
INDI::Logger::DBG_ERROR
@ DBG_ERROR
Definition: indilogger.h:192
LX200_NORTH
@ LX200_NORTH
Definition: lx200driver.h:41
AP_TRACKING_CUSTOM
#define AP_TRACKING_CUSTOM
Definition: lx200apdriver.h:35
LX200_WEST
@ LX200_WEST
Definition: lx200driver.h:42
setAPObjectAZ
int setAPObjectAZ(int fd, double az)
Definition: lx200apdriver.cpp:225
lx200driver.h
tty_read_section
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:557
AP_TRACKING_LUNAR
#define AP_TRACKING_LUNAR
Definition: lx200apdriver.h:34
selectAPMoveToRate
int selectAPMoveToRate(int fd, int moveToRate)
Definition: lx200apdriver.cpp:366
setAPRATrackRate
int setAPRATrackRate(int fd, double rate)
Definition: lx200apdriver.cpp:651
setAPObjectDEC
int setAPObjectDEC(int fd, double dec)
Definition: lx200apdriver.cpp:604
DEBUGDEVICE
#define DEBUGDEVICE(device, priority, msg)
Definition: indilogger.h:60
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
LX200_EAST
@ LX200_EAST
Definition: lx200driver.h:43
MAX_LX200AP_PULSE_LEN
#define MAX_LX200AP_PULSE_LEN
Definition: lx200apdriver.cpp:42
tty_error_msg
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1156
INDI::Logger::DBG_DEBUG
@ DBG_DEBUG
Definition: indilogger.h:195
indilogger.h
tty_read
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
Definition: indicom.c:473
setAPObjectAlt
int setAPObjectAlt(int fd, double alt)
Definition: lx200apdriver.cpp:241
ra
double ra
Definition: ieqprolegacydriver.cpp:43
AP_DBG_SCOPE
unsigned int AP_DBG_SCOPE
Definition: lx200apdriver.cpp:45
tty_write
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:415
AP_TRACKING_SIDEREAL
#define AP_TRACKING_SIDEREAL
Definition: lx200apdriver.h:32
selectAPPECState
int selectAPPECState(int fd, int pecstate)
Definition: lx200apdriver.cpp:331
dec
double dec
Definition: ieqprolegacydriver.cpp:44
setStandardProcedure
int setStandardProcedure(int fd, const char *writeData)
Definition: lx200driver.cpp:821
AP_TRACKING_OFF
#define AP_TRACKING_OFF
Definition: lx200apdriver.h:36
APUnParkMount
int APUnParkMount(int fd)
Definition: lx200apdriver.cpp:851
selectAPTrackingMode
int selectAPTrackingMode(int fd, int trackMode)
Definition: lx200apdriver.cpp:459
setAPObjectRA
int setAPObjectRA(int fd, double ra)
Definition: lx200apdriver.cpp:589
selectAPCenterRate
int selectAPCenterRate(int fd, int centerRate)
Definition: lx200apdriver.cpp:870
DEBUGFDEVICE
#define DEBUGFDEVICE(device, priority, msg,...)
Definition: indilogger.h:61
setAPSiteLatitude
int setAPSiteLatitude(int fd, double Lat)
Definition: lx200apdriver.cpp:638
lx200ap_name
char lx200ap_name[MAXINDIDEVICE]
Definition: lx200apdriver.cpp:44
getAPUTCOffset
int getAPUTCOffset(int fd, double *value)
Definition: lx200apdriver.cpp:98
setAPSiteLongitude
int setAPSiteLongitude(int fd, double Long)
Definition: lx200apdriver.cpp:625
APSyncCMR
int APSyncCMR(int fd, char *matchedObject)
Definition: lx200apdriver.cpp:303
LX200_SOUTH
@ LX200_SOUTH
Definition: lx200driver.h:44
set_lx200ap_name
void set_lx200ap_name(const char *deviceName, unsigned int debug_level)
Definition: lx200apdriver.cpp:47
setAPUTCOffset
int setAPUTCOffset(int fd, double hours)
Definition: lx200apdriver.cpp:262
LX200_TIMEOUT
#define LX200_TIMEOUT
Definition: lx200apdriver.cpp:39
check_lx200ap_status
int check_lx200ap_status(int fd, char *parkStatus, char *slewStatus)
Definition: lx200apdriver.cpp:931
swapAPButtons
int swapAPButtons(int fd, int currentSwap)
Definition: lx200apdriver.cpp:562
setAPDETrackRate
int setAPDETrackRate(int fd, double rate)
Definition: lx200apdriver.cpp:699
APSyncCM
int APSyncCM(int fd, char *matchedObject)
Definition: lx200apdriver.cpp:276
tty_write_string
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Definition: indicom.c:465
TTY_OK
@ TTY_OK
Definition: indicom.h:94
AP_TRACKING_SOLAR
#define AP_TRACKING_SOLAR
Definition: lx200apdriver.h:33
APParkMount
int APParkMount(int fd)
Definition: lx200apdriver.cpp:836
APSendPulseCmd
int APSendPulseCmd(int fd, int direction, int duration_msec)
Definition: lx200apdriver.cpp:748