30 #include <libnova/julian_day.h>
38 #define CELESTRON_TIMEOUT 5
47 angle = angle - 360 * floor(angle / 360);
51 if ((angle > 90.) && (angle <= 270.))
53 else if ((angle > 270.) && (angle <= 360.))
62 angle = angle - 360 * floor(angle / 360);
66 return static_cast<uint16_t
>(angle * 0x10000 / 360.0);
72 angle = angle - 360 * floor(angle / 360);
76 return static_cast<uint32_t
>(angle * 0x100000000 / 360.0);
82 return 360.0 * (
static_cast<double>(value) / 0x10000);
88 return 360.0 * (
static_cast<double>(value) / 0x100000000);
91 void hex_dump(
char *buf,
const char *data,
size_t size)
93 for (
size_t i = 0; i < size; i++)
94 sprintf(buf + 3 * i,
"%02X ", data[i]);
97 buf[3 * size - 1] =
'\0';
114 tcflush(
fd, TCIOFLUSH);
138 vsprintf(response, fmt, args);
148 size_t resp_len,
bool ascii_cmd,
bool ascii_resp)
151 size_t nbytes = resp_len;
164 if (!simulation &&
fd)
168 if ((err = serial_write(
cmd,
static_cast<int>(cmd_len),
reinterpret_cast<int *
>(&nbytes))) !=
TTY_OK)
178 err = serial_read_section(
'#',
reinterpret_cast<int *
>(&nbytes));
181 err = serial_read(
static_cast<int>(resp_len),
reinterpret_cast<int *
>(&nbytes));
183 while (err ==
TTY_OK && resp[nbytes - 1] !=
'#')
204 if (nbytes != resp_len)
206 size_t max = nbytes > resp_len ? nbytes : resp_len;
208 LOGF_DEBUG(
"Received %d bytes, expected %d <%s>", nbytes, resp_len, hexbuf);
214 LOG_DEBUG(
"resp_len 0, no response expected");
235 size_t payload_len,
char *resp,
size_t response_len)
240 cmd[1] =
static_cast<char>(payload_len + 1);
241 cmd[2] =
static_cast<char>(dest);
242 cmd[3] =
static_cast<char>(cmd_id);
243 cmd[7] =
static_cast<char>(response_len);
246 memcpy(
cmd + 4, payload, payload_len);
248 return send_command(
cmd, 8, resp, response_len + 1,
false,
false);
253 LOG_DEBUG(
"Initializing Celestron using Kx CMD...");
255 for (
int i = 0; i < 2; i++)
268 char version[8], model[16], RAVersion[8], DEVersion[8];
273 LOG_DEBUG(
"Getting controller version...");
274 if (!get_version(version, 8))
279 LOG_DEBUG(
"Getting controller variant...");
293 LOG_DEBUG(
"Getting controller model...");
294 if (!get_model(model, 16, &isGem, &canPec, &hasHomeIndex))
303 info->
Model =
"Unknown";
316 LOG_DEBUG(
"Getting RA firmware version...");
321 LOG_DEBUG(
"Getting DEC firmware version...");
330 LOGF_DEBUG(
"Firmware Info HC Ver %s model %s %s %s mount, HW Ver %s",
334 info->
isGem ?
"GEM" :
"Fork",
342 set_sim_response(
"x#");
344 if (!send_command(
"Kx", 2, response, 2,
true,
true))
347 return !strcmp(response,
"x#");
352 set_sim_response(
"\x04\x29#");
354 if (!send_command(
"V", 1, response, 3,
true,
false))
357 snprintf(version, size,
"%d.%02d",
static_cast<uint8_t
>(response[0]),
static_cast<uint8_t
>(response[1]));
359 LOGF_INFO(
"Controller version: %s", version);
366 set_sim_response(
"\x11#");
368 if (!send_command(
"v", 1, response, 2,
true,
false))
371 *variant =
static_cast<uint8_t
>(response[0]);
377 set_sim_response(
"%c#", 20);
378 if (!send_command(
"m", 1, response, 2,
true,
false))
381 return static_cast<uint8_t
>(response[0]);
387 std::map<int, std::string> models =
415 set_sim_response(
"\x14#");
422 if (models.find(m) != models.end())
424 strncpy(model, models[m].c_str(), size);
429 strncpy(model,
"Unknown", size);
430 LOGF_WARN(
"Unrecognized model (%d).", model);
471 *hasHomeIndex = (m == 23 || m == 24);
473 LOGF_DEBUG(
"get_model %s, %s mount, %s, %s", model, *isGem ?
"GEM" :
"Fork", *canPec ?
"has PEC" :
"no PEC",
474 *hasHomeIndex ?
"has home indexes" :
"no home indexes");
481 set_sim_response(
"\x06\x10#");
483 size_t rlen = send_passthrough(dev,
GET_VER,
nullptr, 0, response, 2);
488 snprintf(version, size,
"%01d.0",
static_cast<uint8_t
>(response[0]));
491 snprintf(version, size,
"%d.%02d",
static_cast<uint8_t
>(response[0]),
static_cast<uint8_t
>(response[1]));
535 payload[1] = duration_csec;
537 set_sim_response(
"#");
538 return send_passthrough(dev,
MTR_AUX_GUIDE, payload, 2, response, 0);
562 set_sim_response(
"%c#", 0);
567 return static_cast<bool>(response[0]);
582 set_sim_response(
"%c#", sim_ra_guide_rate);
586 set_sim_response(
"%c#", sim_dec_guide_rate);
591 *rate =
static_cast<uint8_t
>(response[0]);
592 LOGF_DEBUG(
"get_guide_rate raw response (0-255) %i", *rate);
608 sim_ra_guide_rate = rate;
612 sim_dec_guide_rate = rate;
617 set_sim_response(
"#");
626 payload[0] = rate + 1;
628 set_sim_response(
"#");
629 return send_passthrough(dev, cmd_id, payload, 1, response, 0);
635 char payload[] = { 0 };
637 set_sim_response(
"#");
638 return send_passthrough(dev,
MC_MOVE_POS, payload, 1, response, 0);
643 set_sim_response(
"#");
644 return send_command(
"M", 1, response, 1,
true,
true);
649 char RAStr[16], DecStr[16];
653 LOGF_DEBUG(
"Goto RA-DEC(%s,%s)", RAStr, DecStr);
655 set_sim_slewing(
true);
663 set_sim_response(
"#");
664 return send_command(
cmd, strlen(
cmd), response, 1,
true,
true);
669 char AzStr[16], AltStr[16];
673 LOGF_DEBUG(
"Goto AZM-ALT (%s,%s)", AzStr, AltStr);
675 set_sim_slewing(
true);
683 set_sim_response(
"#");
684 return send_command(
cmd, strlen(
cmd), response, 1,
true,
true);
689 char RAStr[16], DecStr[16];
704 set_sim_response(
"#");
705 return send_command(
cmd, strlen(
cmd), response, 1,
true,
true);
712 set_sim_response(
"#");
713 return send_command(
"u", 1, response, 1,
true,
true);
718 uint32_t d1_int = 0, d2_int = 0;
720 sscanf(response,
"%x,%x#", &d1_int, &d2_int);
738 set_sim_response(
"%08X,%08X#",
dd2pnex(sim_data.ra * 15),
dd2pnex(sim_data.dec));
740 if (!send_command(
"e", 1, response, 18,
true,
true))
745 set_sim_response(
"%04X,%04X#",
dd2nex(sim_data.ra * 15),
dd2nex(sim_data.dec));
747 if (!send_command(
"E", 1, response, 10,
true,
true))
755 char RAStr[16], DecStr[16];
767 set_sim_response(
"%08X,%08X#",
dd2pnex(sim_data.az),
dd2pnex(sim_data.alt));
769 if (!send_command(
"z", 1, response, 18,
true,
true))
774 set_sim_response(
"%04X,%04X#",
dd2nex(sim_data.az),
dd2nex(sim_data.alt));
776 if (!send_command(
"Z", 1, response, 10,
true,
true))
782 char AzStr[16], AltStr[16];
784 fs_sexa(AltStr, *alt, 2, 3600);
785 LOGF_EXTRA1(
"RES <%s> ==> AZM-ALT (%s,%s)", response, AzStr, AltStr);
791 LOGF_DEBUG(
"Setting location (%.3f,%.3f)", longitude, latitude);
797 int lat_d, lat_m, lat_s;
798 int long_d, long_m, long_s;
804 cmd[1] =
static_cast<char>(abs(lat_d));
805 cmd[2] =
static_cast<char>(lat_m);
806 cmd[3] =
static_cast<char>(lat_s);
807 cmd[4] = lat_d > 0 ? 0 : 1;
808 cmd[5] =
static_cast<char>(abs(
810 cmd[6] =
static_cast<char>(long_m);
811 cmd[7] =
static_cast<char>(long_s);
812 cmd[8] = longitude > 0 ? 0 : 1;
814 set_sim_response(
"#");
815 return send_command(
cmd, 9, response, 1,
false,
true);
821 set_sim_response(
"%c%c%c%c%c%c%c%c#", 51, 36, 17, 0, 0, 43, 3, 1);
823 if (!send_command(
"w", 1, response, 9,
true,
false))
826 *latitude = response[0];
827 *latitude += response[1] / 60.0;
828 *latitude += response[2] / 3600.0;
829 if (response[3] != 0)
830 *latitude = -*latitude;
832 *longitude = response[4];
833 *longitude += response[5] / 60.0;
834 *longitude += response[6] / 3600.0;
836 *longitude = -*longitude;
848 struct ln_zonedate local_date;
851 ln_date_to_zonedate(utc, &local_date,
static_cast<int>(utc_offset * 3600));
855 cmd[1] =
static_cast<char>(local_date.hours);
856 cmd[2] =
static_cast<char>(local_date.minutes);
857 cmd[3] =
static_cast<char>(local_date.seconds);
858 cmd[4] =
static_cast<char>(local_date.months);
859 cmd[5] =
static_cast<char>(local_date.days);
860 cmd[6] =
static_cast<char>(local_date.years - 2000);
862 int utc_int =
static_cast<int>(utc_offset);
871 cmd[7] =
static_cast<char>(utc_int & 0xFF);
874 cmd[8] = dst ? 1 : 0;
876 set_sim_response(
"#");
877 return send_command(
cmd, 9, response, 1,
false,
true);
881 int *dd,
int *hh,
int *minute,
int *ss,
bool* dst,
bool precise)
887 time_t now = time(
nullptr);
888 tm *ltm = localtime(&now);
890 set_sim_response(
"%c%c%c%c%c%c%c%c#",
891 ltm->tm_hour, ltm->tm_min, ltm->tm_sec,
892 ltm->tm_mon, ltm->tm_mday, ltm->tm_year - 100,
893 precise ? ltm->tm_gmtoff / 900 : ltm->tm_gmtoff / 3600, ltm->tm_isdst);
898 if (!send_command(precise ?
"i" :
"h", 1, response, 9,
true,
false))
902 ln_zonedate localTime;
906 localTime.hours = response[0];
907 localTime.minutes = response[1];
908 localTime.seconds = response[2];
909 localTime.months = response[3];
910 localTime.days = response[4];
911 localTime.years = 2000 + response[5];
912 int gmtoff = response[6];
913 *dst = response[7] != 0;
922 *utc_hours = gmtoff / 4;
923 localTime.gmtoff = gmtoff * 900;
928 localTime.gmtoff = gmtoff * 3600;
934 localTime.gmtoff += 3600;
942 ln_zonedate_to_date(&localTime, &utcTime);
945 *mm = utcTime.months;
948 *minute = utcTime.minutes;
949 *ss =
static_cast<int>(utcTime.seconds);
958 set_sim_response(
"%d#", sim_data.isSlewing);
960 if (!send_command(
"L", 1, response, 2,
true,
true))
963 *slewing = response[0] !=
'0';
969 set_sim_response(
"\02#");
971 if (!send_command(
"t", 1, response, 2,
true,
false))
981 sprintf(
cmd,
"T%c", mode);
982 set_sim_response(
"#");
984 return send_command(
cmd, 2, response, 1,
false,
true);
989 set_sim_response(
"#");
990 return send_command(
"x", 1, response, 1,
true,
true);
996 set_sim_response(
"#");
997 return send_command(
"y", 1, response, 1,
true,
true);
1003 set_sim_response(
"#");
1004 return send_command(
"Y", 1, response, 1,
true,
true);
1018 bool atDecIndex = response[0] !=
'\00';
1021 bool atRaIndex = response[0] !=
'\00';
1022 *atIndex = atDecIndex && atRaIndex;
1029 set_sim_response(
"W#");
1031 if (!send_command(
"p", 1, response, 2,
true,
true))
1033 *side_of_pier = response[0];
1042 set_sim_response(
"\x01#");
1043 if (!send_command(
"J", 1, response, 2,
true,
false))
1046 *isAligned = response[0] == 0x01;
1052 set_sim_response(
"#");
1065 char payload[] = {
static_cast<char>(rate >> 8 & 0xff),
static_cast<char>(rate & 0xff)};
1073 char focVersion[16];
1081 snprintf(focVersion, 15,
"%d.%02d",
static_cast<uint8_t
>(response[0]),
static_cast<uint8_t
>(response[1]));
1082 vernum = (
static_cast<uint8_t
>(response[0]) << 24) + (
static_cast<uint8_t
>(response[1]) << 16);
1086 snprintf(focVersion, 15,
"%d.%02d.%d",
1087 static_cast<uint8_t
>(response[0]),
static_cast<uint8_t
>(response[1]),
1088 static_cast<int>((
static_cast<uint8_t
>(response[2]) << 8) +
static_cast<uint8_t
>(response[3])));
1089 vernum = (
static_cast<uint8_t
>(response[0]) << 24) + (
static_cast<uint8_t
>(response[1]) << 16) + (
static_cast<uint8_t
>
1090 (response[2]) << 8) +
static_cast<uint8_t
>(response[3]);
1097 LOGF_DEBUG(
"Focuser Version %s, exists %s", focVersion, vernum != 0 ?
"true" :
"false");
1105 int offset = get_sim_foc_offset();
1108 else if (offset < -250)
1111 move_sim_foc(offset);
1113 set_sim_response(
"%c%c%c#", sim_data.foc_position >> 16 & 0xff, sim_data.foc_position >> 8 & 0XFF,
1114 sim_data.foc_position & 0XFF);
1119 int pos = (
static_cast<uint8_t
>(response[0]) << 16) + (
static_cast<uint8_t
>(response[1]) << 8) +
static_cast<uint8_t
>
1130 sim_data.foc_target = steps;
1132 char payload[] = {
static_cast<char>(steps >> 16 & 0xff),
static_cast<char>(steps >> 8 & 0xff),
static_cast<char>(steps & 0xff)};
1133 set_sim_response(
"#");
1140 set_sim_response(
"%c#", sim_data.foc_target == sim_data.foc_position ? 0xff : 0x00);
1144 return response[0] !=
'\xff';
1149 set_sim_response(
"%c%c%c%c%c%c%c%c#", 0, 0, 0x07, 0xd0, 0, 0, 0x9C, 0x40);
1155 *low = (
static_cast<uint8_t
>(response[0]) << 24) + (
static_cast<uint8_t
>(response[1]) << 16) + (
static_cast<uint8_t
>
1156 (response[2]) << 8) +
static_cast<uint8_t
>(response[3]);
1157 *high = (
static_cast<uint8_t
>(response[4]) << 24) + (
static_cast<uint8_t
>(response[5]) << 16) + (
static_cast<uint8_t
>
1158 (response[6]) << 8) +
static_cast<uint8_t
>(response[7]);
1161 if (*high - *low < 2000 || *high < 0 || *high > 60000 || *low < 0 || *low > 50000)
1163 LOGF_INFO(
"Focus range %i to %i invalid, range not updated", *high, *low);
1167 LOGF_DEBUG(
"Focus Limits: Maximum (%i) Minimum (%i)", *high, *low);
1175 sim_data.foc_target = sim_data.foc_position;
1177 set_sim_response(
"#");
1179 char payload[] = {0};
1192 LOG_DEBUG(
"PecSeekIndex - already found");
1196 set_sim_response(
"#");
1201 LOG_WARN(
"Start PEC seek index failed");
1207 simSeekIndex =
true;
1209 LOGF_DEBUG(
"PecSeekIndex %s", PecStateStr());
1222 set_sim_response(
"%c#", simSeekIndex ? 0xFF : 0x00);
1228 bool indexed = (response[0] ==
'\xFF');
1236 LOGF_DEBUG(
"isPecAtIndex? %s", indexed ?
"yes" :
"no");
1245 LOG_DEBUG(
"getPecNumBins - PEC not available");
1248 set_sim_response(
"%c#", 88);
1249 char payload[] = { 0x3F };
1254 size_t numPecBins = response[0];
1268 set_sim_response(
"%c#", simIndex);
1282 data[0] = start ? 0x01 : 0x00;
1284 set_sim_response(
"#");
1289 LOGF_WARN(
"PEC Playback %s failed", start ?
"start" :
"stop");
1296 LOGF_DEBUG(
"PecPayback %s, pecState %s", start ?
"start" :
"stop", PecStateStr());
1308 set_sim_response(
"#");
1309 simRecordStart = simIndex;
1311 size_t rlen = send_passthrough(
CELESTRON_DEV_RA, command,
nullptr, 0, response, 0);
1314 LOGF_WARN(
"PEC Record %s failed", start ?
"start" :
"stop");
1320 LOGF_DEBUG(
"PecRecord %s, pecState %s", start ?
"start" :
"stop", PecStateStr());
1329 set_sim_response(
"%c#", simIndex == simRecordStart ? 1 : 0);
1335 bool done = response[0] != 0x00;
1339 LOGF_DEBUG(
"isPecRecordDone %s", done ?
"yes" :
"no");
1349 int val =
static_cast<int>(
std::round(std::cos(index * 2.0 * 3.14192 / 87.0) * 100.0));
1350 if (val < 0) val = 256 + val;
1351 set_sim_response(
"%c#", val);
1353 char data[] = {
static_cast<char>(0x40 + index) };
1359 return response[0] <=
'\127' ? response[0] : -256 + response[0];
1365 payload[0] =
static_cast<char>(0x40 + index);
1366 payload[1] =
static_cast<char>((data < 127) ? data : 256 - data);
1367 set_sim_response(
"#");
1389 return PecStateStr(pecState);
1399 return "Not Available";
1403 return "PEC Playback";
1405 return "seeking index";
1407 return "Index Found";
1409 return "PEC Recording";
1421 for (
size_t i = 0; i <= numBins; ++i)
1423 double p = i * 2.0 * 3.14192 / numBins;
1424 data[i] = std::sin(p) * 5;
1426 wormArcSeconds = 7200;
1433 int mountType = driver->
model();
1434 rateScale = (mountType <= 2) ? 512 : 1024;
1435 wormArcSeconds = mountType == 8 ? 3600 : 7200;
1439 if (numBins < 88 || numBins > 254)
1442 double posError = 0;
1444 for (
size_t i = 0; i < numBins; i++)
1457 double binRate = rawPec * SIDEREAL_ARCSEC_PER_SEC / rateScale;
1458 double binTime = (wormArcSeconds / numBins) / (SIDEREAL_ARCSEC_PER_SEC + binRate);
1459 posError += binRate * binTime;
1460 data[i + 1] = posError;
1462 LOGF_DEBUG(
"i %d, rawPec %d, binRate %f, binTime %f, data[%d] %f", i, rawPec, binRate, binTime, i + 1, data[i + 1]);
1477 std::ifstream pecFile(fileName);
1479 if (pecFile.is_open())
1482 for (
size_t i = 0; i <= numBins; i++)
1486 pecFile >> wormArcSeconds;
1487 LOGF_DEBUG(
"PEC Load File %s, numBins %d, wormarcsecs %d", fileName, numBins, wormArcSeconds);
1493 LOGF_WARN(
"Load PEC file %s, error %s", fileName, strerror(
errno));
1502 std::ofstream pecFile(filename);
1503 if (!pecFile.is_open())
1506 pecFile << numBins <<
"\n";
1507 for (
size_t i = 0; i <= numBins; i++)
1509 pecFile << data[i] <<
"\n";
1512 pecFile << wormArcSeconds <<
"\n";
1525 for (
size_t i = 0; i < numBins; i++)
1532 deltaDist = data[i + 1] - data[i];
1534 double rawPecData = deltaDist * SIDEREAL_ARCSEC_PER_SEC / (wormArcSeconds / numBins - deltaDist);
1536 int rawdata =
static_cast<int>(
std::round(rawPecData * rateScale / SIDEREAL_ARCSEC_PER_SEC));
1537 LOGF_DEBUG(
"i %d, deltaDist %f, rawPecdata %f, rawData %d", i, deltaDist, rawPecData, rawdata);
1552 double delta = (data[numBins] - data[0]) / numBins;
1553 double offset = data[0];
1554 for (
size_t i = 0; i <= numBins; i++)
1556 data[i] = data[i] - offset - delta * i;
1560 void PecData::Kalman(
PecData newData,
int num)
1562 if (numBins != newData.numBins)
1567 auto fraction = 1.0 / num;
1568 auto kf = 1 - fraction;
1570 for (
size_t i = 0; i <= numBins; i++)
1572 data[i] = data[i] * kf + newData.data[i] * fraction;
void parseCoordsResponse(char *response, double *d1, double *d2, bool precise)
void hex_dump(char *buf, const char *data, size_t size)
__attribute__((__format__(__printf__, 2, 0))) void CelestronDriver
#define CELESTRON_TIMEOUT
#define MC_PEC_RECORD_DONE
#define MC_SET_NEG_GUIDERATE
#define MC_PEC_RECORD_STOP
#define MC_PEC_RECORD_START
#define FOC_GET_HS_POSITIONS
#define MC_PEC_WRITE_DATA
#define CELESTRON_DEV_FOC
@ PEC_SEEKING
The PEC index is being searched for, goes to PEC_INDEXED when found
@ PEC_AVAILABLE
PEC is available but inactive, can seek index Seek index is only available command
@ PEC_PLAYBACK
PEC is being played back, stays in this state until stopped equivalent to TelescopePECState PEC_ON
@ PEC_RECORDING
PEC is being recorded, goes to PEC_INDEXED when completed
@ PEC_NOT_AVAILABLE
PEC is not available, hardware has been checked, no other state is possible
@ PEC_INDEXED
the PEC index has been found, can go to Playback or Recording this is equivalent to TelescopePECState...
#define CELESTRON_DEV_DEC
#define MC_SET_AUTOGUIDE_RATE
#define MC_GET_AUTOGUIDE_RATE
#define MC_SET_POS_GUIDERATE
#define MTR_IS_AUX_GUIDE_ACTIVE
bool slew_radec(double ra, double dec, bool precise)
bool get_azalt(double *az, double *alt, bool precise)
bool set_guide_rate(CELESTRON_AXIS axis, uint8_t rate)
bool indexreached(bool *atIndex)
bool check_aligned(bool *isAligned)
bool set_datetime(struct ln_date *utc, double utc_offset, bool dst=false, bool precise=false)
bool set_location(double longitude, double latitude)
bool stop_motion(CELESTRON_DIRECTION dir)
int getPecValue(size_t index)
bool get_firmware(FirmwareInfo *info)
bool sync(double ra, double dec, bool precise)
bool foc_limits(int *low, int *high)
bool PecPlayback(bool start)
bool get_dev_firmware(int dev, char *version, size_t size)
size_t send_pulse(CELESTRON_DIRECTION direction, unsigned char rate, unsigned char duration_msec)
size_t send_passthrough(int dest, int cmd_id, const char *payload, size_t payload_len, char *resp, size_t response_len)
bool get_radec(double *ra, double *dec, bool precise)
bool get_track_mode(CELESTRON_TRACK_MODE *mode)
void set_device(const char *name)
bool set_track_rate(CELESTRON_TRACK_RATE rate, CELESTRON_TRACK_MODE mode)
bool set_track_mode(CELESTRON_TRACK_MODE mode)
bool get_model(char *model, size_t size, bool *isGem, bool *canPec, bool *hasHomeIndex)
bool get_version(char *version, size_t size)
size_t send_command(const char *cmd, size_t cmd_len, char *resp, size_t resp_len, bool ascii_cmd, bool ascii_resp)
virtual int serial_read(int nbytes, int *nbytes_read)
const char * PecStateStr()
bool PecRecord(bool start)
bool isPecAtIndex(bool force=false)
bool get_variant(char *variant)
bool get_location(double *longitude, double *latitude)
const char * getDeviceName()
bool get_pulse_status(CELESTRON_DIRECTION direction)
virtual int serial_write(const char *cmd, int nbytes, int *nbytes_written)
PEC_STATE updatePecState()
virtual int serial_read_section(char stop_char, int *nbytes_read)
bool get_guide_rate(CELESTRON_AXIS axis, uint8_t *rate)
bool slew_azalt(double az, double alt, bool precise)
bool setPecValue(size_t index, int data)
bool foc_move(uint32_t steps)
bool get_pier_side(char *sop)
bool is_slewing(bool *slewing)
bool get_utc_date_time(double *utc_hours, int *yy, int *mm, int *dd, int *hh, int *minute, int *ss, bool *dst, bool precise)
bool start_motion(CELESTRON_DIRECTION dir, CELESTRON_SLEW_RATE rate)
const char * getDeviceName()
bool Load(CelestronDriver *driver)
bool Save(const char *filename)
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
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
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 LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
#define LOGF_EXTRA1(fmt,...)
double pnex2dd(uint32_t value)
uint32_t dd2pnex(double angle)
uint16_t dd2nex(double angle)
double trimDecAngle(double angle)
double nex2dd(uint32_t value)
double round(double value, int decimal_places)