33 #define DMFC_TIMEOUT 3
34 #define FOCUS_SETTINGS_TAB "Settings"
35 #define TEMPERATURE_THRESHOLD 0.1
37 static std::unique_ptr<DMFC> dmfc(
new DMFC());
57 IUFillNumber(&TemperatureN[0],
"TEMPERATURE",
"Celsius",
"%6.2f", -50, 70., 0., 0.);
62 IUFillNumber(&MaxSpeedN[0],
"Value",
"",
"%6.2f", 100, 1000., 100., 400.);
68 IUFillSwitchVector(&EncoderSP, EncoderS, 2,
getDeviceName(),
"Encoders",
"",
FOCUS_SETTINGS_TAB,
IP_RW,
ISR_1OFMANY, 0,
80 IUFillSwitchVector(&LEDSP, LEDS, 2,
getDeviceName(),
"LED",
"",
FOCUS_SETTINGS_TAB,
IP_RW,
ISR_1OFMANY, 0,
IPS_IDLE);
83 IUFillText(&FirmwareVersionT[0],
"Version",
"Version",
"");
118 int configSwitch = MOTOR_STEPPER;
125 if (configSwitch == MOTOR_DC)
134 MotorTypeS[configSwitch].s =
ISS_ON;
169 setMotorType((MotorTypeS[MOTOR_DC].s ==
ISS_ON) ? MOTOR_DC : MOTOR_STEPPER);
175 "Error retrieving data from %s, please ensure device is powered and the port is correct.", this->
getDeviceName());
182 return "Pegasus DMFC";
187 int nbytes_written = 0, nbytes_read = 0, rc = -1;
197 tcflush(
PortFD, TCIOFLUSH);
214 res[nbytes_read - 1] = 0;
217 if( res[nbytes_read - 2] ==
'\r') res[nbytes_read - 2] = 0;
221 tcflush(
PortFD, TCIOFLUSH);
223 if((strstr(res,
"OK_DMFCN") !=
nullptr) || (strstr(res,
"OK_SMFC") !=
nullptr) || (strstr(res,
"OK_PRDG") !=
nullptr))
232 int nbytes_written = 0, rc = -1;
235 snprintf(
cmd, 16,
"W:%ud", ticks);
249 this->ignoreResponse();
254 bool DMFC::moveAbsolute(uint32_t newPosition)
256 int nbytes_written = 0, rc = -1;
259 snprintf(
cmd, 16,
"M:%ud", newPosition);
269 LOGF_ERROR(
"Absolute move error: %s.", errstr);
273 this->ignoreResponse();
278 bool DMFC::moveRelative(
int relativePosition)
280 int nbytes_written = 0, rc = -1;
283 snprintf(
cmd, 16,
"G:%d", relativePosition);
293 LOGF_ERROR(
"Relative move error: %s.", errstr);
297 this->ignoreResponse();
307 if (!strcmp(name, MotorTypeSP.
name))
317 if (MotorTypeS[MOTOR_DC].s ==
ISS_ON)
323 LOG_INFO(
"Motor type changed. Please restart driver for this change to take effect.");
330 if (!strcmp(name, EncoderSP.
name))
333 bool rc = setEncodersEnabled(EncoderS[ENCODERS_ON].s ==
ISS_ON);
340 if (!strcmp(name, LEDSP.
name))
343 bool rc = setLedEnabled(LEDS[LED_ON].s ==
ISS_ON);
352 bool DMFC::ISNewNumber(
const char *dev,
const char *name,
double values[],
char *names[],
int n)
357 if (strcmp(name, MaxSpeedNP.
name) == 0)
360 bool rc = setMaxSpeed(MaxSpeedN[0].value);
370 void DMFC::ignoreResponse()
377 bool DMFC::updateFocusParams()
379 int nbytes_written = 0, nbytes_read = 0, rc = -1;
388 tcflush(
PortFD, TCIOFLUSH);
393 LOGF_ERROR(
"GetFocusParams error: %s.", errstr);
401 LOGF_ERROR(
"GetFocusParams error: %s.", errstr);
405 res[nbytes_read - 1] = 0;
408 if( res[nbytes_read - 2] ==
'\r') res[nbytes_read - 2] = 0;
412 tcflush(
PortFD, TCIOFLUSH);
414 char *token = std::strtok(res,
":");
418 if (token ==
nullptr || ((strstr(token,
"OK_DMFCN") ==
nullptr) && (strstr(token,
"OK_SMFC") ==
nullptr)
419 && (strstr(token,
"OK_PRDG") ==
nullptr)))
421 LOGF_ERROR(
"Invalid status response. %s", res);
426 token = std::strtok(
nullptr,
":");
428 if (token ==
nullptr)
434 if (FirmwareVersionT[0].text ==
nullptr || strcmp(FirmwareVersionT[0].text, token))
442 token = std::strtok(
nullptr,
":");
444 if (token ==
nullptr)
446 LOG_ERROR(
"Invalid motor mode response.");
450 int motorType = atoi(token);
453 if (motorType >= 0 && motorType <= 1)
458 MotorTypeS[MOTOR_DC].s = (motorType == 0) ?
ISS_ON :
ISS_OFF;
459 MotorTypeS[MOTOR_STEPPER].s = (motorType == 1) ?
ISS_ON :
ISS_OFF;
465 token = std::strtok(
nullptr,
":");
467 if (token ==
nullptr)
469 LOG_ERROR(
"Invalid temperature response.");
473 double temperature = atof(token);
474 if (temperature == -127)
483 TemperatureN[0].value = temperature;
490 token = std::strtok(
nullptr,
":");
492 if (token ==
nullptr)
498 currentPosition = atoi(token);
506 token = std::strtok(
nullptr,
":");
508 if (token ==
nullptr)
510 LOG_ERROR(
"Invalid moving status response.");
514 isMoving = (token[0] ==
'1');
517 token = std::strtok(
nullptr,
":");
519 if (token ==
nullptr)
525 int ledStatus = atoi(token);
526 if (ledStatus >= 0 && ledStatus <= 1)
529 LEDS[ledStatus].s =
ISS_ON;
535 token = std::strtok(
nullptr,
":");
537 if (token ==
nullptr)
543 int reverseStatus = atoi(token);
544 if (reverseStatus >= 0 && reverseStatus <= 1)
554 token = std::strtok(
nullptr,
":");
556 if (token ==
nullptr)
562 int encoderStatus = atoi(token);
563 if (encoderStatus >= 0 && encoderStatus <= 1)
566 EncoderS[encoderStatus].s =
ISS_ON;
572 token = std::strtok(
nullptr,
":");
574 if (token ==
nullptr)
580 int backlash = atoi(token);
584 LOG_WARN(
"Backlash value is zero, disabling backlash switch...");
612 bool DMFC::setMaxSpeed(uint16_t speed)
614 int nbytes_written = 0, rc = -1;
617 snprintf(
cmd, 16,
"S:%d", speed);
622 tcflush(
PortFD, TCIOFLUSH);
633 this->ignoreResponse();
639 int nbytes_written = 0, rc = -1;
642 snprintf(
cmd, 16,
"N:%d", enabled ? 1 : 0);
647 tcflush(
PortFD, TCIOFLUSH);
658 this->ignoreResponse();
663 bool DMFC::setLedEnabled(
bool enable)
665 int nbytes_written = 0, rc = -1;
668 snprintf(
cmd, 16,
"L:%d", enable ? 2 : 1);
673 tcflush(
PortFD, TCIOFLUSH);
684 this->ignoreResponse();
688 bool DMFC::setEncodersEnabled(
bool enable)
690 int nbytes_written = 0, rc = -1;
693 snprintf(
cmd, 16,
"E:%d", enable ? 0 : 1);
698 tcflush(
PortFD, TCIOFLUSH);
709 this->ignoreResponse();
715 int nbytes_written = 0, rc = -1;
718 snprintf(
cmd, 16,
"C:%d", steps);
723 tcflush(
PortFD, TCIOFLUSH);
734 this->ignoreResponse();
746 bool DMFC::setMotorType(uint8_t
type)
749 int nbytes_written = 0, rc = -1;
755 snprintf(
cmd, 16,
"R:%d", (
type == MOTOR_STEPPER) ? 1 : 2);
760 tcflush(
PortFD, TCIOFLUSH);
771 this->ignoreResponse();
778 targetPosition = targetTicks;
780 bool rc = moveAbsolute(targetPosition);
792 int relativePosition = ticks * ((dir ==
FOCUS_INWARD) ? -1 : 1);
804 bool rc = updateFocusParams();
810 if (isMoving ==
false)
816 LOG_INFO(
"Focuser reached requested position.");
827 char cmd[2] = {
'H', 0xA };
835 this->ignoreResponse();
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
virtual bool SetFocuserBacklashEnabled(bool enabled) override
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
const char * getDefaultName() override
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
const char * getDeviceName() const
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
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 FocusBacklashNP
ISwitchVectorProperty FocusBacklashSP
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
uint32_t GetCapability() const
GetFocuserCapability returns the capability of the focuser.
ISwitchVectorProperty FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INumber FocusBacklashN[1]
ISwitch FocusBacklashS[2]
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
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.
Connection::Serial * serialConnection
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
#define TEMPERATURE_THRESHOLD
#define FOCUS_SETTINGS_TAB
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
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.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
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 IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text'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.
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#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,...)