32 static std::unique_ptr<MoonLite> moonLite(
new MoonLite());
54 IUFillSwitchVector(&StepModeSP, StepModeS, 2,
getDeviceName(),
"Step Mode",
"",
OPTIONS_TAB,
IP_RW,
ISR_1OFMANY, 0,
58 IUFillNumber(&TemperatureN[0],
"TEMPERATURE",
"Celsius",
"%6.2f", -50, 70., 0., 0.);
63 IUFillNumber(&TemperatureSettingN[0],
"Calibration",
"",
"%6.2f", -100, 100, 0.5, 0);
64 IUFillNumber(&TemperatureSettingN[1],
"Coefficient",
"",
"%6.2f", -100, 100, 0.5, 0);
104 LOG_INFO(
"MoonLite parameters updated, focuser ready for use.");
121 LOG_INFO(
"MoonLite is online. Getting focus parameters...");
126 "Error retrieving data from MoonLite, please ensure MoonLite controller is powered and the port is correct.");
137 bool success =
false;
139 for (
int i = 0; i < 3; i++)
153 bool MoonLite::readStepMode()
155 char res[ML_RES] = {0};
157 if (sendCommand(
":GH#", res) ==
false)
160 if (strcmp(res,
"FF#") == 0)
162 else if (strcmp(res,
"00#") == 0)
166 LOGF_ERROR(
"Unknown error: focuser step value (%s)", res);
173 bool MoonLite::readVersion()
175 char res[ML_RES] = {0};
177 if (sendCommand(
":GV#", res,
true, 2) ==
false)
180 LOGF_INFO(
"Detected firmware version %c.%c", res[0], res[1]);
185 bool MoonLite::readTemperature()
187 char res[ML_RES] = {0};
191 if (sendCommand(
":GT#", res) ==
false)
195 int rc = sscanf(res,
"%X", &temp);
198 TemperatureN[0].value =
static_cast<int16_t
>(temp) / 2.0;
201 LOGF_ERROR(
"Unknown error: focuser temperature value (%s)", res);
208 bool MoonLite::readPosition()
210 char res[ML_RES] = {0};
212 if (sendCommand(
":GP#", res) ==
false)
216 int rc = sscanf(res,
"%X#", &pos);
222 LOGF_ERROR(
"Unknown error: focuser position value (%s)", res);
229 bool MoonLite::readSpeed()
231 char res[ML_RES] = {0};
233 if (sendCommand(
":GD#", res) ==
false)
237 int rc = sscanf(res,
"%hX#", &speed);
241 int focus_speed = -1;
251 LOGF_ERROR(
"Unknown error: focuser speed value (%s)", res);
258 bool MoonLite::isMoving()
260 char res[ML_RES] = {0};
262 if (sendCommand(
":GI#", res) ==
false)
266 if (strstr(res,
"1#"))
268 else if (strstr(res,
"0#"))
271 LOGF_ERROR(
"Unknown error: isMoving value (%s)", res);
275 bool MoonLite::setTemperatureCalibration(
double calibration)
277 char cmd[ML_RES] = {0};
278 uint8_t hex =
static_cast<int8_t
>(calibration * 2) & 0xFF;
279 snprintf(
cmd, ML_RES,
":PO%02X#", hex);
280 return sendCommand(
cmd);
283 bool MoonLite::setTemperatureCoefficient(
double coefficient)
285 char cmd[ML_RES] = {0};
286 uint8_t hex =
static_cast<int8_t
>(coefficient * 2) & 0xFF;
287 snprintf(
cmd, ML_RES,
":SC%02X#", hex);
288 return sendCommand(
cmd);
293 char cmd[ML_RES] = {0};
294 snprintf(
cmd, ML_RES,
":SP%04X#", ticks);
295 return sendCommand(
cmd);
300 char cmd[ML_RES] = {0};
301 snprintf(
cmd, ML_RES,
":SN%04X#", position);
303 if (sendCommand(
cmd) ==
false)
306 if (sendCommand(
":FG#") ==
false)
312 bool MoonLite::setStepMode(FocusStepMode mode)
314 char cmd[ML_RES] = {0};
316 return sendCommand(
cmd);
319 bool MoonLite::setSpeed(
int speed)
321 char cmd[ML_RES] = {0};
324 snprintf(
cmd, ML_RES,
":SD%02X#", hex_value);
325 return sendCommand(
cmd);
328 bool MoonLite::setTemperatureCompensation(
bool enable)
330 char cmd[ML_RES] = {0};
331 snprintf(
cmd, ML_RES,
":%c#", enable ?
'+' :
'-');
332 return sendCommand(
cmd);
340 if (strcmp(StepModeSP.
name, name) == 0)
348 if (current_mode == target_mode)
358 StepModeS[current_mode].s =
ISS_ON;
370 if (strcmp(TemperatureCompensateSP.
name, name) == 0)
375 bool rc = setTemperatureCompensation((TemperatureCompensateS[0].s ==
ISS_ON));
381 TemperatureCompensateS[last_index].s =
ISS_ON;
386 TemperatureCompensateSP.
s =
IPS_OK;
400 if (strcmp(name, TemperatureSettingNP.
name) == 0)
403 if (!setTemperatureCalibration(TemperatureSettingN[0].value) ||
404 !setTemperatureCoefficient(TemperatureSettingN[1].value))
411 TemperatureSettingNP.
s =
IPS_OK;
420 void MoonLite::GetFocusParams()
425 if (readTemperature())
437 return setSpeed(speed);
442 if (speed !=
static_cast<int>(
FocusSpeedN[0].value))
444 if (!setSpeed(speed))
461 static_cast<MoonLite *
>(context)->timedMoveCallback();
464 void MoonLite::timedMoveCallback()
478 targetPos = targetTicks;
489 int32_t offset = ((dir ==
FOCUS_INWARD) ? -1 : 1) *
static_cast<int32_t
>(ticks);
508 bool rc = readPosition();
518 rc = readTemperature();
521 if (fabs(lastTemperature - TemperatureN[0].value) >= 0.5)
524 lastTemperature =
static_cast<uint32_t
>(TemperatureN[0].value);
537 LOG_INFO(
"Focuser reached requested position.");
546 return sendCommand(
":FQ#");
551 Focuser::saveConfigItems(fp);
558 bool MoonLite::sendCommand(
const char *
cmd,
char * res,
bool silent,
int nret)
560 int nbytes_written = 0, nbytes_read = 0, rc = -1;
562 tcflush(
PortFD, TCIOFLUSH);
571 LOGF_ERROR(
"Serial write error: %s.", errstr);
601 tcflush(
PortFD, TCIOFLUSH);
const char * getDeviceName() const
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
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.
INumberVectorProperty FocusSpeedNP
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
INumberVectorProperty FocusTimerNP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
@ FOCUSER_HAS_VARIABLE_SPEED
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState MoveFocuser(FocusDirection dir, int speed, uint16_t duration) override
MoveFocuser Move focuser in a specific direction and speed for period of time.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
static void timedMoveHelper(void *context)
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool SetFocuserSpeed(int speed) override
SetFocuserSpeed Set Focuser speed.
const char * getDefaultName() override
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set the supplied position as the current focuser position.
virtual bool Handshake() override
Handshake Try to communicate with Focuser and see if there is a valid response.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveAbsFocuser Move to an absolute target position.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveRelFocuser Move focuser for a relative amount of ticks in a specific direction.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
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.
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)