31 #define PYXIS_TIMEOUT 3
34 #define SETTINGS_TAB "Settings"
37 #define PYXIS_3INCH_RATE 6
38 #define PYXIS_2INCH_RATE 8
41 #define PYXIS_3INCH_PER_DEG (128)
42 #define PYXIS_2INCH_PER_DEG 14
45 #define POLL_100MS 100
62 IUFillNumber(&RotationRateN[0],
"RATE",
"Rate",
"%.f", 0, 99, 10, 8);
75 IUFillSwitchVector(&PowerSP, PowerS, 2,
getDeviceName(),
"POWER_STATE",
"Power",
SETTINGS_TAB,
IP_RW,
ISR_ATMOST1, 0,
79 IUFillText(&FirmwareT[0],
"FIRMWARE_VERSION",
"Version",
"Unknown");
83 IUFillText(&ModelT[0],
"HARDWARE_MODEL",
"Model",
"Unknown");
97 LOG_INFO(
"Error retrieving data from Pyxis, please ensure Pyxis controller is powered and the port is correct.");
132 void Pyxis::queryParams()
137 int dir = getReverseStatus();
151 std::string sversion = getVersion() ;
156 LOGF_DEBUG(
"queryParms firmware = %s", sversion.c_str()) ;
159 if (atof(sversion.c_str()) >= 3)
162 bool rc = setRotationRate(rate) ;
163 LOGF_DEBUG(
"queryParms rate = %d, firmware = %s", rate, sversion.c_str()) ;
167 RotationRateN[0].value = rate ;
186 const char *
cmd =
"CCLINK";
189 int nbytes_written = 0, nbytes_read = 0, rc = -1;
194 tcflush(
PortFD, TCIOFLUSH);
206 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
212 tcflush(
PortFD, TCIOFLUSH);
216 LOG_ERROR(
"Cannot establish communication. Check power is on and homing is complete.");
227 if (!strcmp(name, RotationRateNP.
name))
229 bool rc = setRotationRate(
static_cast<uint8_t
>(values[0]));
233 RotationRateN[0].value = values[0];
253 if (!strcmp(name, SteppingSP.
name))
257 rc = setSteppingMode(FULL_STEP);
259 rc = setSteppingMode(HALF_STEP);
277 if (!strcmp(name, PowerSP.
name))
283 if (PowerS[POWER_SLEEP].s ==
ISS_OFF)
286 LOG_WARN(
"Controller is not in sleep mode.");
291 rc = wakeupController();
307 bool rc = sleepController();
312 PowerS[POWER_SLEEP].s =
ISS_ON;
313 LOG_INFO(
"Controller in sleep mode. No functions can be used until controller is waken up.");
327 bool Pyxis::setSteppingMode(uint8_t mode)
331 int nbytes_written = 0, rc = -1;
338 tcflush(
PortFD, TCIOFLUSH);
350 bool Pyxis::setRotationRate(uint8_t rate)
353 int nbytes_written = 0, rc = -1;
356 char res[1] = { 0 } ;
357 int nbytes_read = 0 ;
363 tcflush(
PortFD, TCIOFLUSH);
375 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
379 tcflush(
PortFD, TCIOFLUSH);
383 return (res[0] ==
'!');
386 bool Pyxis::sleepController()
388 const char *
cmd =
"CSLEEP";
390 int nbytes_written = 0, rc = -1;
395 tcflush(
PortFD, TCIOFLUSH);
407 bool Pyxis::wakeupController()
409 const char *
cmd =
"CWAKEUP";
412 int nbytes_written = 0, nbytes_read = 0, rc = -1;
417 tcflush(
PortFD, TCIOFLUSH);
429 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
433 tcflush(
PortFD, TCIOFLUSH);
437 return (res[0] ==
'!');
442 const char *
cmd =
"CHOMES";
444 int nbytes_written = 0, rc = -1;
449 tcflush(
PortFD, TCIOFLUSH);
465 int nbytes_written = 0, rc = -1;
468 uint16_t current =
static_cast<uint16_t
>(
GotoRotatorN[0].value) ;
470 targetPA =
static_cast<uint16_t
>(
round(angle));
477 if (current <= 180 && targetPA < 180)
478 direction = (targetPA >= current ? 1 : -1) ;
479 else if (current <= 180 && targetPA > 180)
481 else if (current > 180 && targetPA >= 180)
482 direction = (targetPA >= current ? 1 : -1) ;
483 else if (current > 180 && targetPA < 180)
490 tcflush(
PortFD, TCIOFLUSH);
506 int nbytes_written = 0, rc = -1;
513 tcflush(
PortFD, TCIOFLUSH);
535 if (isMotionComplete())
551 if (!isMotionComplete())
561 if (getPA(PA) && (PA !=
static_cast<uint16_t
>(
GotoRotatorN[0].value)))
570 bool Pyxis::isMotionComplete()
572 int nbytes_read = 0, rc = -1;
576 bool pyxis3inch = atoi(FirmwareT[0].text) >= 3 ;
588 int current =
static_cast<uint16_t
>(
GotoRotatorN[0].value) ;
590 current = current + direction ;
591 if (current < 0) current = 359 ;
592 if (current > 360) current = 1 ;
598 LOGF_DEBUG(
"TTY_OVERFLOW, nbytes_read = %d", nbytes_read) ;
603 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
609 LOG_ERROR(
"Homing failed. Check possible jam.");
610 tcflush(
PortFD, TCIOFLUSH);
622 bool Pyxis::isMotionComplete()
624 int nbytes_read = 0, rc = -1;
631 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
641 else if (res[0] ==
'F')
648 LOG_ERROR(
"Homing failed. Check possible jam.");
649 tcflush(
PortFD, TCIOFLUSH);
656 std::string Pyxis::getVersion()
658 const char *
cmd =
"CVxxxx";
661 int nbytes_written = 0, nbytes_read = 0, rc = -1;
666 tcflush(
PortFD, TCIOFLUSH);
672 return std::string(
"");;
678 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
679 return std::string(
"") ;
682 tcflush(
PortFD, TCIOFLUSH);
687 return std::string(
"");
689 return std::string(res) ;;
693 bool Pyxis::getPA(uint16_t &PA)
695 const char *
cmd =
"CGETPA";
698 int nbytes_written = 0, nbytes_read = 0, rc = -1;
703 tcflush(
PortFD, TCIOFLUSH);
715 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
719 tcflush(
PortFD, TCIOFLUSH);
731 int Pyxis::getReverseStatus()
733 const char *
cmd =
"CMREAD";
736 int nbytes_written = 0, nbytes_read = 0, rc = -1;
741 tcflush(
PortFD, TCIOFLUSH);
753 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
757 tcflush(
PortFD, TCIOFLUSH);
761 return (res[0] ==
'1' ? 1 : 0);
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
const char * getDeviceName() const
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.
INumberVectorProperty GotoRotatorNP
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
ISwitchVectorProperty HomeRotatorSP
ISwitchVectorProperty ReverseRotatorSP
ISwitch ReverseRotatorS[2]
Connection::Serial * serialConnection
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
void setRotatorConnection(const uint8_t &value)
setRotatorConnection Set Rotator connection mode. Child class should call this in the constructor bef...
virtual IPState HomeRotator() override
HomeRotator Go to home 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.
const char * getDefaultName() override
virtual IPState MoveRotator(double angle) override
MoveRotator Go to specific angle.
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.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool ReverseRotator(bool enabled) override
ReverseRotator Reverse the direction of the rotator. CW is usually the normal direction,...
virtual bool Handshake() override
perform handshake with device to check communication
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
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 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 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.
const char * IUFindOnSwitchName(ISState *states, char *names[], int n)
Returns the name of the first ON switch it finds in the supplied arguments.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
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,...)
void IDSetText(const ITextVectorProperty *tvp, const char *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,...)
std::unique_ptr< Pyxis > pyxis(new Pyxis())
#define PYXIS_3INCH_PER_DEG
#define PYXIS_2INCH_PER_DEG
double round(double value, int decimal_places)