34static std::unique_ptr<CelestronSCT> celestronSCT(
new CelestronSCT());
37 truePosMax(0xffffffff),
41 calibrateInProgress(false),
43 focuserIsCalibrated(false)
75 CalibrateSP[START].
fill(
"START",
"Start Calibration",
ISS_OFF);
76 CalibrateSP[STOP].
fill(
"STOP",
"Stop Calibration",
ISS_OFF);
80 CalibrateStateTP[0].
fill(
"CALIBRATE_STATE",
"Calibrate state",
"");
144 if (getStartupParameters())
145 LOG_INFO(
"Celestron SCT focuser parameters updated, focuser ready for use.");
147 LOG_WARN(
"Failed to retrieve some focuser parameters. Check logs.");
165 LOG_INFO(
"Celestron SCT Focuser is online. Getting focus parameters...");
169 LOG_INFO(
"Error retrieving data from Celestron SCT, please ensure Celestron SCT controller is powered and the port is correct.");
175 return "Celestron SCT";
178bool CelestronSCT::Ack()
190 LOG_ERROR(
"Empty response from focuser");
195 if (reply.size() < 2)
197 LOG_ERROR(
"Incomplete firmware version response");
201 if (reply.size() >= 4)
204 uint16_t build = (reply[2] << 8);
205 if (reply.size() > 4)
207 LOGF_INFO(
"Firmware Version %d.%d.%d", reply[0], reply[1], build);
212 LOGF_INFO(
"Firmware Version %d.%d", reply[0], reply[1]);
217bool CelestronSCT::readPosition()
224 if (reply.size() < 3)
226 LOG_ERROR(
"Invalid position response size");
230 int truePos = (reply[0] << 16) + (reply[1] << 8) + reply[2];
236bool CelestronSCT::isMoving()
241 LOG_ERROR(
"Failed to get motion status");
247 LOG_ERROR(
"Empty motion status response");
251 return reply[0] !=
static_cast<uint8_t
>(0xFF);
255bool CelestronSCT::readLimits()
262 if (reply.size() < 8)
264 LOG_ERROR(
"Invalid limits response size");
268 truePosMin = (reply[0] << 24) + (reply[1] << 16) + (reply[2] << 8) + reply[3];
269 truePosMax = (reply[4] << 24) + (reply[5] << 16) + (reply[6] << 8) + reply[7];
272 if (truePosMax <= truePosMin)
274 focuserIsCalibrated =
false;
275 LOGF_INFO(
"Focus range %i to %i invalid", truePosMin, truePosMax);
291 focuserIsCalibrated =
true;
292 LOGF_INFO(
"Focus range %i to %i valid", truePosMin, truePosMax);
320 CalibrateSP.
update(states, names, n);
327 LOG_INFO(
"Focuser Calibrate start");
328 calibrateInProgress =
true;
333 LOG_INFO(
"Focuser Calibrate abort");
349bool CelestronSCT::getStartupParameters()
351 bool rc1 =
false, rc2 =
false;
353 if ( (rc1 = readPosition()))
356 if ( !(rc2 = readLimits()))
358 LOG_WARN(
"Focuser not calibrated, You MUST calibrate before moves are allowed.");
371 if (!focuserIsCalibrated)
373 LOG_ERROR(
"Move not allowed because focuser is not calibrated.");
376 if (calibrateInProgress)
378 LOG_WARN(
"Move not allowed because a calibration is in progress");
387 LOGF_ERROR(
"Move to %i not allowed because it is out of range", targetTicks);
391 uint32_t position = targetTicks;
398 finalPosition = position;
402 if (!startMove(position))
408bool CelestronSCT::startMove(uint32_t absPos)
411 int position = truePos(absPos);
415 static_cast<uint8_t
>((position >> 16) & 0xFF),
416 static_cast<uint8_t
>((position >> 8) & 0xFF),
417 static_cast<uint8_t
>(position & 0xFF)
420 LOGF_DEBUG(
"startMove to true position %i, %x %x %x", position, data[0], data[1], data[2]);
427 int32_t newPosition = 0;
435 newPosition = std::max(0, std::min(
static_cast<int32_t
>(
FocusAbsPosNP[0].getMax()), newPosition));
449 bool rc = readPosition();
471 backlashMove =
false;
472 if (startMove(finalPosition))
473 LOGF_INFO(
"Backlash move to %i", finalPosition);
483 LOG_INFO(
"Focuser reached requested position.");
488 if (calibrateInProgress)
495 LOG_ERROR(
"Failed to get calibration status");
500 if (reply.size() < 2)
502 LOG_ERROR(
"Invalid calibration status response size");
506 bool complete = reply[0] > 0;
507 int state = reply[1];
509 if (complete || state == 0)
513 const char *msg = complete ?
"Calibrate complete" :
"Calibrate aborted";
515 calibrateInProgress =
false;
518 CalibrateStateTP[0].setText(msg);
520 CalibrateStateTP.
apply();
522 if (complete && readLimits())
531 if (state != calibrateState)
533 calibrateState = state;
535 snprintf(str, 20,
"Calibrate state %i", state);
536 CalibrateStateTP[0].setText(str);
537 CalibrateStateTP.
apply(
nullptr);
547 if (calibrateInProgress)
549 LOG_WARN(
"Abort move not allowed when calibrating, use abort calibration to stop");
bool commandBlind(int port, Target dest, Command cmd, buffer data)
static void setDeviceName(const std::string &device)
bool sendCommand(int port, Target dest, Command cmd, buffer data, buffer &reply)
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool AbortFocuser() override
AbortFocuser Abort Focuser motion.
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveAbsFocuser Move to an absolute target position.
virtual bool Handshake() override
Handshake Try to communicate with Focuser and see if there is a valid response.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveRelFocuser Move focuser for a relative amount of ticks in a specific direction.
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual void TimerHit() override
TimerHit Primary Loop called every POLLMS milliseconds (set in Options) to check on the focuser statu...
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
const char * getDefaultName() override
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
INDI::PropertyNumber FocusRelPosNP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusSpeedNP
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertyNumber FocusBacklashNP
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
void setPermission(IPerm permission)
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
@ MC_GOTO_FAST
send 24 bit target
@ GET_VER
return 2 or 4 bytes major.minor.build
@ MC_GET_POSITION
return 24 bit position
@ FOC_GET_HS_POSITIONS
returns 2 ints low and high limits
@ FOC_CALIB_ENABLE
send 0 to start or 1 to stop
@ MC_MOVE_POS
send move rate 0-9
@ MC_SLEW_DONE
return 0xFF when move finished
@ FOC_CALIB_DONE
returns 2 bytes [0] done, [1] state 0-12
std::vector< uint8_t > buffer