2 LX200 Astro - Physics Driver
3 Copyright (C) 2007 Markus Wildi
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;
10 version 2.1 of the License, or (at your option) any later version.
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.
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
39 #define LX200_TIMEOUT 5
42 #define MAX_LX200AP_PULSE_LEN 999
55 const struct timespec timeout = {0, 50000000L};
57 char temp_string[256];
67 "check_lx200ap_connection: not a valid file descriptor received");
71 for (i = 0; i < 2; i++)
77 "check_lx200ap_connection: unsuccessful write to telescope, %d", nbytes_write);
82 tcflush(
fd, TCIFLUSH);
85 temp_string[nbytes_read - 1] =
'\0';
88 nbytes_write, temp_string);
92 nanosleep(&timeout,
nullptr);
104 int nbytes_write = 0;
107 char temp_string[256];
111 const char *
cmd =
"#:GG#";
124 tcflush(
fd, TCIFLUSH);
129 if ((temp_string[0] ==
'A') || ((temp_string[0] ==
'0') && (temp_string[1] ==
'0')) || (temp_string[0] ==
'@'))
132 for (i = nbytes_read; i > 0; i--)
134 temp_string[i] = temp_string[i - 1];
136 temp_string[0] =
'-';
137 temp_string[nbytes_read + 1] =
'\0';
139 if (temp_string[1] ==
'A')
141 temp_string[1] =
'0';
142 switch (temp_string[2])
146 temp_string[2] =
'1';
150 temp_string[2] =
'2';
154 temp_string[2] =
'3';
158 temp_string[2] =
'4';
162 temp_string[2] =
'5';
171 else if (temp_string[1] ==
'0')
173 temp_string[1] =
'0';
174 temp_string[2] =
'6';
176 else if (temp_string[1] ==
'@')
178 temp_string[1] =
'0';
179 switch (temp_string[2])
183 temp_string[2] =
'7';
187 temp_string[2] =
'8';
191 temp_string[2] =
'9';
195 temp_string[2] =
'0';
198 temp_string[1] =
'1';
199 temp_string[2] =
'1';
203 temp_string[1] =
'1';
204 temp_string[2] =
'2';
220 temp_string[nbytes_read - 1] =
'\0';
237 while (az < 0) az += 360.0;
238 while (az > 360.0) az -= 360.0;
242 snprintf(
cmd,
sizeof(
cmd),
"#:Sz %03d*%02d:%02d#", h, m, s);
258 snprintf(
cmd,
sizeof(
cmd),
"#:Sa %s%02d*%02d:%02d#",
259 alt >= 0 ?
"+" :
"-", d, m, s);
277 snprintf(
cmd,
sizeof(
cmd),
"#:SG %s%02d:%02d:%02d#",
278 hours >= 0 ?
"+" :
"-", h, m, s);
286 const struct timespec timeout = {0, 10000000L};
288 int nbytes_write = 0;
291 const char *
cmd =
"#:CM#";
300 matchedObject[nbytes_read - 1] =
'\0';
305 nanosleep(&timeout,
nullptr);
307 tcflush(
fd, TCIFLUSH);
314 const struct timespec timeout = {0, 10000000L};
316 int nbytes_write = 0;
319 const char *
cmd =
"#:CMR#";
328 matchedObject[nbytes_read - 1] =
'\0';
333 nanosleep(&timeout,
nullptr);
335 tcflush(
fd, TCIFLUSH);
344 int nbytes_write = 0;
363 return sendAPCommand(
fd,
"#:pR#",
"selectAPPECState: Enabling PEC RECORD");
395 tcflush(
fd, TCIFLUSH);
398 response[nbytes_read - 1] =
'\0';
400 sscanf(response,
"%d", position);
413 return sendAPCommand(
fd,
"#:RC0#",
"selectAPMoveToRate: Setting move to rate to 12x");
415 return sendAPCommand(
fd,
"#:RC1#",
"selectAPMoveToRate: Setting move to rate to 64x");
417 return sendAPCommand(
fd,
"#:RC2#",
"selectAPMoveToRate: Setting move to rate to 600x");
419 return sendAPCommand(
fd,
"#:RC3#",
"selectAPMoveToRate: Setting move to rate to 1200x");
431 return sendAPCommand(
fd,
"#:RS0#",
"selectAPSlewRate: Setting slew to rate to index 0");
433 return sendAPCommand(
fd,
"#:RS1#",
"selectAPSlewRate: Setting slew to rate to index 1");
435 return sendAPCommand(
fd,
"#:RS2#",
"selectAPSlewRate: Setting slew to rate to index 2");
447 return sendAPCommand(
fd,
"#:RT2#",
"selectAPTrackingMode: Setting tracking mode to sidereal.");
449 return sendAPCommand(
fd,
"#:RT1#",
"selectAPTrackingMode: Setting tracking mode to solar.");
451 return sendAPCommand(
fd,
"#:RT0#",
"selectAPTrackingMode: Setting tracking mode to lunar.");
454 "selectAPTrackingMode: Setting tracking mode to Custom -- NOT IMPLEMENTED!.");
457 return sendAPCommand(
fd,
"#:RT9#",
"selectAPTrackingMode: Setting tracking mode to Zero.");
469 return sendAPCommand(
fd,
"#:RG0#",
"selectAPGuideRate: Setting guide to rate to 0.25x");
471 return sendAPCommand(
fd,
"#:RG1#",
"selectAPGuideRate: Setting guide to rate to 0.50x");
473 return sendAPCommand(
fd,
"#:RG2#",
"selectAPGuideRate: Setting guide to rate to 1.00x");
501 while (
ra < 0)
ra += 24.0;
502 while (
ra > 24.0)
ra -= 24.0;
506 snprintf(
cmd,
sizeof(
cmd),
"#:Sr %02d:%02d:%02d#", h, m, s);
520 snprintf(
cmd,
sizeof(
cmd),
"#:Sd %s%02d*%02d:%02d#",
521 dec >= 0 ?
"+" :
"-", d, m, s);
535 while (Long < 0) Long += 360.0;
536 while (Long > 360.0) Long -= 360.0;
539 snprintf(
cmd,
sizeof(
cmd),
"#:Sg %03d*%02d:%02d#", d, m, s);
554 snprintf(
cmd,
sizeof(
cmd),
"#:St %s%02d*%02d:%02d#",
555 Lat >= 0 ?
"+" :
"-", d, m, s);
570 int nbytes_written = 0;
577 snprintf(
cmd, 16,
"#:RR%c%03.4f#", sign, fabs(rate));
581 tcflush(
fd, TCIFLUSH);
599 response[nbytes_read] =
'\0';
602 tcflush(
fd, TCIFLUSH);
618 int nbytes_written = 0;
625 snprintf(
cmd, 16,
"#:RD%c%03.4f#", sign, fabs(rate));
630 tcflush(
fd, TCIFLUSH);
648 response[nbytes_read] =
'\0';
651 tcflush(
fd, TCIFLUSH);
673 sprintf(
cmd,
"#:Mn%03d#", duration_msec);
676 sprintf(
cmd,
"#:Ms%03d#", duration_msec);
679 sprintf(
cmd,
"#:Me%03d#", duration_msec);
682 sprintf(
cmd,
"#:Mw%03d#", duration_msec);
689 tcflush(
fd, TCIFLUSH);
695 return sendAPCommand(
fd,
"#:KA#",
"APParkMount: Sending park command.");
701 return sendAPCommand(
fd,
"#:PO#",
"APUnParkMount: Sending unpark command.");
714 return sendAPCommand(
fd,
"#:RG#",
"selectAPMoveToRate: Setting move to rate to GUIDE");
716 return sendAPCommand(
fd,
"#:RC0#",
"selectAPMoveToRate: Setting move to rate to 12x");
718 return sendAPCommand(
fd,
"#:RC1#",
"selectAPMoveToRate: Setting move to rate to 64x");
720 return sendAPCommand(
fd,
"#:RC2#",
"selectAPMoveToRate: Setting move to rate to 600x");
722 return sendAPCommand(
fd,
"#:RC3#",
"selectAPMoveToRate: Setting move to rate to 1200x");
739 return sendAPCommand(
fd,
"#:RC5#",
"selectAPMoveToRate: Setting center rate to 0.25x");
741 return sendAPCommand(
fd,
"#:RC6#",
"selectAPMoveToRate: Setting center rate to 0.5x");
743 return sendAPCommand(
fd,
"#:RC7#",
"selectAPMoveToRate: Setting center rate to 1.0x");
745 return sendAPCommand(
fd,
"#:RC0#",
"selectAPMoveToRate: Setting center rate to 12");
747 return sendAPCommand(
fd,
"#:RC1#",
"selectAPMoveToRate: Setting center rate to 64x");
749 return sendAPCommand(
fd,
"#:RC2#",
"selectAPMoveToRate: Setting center rate to 200x");
751 return sendAPCommand(
fd,
"#:RC3#",
"selectAPMoveToRate: Setting center rate to index 3");
753 return sendAPCommand(
fd,
"#:RC4#",
"selectAPMoveToRate: Setting center rate to index 4");
806 int nbytes_write = 0;
812 "getApStatusString: not a valid file descriptor received");
820 "getApStatusString: unsuccessful write to telescope, %d", nbytes_write);
825 tcflush(
fd, TCIFLUSH);
828 statusString[nbytes_read - 1] =
'\0';
831 nbytes_write, statusString);
847 const struct timespec timeout50ms = {0, 50000000L};
848 nanosleep(&timeout50ms,
nullptr);
853 const struct timespec timeout250ms = {0, 250000000L};
854 nanosleep(&timeout250ms,
nullptr);
863 char status_string[256];
865 if (res !=
TTY_OK)
return res;
867 *parkStatus = status_string[0];
868 *slewStatus = status_string[3];
881 if (strlen(statusString) < 11)
883 const char statusChar = statusString[10];
893 return "Low Power Supply";
896 return "Servo Fault";
898 return "CCW DEC or AE Limit";
900 return "CW DEC or AE Limit";
902 return "East RA or AE Limit";
904 return "West RA or AE Limit";
906 return "Kill Function issued";
915 return statusString[0] ==
'P';
920 return statusString[3] !=
'0';
926 if (strlen(statusString) >= 14)
928 switch (statusString[13])
975 bool complain =
false;
976 int nbytes_write = 0;
981 *clutchAware =
false;
986 "getApStatusString: not a valid file descriptor received");
994 "getApMountFeatures: unsuccessful write to telescope, %d", nbytes_write);
999 tcflush(
fd, TCIFLUSH);
1000 if (nbytes_read > 1)
1002 readBuffer[nbytes_read - 1] =
'\0';
1005 nbytes_write, readBuffer);
1007 if (sscanf(readBuffer,
"%d", &value) > 0)
1009 *hasEncoder = value & 4;
1010 *clutchAware = value & 128;
1023 bool hasEncoder =
false;
1024 bool clutchAware =
false;
1026 hasEncoder && clutchAware;
1040 int nbytes_write = 0;
1041 int nbytes_read = 0;
1048 "isAPInitialized: not a valid file descriptor received");
1056 "isAPInitialized: unsuccessful write to telescope, %d", nbytes_write);
1064 if (nbytes_read < 1)
1070 readBuffer[nbytes_read - 1] =
'\0';
1072 if (!strcmp(
"00:00.0", readBuffer))
1073 *isInitialized =
false;
1074 else if (!strcmp(
"00:00:00.0", readBuffer))
1075 *isInitialized =
false;
1077 *isInitialized =
true;
1079 tcflush(
fd, TCIFLUSH);
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
void getSexComponents(double value, int *d, int *m, int *s)
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Implementations for common driver routines.
#define DEBUGDEVICE(device, priority, msg)
#define DEBUGFDEVICE(device, priority, msg,...)
int selectAPMoveToRate(int fd, int moveToIndex)
char lx200ap_name[MAXINDIDEVICE]
bool apStatusParked(const char *statusString)
int check_lx200ap_connection(int fd)
int setAPUTCOffset(int fd, double hours)
int setAPSiteLatitude(int fd, double Lat)
int getAPWormPosition(int fd, int *position)
void set_lx200ap_name(const char *deviceName, unsigned int debug_level)
int setAPRATrackRate(int fd, double rate)
int apHomeAndSync(int fd)
int setAPObjectRA(int fd, double ra)
int APSyncCMR(int fd, char *matchedObject)
int setAPObjectAlt(int fd, double alt)
int swapAPButtons(int fd, int currentSwap)
int setAPObjectDEC(int fd, double dec)
int isAPInitialized(int fd, bool *isInitialized)
int APSendPulseCmd(int fd, int direction, int duration_msec)
const char * apMountStatus(const char *statusString)
int selectAPCenterRate(int fd, int centerIndex)
unsigned int AP_DBG_SCOPE
int selectAPSlewRate(int fd, int slewIndex)
int getApStatusString(int fd, char *statusString)
int check_lx200ap_status(int fd, char *parkStatus, char *slewStatus)
int APUnParkMount(int fd)
int selectAPPECState(int fd, int pecstate)
int selectAPGuideRate(int fd, int guideRate)
APRateTableState apRateTable(const char *statusString)
int getApStatusStringInternal(int fd, char *statusString, bool complain)
int setAPObjectAZ(int fd, double az)
int APSyncCM(int fd, char *matchedObject)
int getApMountFeatures(int fd, bool *hasEncoder, bool *clutchAware)
#define MAX_LX200AP_PULSE_LEN
int getAPUTCOffset(int fd, double *value)
int setAPDETrackRate(int fd, double rate)
bool apStatusSlewing(const char *statusString)
int setAPSiteLongitude(int fd, double Long)
int selectAPV2CenterRate(int fd, int centerIndex, APRateTableState rateTable)
int sendAPCommand(int fd, const char *cmd, const char *comment)
int selectAPTrackingMode(int fd, int trackMode)
#define AP_TRACKING_LUNAR
#define AP_TRACKING_CUSTOM
#define AP_TRACKING_SIDEREAL
#define AP_TRACKING_SOLAR
int setStandardProcedure(int fd, const char *data)