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
62 RotationRateNP[0].
fill(
"RATE",
"Rate",
"%.f", 0, 99, 10, 8);
67 SteppingSP[FULL_STEP].
fill(
"FULL_STEP",
"Full",
ISS_OFF);
68 SteppingSP[HALF_STEP].
fill(
"HALF_STEP",
"Half",
ISS_OFF);
73 PowerSP[POWER_SLEEP].
fill(
"POWER_SLEEP",
"Sleep",
ISS_OFF);
74 PowerSP[POWER_WAKEUP].
fill(
"POWER_WAKEUP",
"Wake Up",
ISS_OFF);
79 FirmwareTP[0].
fill(
"FIRMWARE_VERSION",
"Version",
"Unknown");
83 ModelTP[0].
fill(
"HARDWARE_MODEL",
"Model",
"Unknown");
97 LOG_INFO(
"Error retrieving data from Pyxis, please ensure Pyxis controller is powered and the port is correct.");
132void Pyxis::queryParams()
137 int dir = getReverseStatus();
151 std::string sversion = getVersion() ;
152 FirmwareTP[0].setText(sversion.c_str()) ;
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 RotationRateNP[0].setValue(rate) ;
168 RotationRateNP.
apply() ;
170 ModelTP[0].setText(
"Pyxis 3 Inch");
177 ModelTP[0].setText(
"Pyxis 2 Inch") ;
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.");
229 bool rc = setRotationRate(
static_cast<uint8_t
>(values[0]));
233 RotationRateNP[0].setValue(values[0]);
238 RotationRateNP.
apply();
243 return Rotator::ISNewNumber(dev, name, values, names, n);
257 rc = setSteppingMode(FULL_STEP);
259 rc = setSteppingMode(HALF_STEP);
264 SteppingSP.
update(states, names, n);
283 if (PowerSP[POWER_SLEEP].getState() ==
ISS_OFF)
286 LOG_WARN(
"Controller is not in sleep mode.");
291 rc = wakeupController();
307 bool rc = sleepController();
313 LOG_INFO(
"Controller in sleep mode. No functions can be used until controller is waken up.");
324 return Rotator::ISNewSwitch(dev, name, states, names, n);
327bool Pyxis::setSteppingMode(uint8_t mode)
331 int nbytes_written = 0, rc = -1;
338 tcflush(
PortFD, TCIOFLUSH);
350bool 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] ==
'!');
386bool Pyxis::sleepController()
388 const char *
cmd =
"CSLEEP";
390 int nbytes_written = 0, rc = -1;
395 tcflush(
PortFD, TCIOFLUSH);
407bool 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
>(
GotoRotatorNP[0].getValue()) ;
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);
538 if (isMotionComplete())
555 if (!isMotionComplete())
581bool Pyxis::isMotionComplete()
583 int nbytes_read = 0, rc = -1;
587 bool pyxis3inch = atoi(FirmwareTP[0].
getText()) >= 3 ;
599 int current =
static_cast<uint16_t
>(
GotoRotatorNP[0].getValue()) ;
601 current = current + direction ;
602 if (current < 0) current = 359 ;
603 if (current > 360) current = 1 ;
609 LOGF_DEBUG(
"TTY_OVERFLOW, nbytes_read = %d", nbytes_read) ;
614 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
620 LOG_ERROR(
"Homing failed. Check possible jam.");
621 tcflush(
PortFD, TCIOFLUSH);
632bool Pyxis::isMotionComplete()
634 int nbytes_read = 0, rc = -1;
641 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
651 else if (res[0] ==
'F')
658 LOG_ERROR(
"Homing failed. Check possible jam.");
659 tcflush(
PortFD, TCIOFLUSH);
666std::string Pyxis::getVersion()
668 const char *
cmd =
"CVxxxx";
671 int nbytes_written = 0, nbytes_read = 0, rc = -1;
676 tcflush(
PortFD, TCIOFLUSH);
682 return std::string(
"");;
688 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
689 return std::string(
"") ;
692 tcflush(
PortFD, TCIOFLUSH);
697 return std::string(
"");
699 return std::string(res) ;;
703bool Pyxis::getPA(uint16_t &PA)
705 const char *
cmd =
"CGETPA";
708 int nbytes_written = 0, nbytes_read = 0, rc = -1;
713 tcflush(
PortFD, TCIOFLUSH);
725 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
729 tcflush(
PortFD, TCIOFLUSH);
741int Pyxis::getReverseStatus()
743 const char *
cmd =
"CMREAD";
746 int nbytes_written = 0, nbytes_read = 0, rc = -1;
751 tcflush(
PortFD, TCIOFLUSH);
763 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
767 tcflush(
PortFD, TCIOFLUSH);
771 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...
INDI::PropertyText getText(const char *name) const
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 setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
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)
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
INDI::PropertySwitch HomeRotatorSP
INDI::PropertySwitch ReverseRotatorSP
INDI::PropertyNumber GotoRotatorNP
Connection::Serial * serialConnection
virtual bool initProperties() override
Initialize 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
Initialize 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
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
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.
const char * IUFindOnSwitchName(ISState *states, char *names[], int n)
Returns the name of the first ON switch it finds in the supplied arguments.
#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,...)
#define PYXIS_3INCH_PER_DEG
#define PYXIS_2INCH_PER_DEG
std::unique_ptr< Pyxis > pyxis(new Pyxis())
double round(double value, int decimal_places)