3
Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29
#include "celestronprotocol.h"
30
#include "celestrongps.h"
32
#define mydev "Celestron GPS"
35
#define currentRA EquatorialCoordsRN[0].value
36
#define currentDEC EquatorialCoordsRN[1].value
37
#define targetRA EquatorialCoordsWN[0].value
38
#define targetDEC EquatorialCoordsWN[1].value
40
/* Enable to log debug statements
41
#define CELESTRON_DEBUG 1
44
CelestronGPS *telescope = NULL;
47
/* There is _one_ binary for all LX200 drivers, but each binary is renamed
48
** to its device name (i.e. lx200gps, lx200_16..etc). The main function will
49
** fetch from std args the binary name and ISInit will create the apporpiate
50
** device afterwards. If the binary name does not match any known devices,
51
** we simply create a generic device
55
#define COMM_GROUP "Communication"
56
#define BASIC_GROUP "Main Control"
57
#define MOVE_GROUP "Movement Control"
59
static void ISPoll(void *);
62
static ISwitch SlewModeS[] = {{"Slew", "", ISS_ON, 0, 0}, {"Find", "", ISS_OFF, 0, 0}, {"Centering", "", ISS_OFF, 0, 0}, {"Guide", "", ISS_OFF, 0, 0}};
64
/* Equatorial Coordinates: Request */
65
static INumber EquatorialCoordsWN[] = { {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};
66
static INumberVectorProperty EquatorialCoordsWNP = { mydev, "EQUATORIAL_EOD_COORD_REQUEST", "Equatorial JNow", BASIC_GROUP, IP_WO, 120, IPS_IDLE, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), "", 0};
68
/* Equatorial Coordinates: Info */
69
static INumber EquatorialCoordsRN[] = { {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};
70
static INumberVectorProperty EquatorialCoordsRNP = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RO, 120, IPS_IDLE, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), "", 0};
72
/* Tracking precision */
73
INumber TrackingAccuracyN[] = {
74
{"TrackRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0},
75
{"TrackDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0},
77
static INumberVectorProperty TrackingAccuracyNP = {mydev, "Tracking Accuracy", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, TrackingAccuracyN, NARRAY(TrackingAccuracyN), "", 0};
80
INumber SlewAccuracyN[] = {
81
{"SlewRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0},
82
{"SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0},
84
static INumberVectorProperty SlewAccuracyNP = {mydev, "Slew Accuracy", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, SlewAccuracyN, NARRAY(SlewAccuracyN), "", 0};
86
/* Fundamental group */
87
static ISwitch ConnectS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
88
static ISwitchVectorProperty ConnectSP = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ConnectS, NARRAY(ConnectS), "", 0};
90
static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}};
91
static ITextVectorProperty PortTP = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0};
94
static ISwitch OnCoordSetS[] = {{"SLEW", "Slew", ISS_ON, 0 , 0}, {"TRACK", "Track", ISS_OFF, 0, 0}, {"SYNC", "Sync", ISS_OFF, 0, 0}};
95
static ISwitchVectorProperty OnCoordSetSP = { mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, OnCoordSetS, NARRAY(OnCoordSetS), "", 0};
97
static ISwitch AbortSlewS[] = {{"ABORT", "Abort", ISS_OFF, 0, 0}};
98
static ISwitchVectorProperty AbortSlewSP = { mydev, "TELESCOPE_ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, AbortSlewS, NARRAY(AbortSlewS), "", 0};
99
static ISwitchVectorProperty SlewModeSP = { mydev, "Slew rate", "", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SlewModeS, NARRAY(SlewModeS), "", 0};
101
/* Movement (Arrow keys on handset). North/South */
102
static ISwitch MovementNSS[] = {{"MOTION_NORTH", "North", ISS_OFF, 0, 0}, {"MOTION_SOUTH", "South", ISS_OFF, 0, 0}};
104
static ISwitchVectorProperty MovementNSSP = { mydev, "TELESCOPE_MOTION_NS", "North/South", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementNSS, NARRAY(MovementNSS), "", 0};
106
/* Movement (Arrow keys on handset). West/East */
107
static ISwitch MovementWES[] = {{"MOTION_WEST", "West", ISS_OFF, 0, 0}, {"MOTION_EAST", "East", ISS_OFF, 0, 0}};
109
static ISwitchVectorProperty MovementWESP = { mydev, "TELESCOPE_MOTION_WE", "West/East", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0};
112
/* send client definitions of all properties */
122
IUSaveText(&PortT[0], "/dev/ttyS0");
124
telescope = new CelestronGPS();
126
IEAddTimer (POLLMS, ISPoll, NULL);
129
void ISGetProperties (const char *dev)
130
{ ISInit(); telescope->ISGetProperties(dev);}
131
void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
132
{ ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);}
133
void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
134
{ ISInit(); telescope->ISNewText(dev, name, texts, names, n);}
135
void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
136
{ ISInit(); telescope->ISNewNumber(dev, name, values, names, n);}
137
void ISPoll (void *p) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;}
138
void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
143
INDI_UNUSED(blobsizes);
145
INDI_UNUSED(formats);
149
void ISSnoopDevice (XMLEle *root)
154
/**************************************************
155
*** LX200 Generic Implementation
156
***************************************************/
158
CelestronGPS::CelestronGPS()
166
// Children call parent routines, this is the default
167
IDLog("initilizaing from Celeston GPS device...\n");
171
void CelestronGPS::ISGetProperties(const char *dev)
174
if (dev && strcmp (mydev, dev))
178
IDDefSwitch (&ConnectSP, NULL);
179
IDDefText (&PortTP, NULL);
182
IDDefNumber (&EquatorialCoordsWNP, NULL);
183
IDDefNumber (&EquatorialCoordsRNP, NULL);
184
IDDefSwitch (&OnCoordSetSP, NULL);
185
IDDefSwitch (&AbortSlewSP, NULL);
186
IDDefSwitch (&SlewModeSP, NULL);
189
IDDefSwitch (&MovementNSSP, NULL);
190
IDDefSwitch (&MovementWESP, NULL);
191
IDDefNumber (&TrackingAccuracyNP, NULL);
192
IDDefNumber (&SlewAccuracyNP, NULL);
194
/* Send the basic data to the new client if the previous client(s) are already connected. */
195
if (ConnectSP.s == IPS_OK)
200
void CelestronGPS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
206
// ignore if not ours //
207
if (strcmp (dev, mydev))
210
if (!strcmp(name, PortTP.name) )
214
tp = IUFindText( &PortTP, names[0] );
218
IUSaveText(&PortT[0], texts[0]);
219
IDSetText (&PortTP, NULL);
224
int CelestronGPS::handleCoordSet()
228
char RAStr[32], DecStr[32];
236
if (EquatorialCoordsWNP.s == IPS_BUSY)
239
// sleep for 500 mseconds
243
if ((i = SlewToCoords(targetRA, targetDEC)))
249
EquatorialCoordsWNP.s = IPS_BUSY;
250
EquatorialCoordsRNP.s = IPS_BUSY;
251
fs_sexa(RAStr, targetRA, 2, 3600);
252
fs_sexa(DecStr, targetDEC, 2, 3600);
253
IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
254
IDSetNumber(&EquatorialCoordsRNP, NULL);
255
IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
261
if (EquatorialCoordsWNP.s == IPS_BUSY)
264
// sleep for 500 mseconds
268
if ( (fabs ( targetRA - currentRA ) >= (TrackingAccuracyN[0].value/(15.0*60.0))) ||
269
(fabs (targetDEC - currentDEC) >= (TrackingAccuracyN[1].value)/60.0))
272
#ifdef CELESTRON_DEBUG
273
IDLog("Exceeded Tracking threshold, will attempt to slew to the new target.\n");
274
IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA);
275
IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC);
278
if (( i = SlewToCoords(targetRA, targetDEC)))
284
fs_sexa(RAStr, targetRA, 2, 3600);
285
fs_sexa(DecStr, targetDEC, 2, 3600);
286
EquatorialCoordsWNP.s = IPS_BUSY;
287
EquatorialCoordsRNP.s = IPS_BUSY;
288
IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
289
IDSetNumber(&EquatorialCoordsRNP, NULL);
290
IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
294
#ifdef CELESTRON_DEBUG
295
IDLog("Tracking called, but tracking threshold not reached yet.\n");
297
EquatorialCoordsWNP.s = IPS_OK;
298
EquatorialCoordsRNP.s = IPS_OK;
300
IDSetNumber(&EquatorialCoordsWNP, "Tracking...");
302
IDSetNumber(&EquatorialCoordsWNP, NULL);
304
IDSetNumber(&EquatorialCoordsRNP, NULL);
312
OnCoordSetSP.s = IPS_OK;
313
SyncToCoords(targetRA, targetDEC);
314
EquatorialCoordsWNP.s = IPS_OK;
315
EquatorialCoordsRNP.s = IPS_OK;
316
IDSetNumber(&EquatorialCoordsWNP, "Synchronization successful.");
317
IDSetNumber(&EquatorialCoordsRNP, NULL);
325
void CelestronGPS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
327
double newRA=0, newDEC=0;
329
// ignore if not ours //
330
if (strcmp (dev, mydev))
339
if (!strcmp (name, TrackingAccuracyNP.name))
341
if (!IUUpdateNumber(&TrackingAccuracyNP, values, names, n))
343
TrackingAccuracyNP.s = IPS_OK;
344
IDSetNumber(&TrackingAccuracyNP, NULL);
348
TrackingAccuracyNP.s = IPS_ALERT;
349
IDSetNumber(&TrackingAccuracyNP, "unknown error while setting tracking precision");
353
if (!strcmp(name, SlewAccuracyNP.name))
355
IUUpdateNumber(&SlewAccuracyNP, values, names, n);
357
SlewAccuracyNP.s = IPS_OK;
358
IDSetNumber(&SlewAccuracyNP, NULL);
362
SlewAccuracyNP.s = IPS_ALERT;
363
IDSetNumber(&SlewAccuracyNP, "unknown error while setting slew precision");
367
if (!strcmp (name, EquatorialCoordsWNP.name))
371
if (checkPower(&EquatorialCoordsWNP))
374
for (nset = i = 0; i < n; i++)
376
INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
377
if (eqp == &EquatorialCoordsWN[0])
380
nset += newRA >= 0 && newRA <= 24.0;
381
} else if (eqp == &EquatorialCoordsWN[1])
384
nset += newDEC >= -90.0 && newDEC <= 90.0;
390
//EquatorialCoordsNP.s = IPS_BUSY;
398
if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY)
400
IUResetSwitch(&MovementNSSP);
401
IUResetSwitch(&MovementWESP);
402
MovementNSSP.s = MovementWESP.s = IPS_IDLE;
403
IDSetSwitch(&MovementNSSP, NULL);
404
IDSetSwitch(&MovementWESP, NULL);
407
if (handleCoordSet())
409
EquatorialCoordsWNP.s = IPS_ALERT;
410
IDSetNumber(&EquatorialCoordsWNP, NULL);
415
EquatorialCoordsWNP.s = IPS_ALERT;
416
IDSetNumber(&EquatorialCoordsWNP, "RA or Dec missing or invalid.");
423
void CelestronGPS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
430
// ignore if not ours //
431
if (strcmp (dev, mydev))
434
// FIRST Switch ALWAYS for power
435
if (!strcmp (name, ConnectSP.name))
437
if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0) return;
442
if (!strcmp(name, OnCoordSetSP.name))
444
if (checkPower(&OnCoordSetSP))
448
if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0) return;
449
currentSet = getOnSwitch(&OnCoordSetSP);
453
if (!strcmp (name, AbortSlewSP.name))
455
if (checkPower(&AbortSlewSP))
457
AbortSlewSP.s = IPS_ALERT;
458
IDSetSwitch(&AbortSlewSP, NULL);
462
IUResetSwitch(&AbortSlewSP);
465
if (EquatorialCoordsWNP.s == IPS_BUSY)
467
AbortSlewSP.s = IPS_OK;
468
EquatorialCoordsWNP.s = IPS_IDLE;
469
EquatorialCoordsRNP.s = IPS_IDLE;
470
IDSetSwitch(&AbortSlewSP, "Slew aborted.");
471
IDSetNumber(&EquatorialCoordsWNP, NULL);
472
IDSetNumber(&EquatorialCoordsRNP, NULL);
474
else if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY)
476
MovementNSSP.s = MovementWESP.s = IPS_IDLE;
478
AbortSlewSP.s = IPS_OK;
479
EquatorialCoordsRNP.s = IPS_IDLE;
480
IUResetSwitch(&MovementNSSP);
481
IUResetSwitch(&MovementWESP);
482
IUResetSwitch(&AbortSlewSP);
484
IDSetSwitch(&AbortSlewSP, "Slew aborted.");
485
IDSetSwitch(&MovementNSSP, NULL);
486
IDSetSwitch(&MovementWESP, NULL);
487
IDSetNumber(&EquatorialCoordsRNP, NULL);
491
AbortSlewSP.s = IPS_OK;
492
IDSetSwitch(&AbortSlewSP, NULL);
499
if (!strcmp (name, SlewModeSP.name))
501
if (checkPower(&SlewModeSP))
504
IUResetSwitch(&SlewModeSP);
505
IUUpdateSwitch(&SlewModeSP, states, names, n);
506
index = getOnSwitch(&SlewModeSP);
509
SlewModeSP.s = IPS_OK;
510
IDSetSwitch(&SlewModeSP, NULL);
514
// Movement (North/South)
515
if (!strcmp (name, MovementNSSP.name))
517
if (checkPower(&MovementNSSP))
521
int current_move = -1;
523
// -1 means all off previously
524
last_move = getOnSwitch(&MovementNSSP);
526
if (IUUpdateSwitch(&MovementNSSP, states, names, n) < 0)
529
current_move = getOnSwitch(&SlewModeSP);
531
// Previosuly active switch clicked again, so let's stop.
532
if (current_move == last_move)
534
StopSlew((current_move == 0) ? NORTH : SOUTH);
535
IUResetSwitch(&MovementNSSP);
536
MovementNSSP.s = IPS_IDLE;
537
IDSetSwitch(&MovementNSSP, NULL);
541
#ifdef CELESTRON_DEBUG
542
IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move);
545
// 0 (North) or 1 (South)
546
last_move = current_move;
548
// Correction for Celestron Driver: North 0 - South 3
549
current_move = (current_move == 0) ? NORTH : SOUTH;
551
StartSlew(current_move);
553
MovementNSSP.s = IPS_BUSY;
554
IDSetSwitch(&MovementNSSP, "Moving toward %s", (current_move == NORTH) ? "North" : "South");
558
// Movement (West/East)
559
if (!strcmp (name, MovementWESP.name))
561
if (checkPower(&MovementWESP))
565
int current_move = -1;
567
// -1 means all off previously
568
last_move = getOnSwitch(&MovementWESP);
570
if (IUUpdateSwitch(&MovementWESP, states, names, n) < 0)
573
current_move = getOnSwitch(&SlewModeSP);
575
// Previosuly active switch clicked again, so let's stop.
576
if (current_move == last_move)
578
StopSlew((current_move ==0) ? WEST : EAST);
579
IUResetSwitch(&MovementWESP);
580
MovementWESP.s = IPS_IDLE;
581
IDSetSwitch(&MovementWESP, NULL);
585
#ifdef CELESTRON_DEBUG
586
IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move);
589
// 0 (West) or 1 (East)
590
last_move = current_move;
592
// Correction for Celestron Driver: West 1 - East 2
593
current_move = (current_move == 0) ? WEST : EAST;
595
StartSlew(current_move);
597
MovementWESP.s = IPS_BUSY;
598
IDSetSwitch(&MovementWESP, "Moving toward %s", (current_move == WEST) ? "West" : "East");
604
int CelestronGPS::getOnSwitch(ISwitchVectorProperty *sp)
606
for (int i=0; i < sp->nsp ; i++)
607
if (sp->sp[i].s == ISS_ON)
614
int CelestronGPS::checkPower(ISwitchVectorProperty *sp)
616
if (ConnectSP.s != IPS_OK)
618
if (!strcmp(sp->label, ""))
619
IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->name);
621
IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->label);
624
IDSetSwitch(sp, NULL);
631
int CelestronGPS::checkPower(INumberVectorProperty *np)
633
if (ConnectSP.s != IPS_OK)
635
if (!strcmp(np->label, ""))
636
IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->name);
638
IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->label);
641
IDSetNumber(np, NULL);
647
int CelestronGPS::checkPower(ITextVectorProperty *tp)
650
if (ConnectSP.s != IPS_OK)
652
if (!strcmp(tp->label, ""))
653
IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->name);
655
IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->label);
666
void CelestronGPS::ISPoll()
671
switch (EquatorialCoordsWNP.s)
674
if (ConnectSP.s != IPS_OK)
677
currentDEC = GetDec();
679
if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
682
lastDEC = currentDEC;
683
IDSetNumber (&EquatorialCoordsRNP, NULL);
690
currentDEC = GetDec();
691
dx = targetRA - currentRA;
692
dy = targetDEC - currentDEC;
694
#ifdef CELESTRON_DEBUG
695
IDLog("targetRA is %f, currentRA is %f\n", (float) targetRA, (float) currentRA);
696
IDLog("targetDEC is %f, currentDEC is %f\n****************************\n", (float) targetDEC, (float) currentDEC);
699
status = CheckCoords(targetRA, targetDEC, SlewAccuracyN[0].value/(15.0*60.0) , SlewAccuracyN[1].value/60.0);
701
// Wait until acknowledged or within 3.6', change as desired.
704
case 0: /* goto in progress */
705
IDSetNumber (&EquatorialCoordsRNP, NULL);
707
case 1: /* goto complete within tolerance */
708
case 2: /* goto complete but outside tolerance */
709
currentRA = targetRA;
710
currentDEC = targetDEC;
712
EquatorialCoordsWNP.s = IPS_OK;
713
EquatorialCoordsRNP.s = IPS_OK;
717
IDSetNumber (&EquatorialCoordsWNP, "Slew is complete.");
718
IDSetNumber (&EquatorialCoordsRNP, NULL);
722
IDSetNumber (&EquatorialCoordsWNP, "Slew is complete. Tracking...");
723
IDSetNumber (&EquatorialCoordsRNP, NULL);
731
if (ConnectSP.s != IPS_OK)
734
currentDEC = GetDec();
736
if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
739
lastDEC = currentDEC;
740
IDSetNumber (&EquatorialCoordsRNP, NULL);
750
switch (MovementNSSP.s)
756
currentDEC = GetDec();
757
IDSetNumber (&EquatorialCoordsRNP, NULL);
766
switch (MovementWESP.s)
772
currentDEC = GetDec();
773
IDSetNumber (&EquatorialCoordsRNP, NULL);
784
void CelestronGPS::getBasicData()
788
currentDEC = GetDec();
790
IDSetNumber(&EquatorialCoordsRNP, NULL);
794
void CelestronGPS::connectTelescope()
797
switch (ConnectSP.sp[0].s)
801
if (ConnectTel(PortTP.tp[0].text) < 0)
803
ConnectS[0].s = ISS_OFF;
804
ConnectS[1].s = ISS_ON;
805
IDSetSwitch (&ConnectSP, "Error connecting to port %s. Make sure you have BOTH write and read permission to the port.", PortTP.tp[0].text);
809
ConnectSP.s = IPS_OK;
810
IDSetSwitch (&ConnectSP, "Telescope is online. Retrieving basic data...");
815
IDSetSwitch (&ConnectSP, "Telescope is offline.");
816
IDLog("Telescope is offline.");
823
void CelestronGPS::slewError(int slewCode)
825
EquatorialCoordsWNP.s = IPS_ALERT;
830
IDSetNumber (&EquatorialCoordsWNP, "Invalid newDec in SlewToCoords");
833
IDSetNumber (&EquatorialCoordsWNP, "RA count overflow in SlewToCoords");
836
IDSetNumber (&EquatorialCoordsWNP, "Dec count overflow in SlewToCoords");
839
IDSetNumber (&EquatorialCoordsWNP, "No acknowledgment from telescope after SlewToCoords");
842
IDSetNumber (&EquatorialCoordsWNP, "Unknown error");