39 #include <sys/ioctl.h>
41 static std::unique_ptr<EsattoArco> esattoarco(
new EsattoArco());
63 setConnectionParams();
66 FirmwareTP[ESATTO_FIRMWARE_SN].
fill(
"ESATTO_FIRMWARE_SN",
"Esatto SN",
"");
67 FirmwareTP[ESATTO_FIRMWARE_VERSION].
fill(
"ESATTO_FIRMWARE_VERSION",
"Esatto Firmware",
"");
68 FirmwareTP[ARCO_FIRMWARE_SN].
fill(
"ARCO_FIRMWARE_SN",
"Arco SN",
"");
69 FirmwareTP[ARCO_FIRMWARE_VERSION].
fill(
"VERARCO_FIRMWARE_VERSIONSION",
"Arco Firmware",
"");
77 VoltageNP[VOLTAGE_12V].
fill(
"VOLTAGE_12V",
"12v",
"%.2f", 0, 100, 0., 0.);
78 VoltageNP[VOLTAGE_USB].
fill(
"VOLTAGE_USB",
"USB",
"%.2f", 0, 100, 0., 0.);
82 IUFillNumber(&TemperatureN[TEMPERATURE_MOTOR],
"TEMPERATURE",
"Motor (c)",
"%.2f", -50, 70., 0., 0.);
83 IUFillNumber(&TemperatureN[TEMPERATURE_EXTERNAL],
"TEMPERATURE_ETX",
"External (c)",
"%.2f", -50, 70., 0., 0.);
88 IUFillNumber(&SpeedN[0],
"SPEED",
"steps/s",
"%.f", 0, 7000., 1, 0);
93 IUFillText(&BacklashMessageT[0],
"BACKLASH",
"Backlash stage",
"Press START to measure backlash.");
123 IUFillNumber(&RotatorAbsPosN[0],
"ROTATOR_ABSOLUTE_POSITION",
"Ticks",
"%.f", 0., 100000., 1000., 0.);
127 IUFillSwitch(&RotCalibrationS[ARCO_CALIBRATION_START],
"ARCO_CALIBRATION_START",
"Start",
ISS_OFF);
182 if (getStartupValues())
185 LOG_WARN(
"Failed to inquire parameters. Check logs.");
195 if (updateTemperature())
198 if (updateVoltageIn())
242 LOG_INFO(
"Error retrieving data from device, please ensure focuser is powered and the port is correct.");
251 return "Esatto Arco";
257 bool EsattoArco::updateTemperature()
259 double temperature = 0;
260 if (m_Esatto->getMotorTemp(temperature))
262 TemperatureN[TEMPERATURE_MOTOR].value = temperature;
268 TemperatureN[TEMPERATURE_EXTERNAL].value = -273.15;
269 if (m_Esatto->getExternalTemp(temperature) && temperature > -127)
271 TemperatureN[TEMPERATURE_EXTERNAL].value = temperature;
280 bool EsattoArco::updateMaxLimit()
282 uint32_t maxLimit = 0;
284 if (m_Esatto->getMaxPosition(maxLimit) && maxLimit > 0)
321 return m_Esatto->setBacklash(steps);
327 bool EsattoArco::updatePosition()
331 if (m_Esatto->getAbsolutePosition(steps))
339 RotatorAbsPosN[0].value = arcoPosition;
360 bool EsattoArco::updateVoltageIn()
363 if (m_Esatto->getVoltage12v(voltage))
364 VoltageNP[VOLTAGE_12V].setValue(voltage);
367 if (m_Esatto->getVoltageUSB(voltage))
368 VoltageNP[VOLTAGE_USB].setValue(voltage);
375 bool EsattoArco::isMotionComplete()
378 if (m_Esatto->getCurrentSpeed(speed))
393 if (!strcmp(name, BacklashMeasurementSP.
name))
399 BacklashMeasurementS[current_switch].s =
ISS_ON;
402 if (current_switch == BACKLASH_START)
404 if (bStage == BacklashIdle || bStage == BacklashComplete )
407 LOG_INFO(
"Start Backlash measurement.");
411 IUSaveText(&BacklashMessageT[0],
"Drive the focuser in any direction until focus changes.");
415 bStage = BacklashMinimum;
419 LOG_INFO(
"Already started backlash measure. Proceed to next step.");
420 IUSaveText(&BacklashMessageT[0],
"Already started. Proceed to NEXT.");
424 else if (current_switch == BACKLASH_NEXT)
426 if (bStage == BacklashMinimum)
430 IUSaveText(&BacklashMessageT[0],
"Drive the focuser in the opposite direction, then press NEXT to finish.");
432 bStage = BacklashMaximum;
434 else if (bStage == BacklashMaximum)
444 IUSaveText(&BacklashMessageT[0],
"Backlash Measure Completed.");
447 bStage = BacklashComplete;
449 LOG_INFO(
"Backlash measurement completed");
450 BacklashMeasurementSP.
s =
IPS_OK;
452 BacklashMeasurementS[current_switch].s =
ISS_OFF;
457 IUSaveText(&BacklashMessageT[0],
"Backlash not in progress.");
465 else if (!strcmp(name, FastMoveSP.
name))
470 switch (current_switch)
473 if (!m_Esatto->fastMoveIn())
478 if (!m_Esatto->fastMoveOut())
483 if (!m_Esatto->stop())
495 else if (!strcmp(name, RotatorCalibrationSP.
name))
497 if(m_Arco->calibrate())
499 LOG_INFO(
"Calibrating Arco. Please wait.");
515 else if (strstr(name,
"ROTATOR"))
532 else if (strcmp(name, RotatorAbsPosNP.
name) == 0)
542 LOGF_INFO(
"Rotator moving to %.f steps...", values[0]);
545 else if (strstr(name,
"ROTATOR"))
559 if (m_Esatto->goAbsolutePosition(targetTicks))
574 int relativeTicks = ((dir ==
FOCUS_INWARD) ? -ticks : ticks) * reversed;
575 double newPosition =
FocusAbsPosN[0].value + relativeTicks;
587 return m_Esatto->stop();
602 auto currentRotatorPosition = RotatorAbsPosN[0].value;
603 if (updatePosition())
605 if (std::abs(currentFocusPosition -
FocusAbsPosN[0].value) > 0)
622 if (std::abs(currentRotatorPosition - RotatorAbsPosN[0].value) > 0)
632 LOG_INFO(
"Arco calibration complete.");
634 LOG_INFO(
"Arco position synced to zero.");
649 if (m_TemperatureCounter++ == TEMPERATURE_FREQUENCY)
652 if (updateTemperature())
658 auto current12V = VoltageNP[VOLTAGE_12V].getValue();
659 auto currentUSB = VoltageNP[VOLTAGE_USB].getValue();
660 if (updateVoltageIn())
662 if (std::abs(current12V - VoltageNP[VOLTAGE_12V].getValue()) >= 0.1 ||
663 std::abs(currentUSB - VoltageNP[VOLTAGE_USB].getValue()) >= 0.1)
666 if (VoltageNP[VOLTAGE_12V].getValue() < 11.0)
667 LOG_WARN(
"Please check 12v DC power supply is connected.");
671 m_TemperatureCounter = 0;
680 bool EsattoArco::getStartupValues()
684 if (m_Arco->getMotorInfo(info))
689 info[
"get"][
"MOT2"][
"CAL_MAXPOS"].
get_to(calMax);
690 info[
"get"][
"MOT2"][
"CAL_MINPOS"].
get_to(calMin);
695 LOGF_ERROR(
"Failed to parse info: %s Exception: %s id: %d", info.
dump().c_str(),
699 RotatorAbsPosN[0].min = calMin;
700 RotatorAbsPosN[0].max = calMax;
701 RotatorAbsPosN[0].step = std::abs(calMax - calMin) / 50.0;
709 bool EsattoArco::Ack()
711 std::string serial, firmware;
713 if(initCommandSet() ==
false)
715 LOG_ERROR(
"Failed setting attributes on serial port and init command sets");
719 if (m_Arco->setEnabled(
true) && !m_Arco->isEnabled())
721 LOG_ERROR(
"Failed to enable ARCO rotator. Please check it is powered and connected.");
725 bool rc1 = m_Esatto->getSerialNumber(serial);
726 bool rc2 = m_Esatto->getFirmwareVersion(firmware);
730 FirmwareTP[ESATTO_FIRMWARE_SN].setText(serial);
731 FirmwareTP[ESATTO_FIRMWARE_VERSION].setText(firmware);
732 LOGF_INFO(
"Esatto SN: %s Firmware version: %s", FirmwareTP[ESATTO_FIRMWARE_SN].
getText(),
733 FirmwareTP[ESATTO_FIRMWARE_VERSION].
getText());
738 rc1 = m_Arco->getSerialNumber(serial);
739 rc2 = m_Arco->getFirmwareVersion(firmware);
743 FirmwareTP[ARCO_FIRMWARE_SN].setText(serial);
744 FirmwareTP[ARCO_FIRMWARE_VERSION].setText(firmware);
745 LOGF_INFO(
"Arco SN: %s Firmware version: %s", FirmwareTP[ARCO_FIRMWARE_SN].
getText(),
746 FirmwareTP[ARCO_FIRMWARE_VERSION].
getText());
757 void EsattoArco::setConnectionParams()
766 bool EsattoArco::initCommandSet()
771 LOG_ERROR(
"setTTYFlags: failed getting tty attributes.");
777 LOG_ERROR(
"setTTYFlags: failed setting attributes on serial port.");
791 Focuser::saveConfigItems(fp);
807 newAngle = ( angle > 180 ? 360 - angle : angle * -1);
809 newAngle = ( angle > 180 ? angle - 360 : angle);
821 auto rc = m_Arco->stop();
853 newAngle = ( angle > 180 ? 360 - angle : angle * -1);
855 newAngle = ( angle > 180 ? angle - 360 : angle);
void setWordSize(const uint8_t &value)
setWordSize Set word size to be used in the serial connection. Default 8
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
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.
const char * getDefaultName() override
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
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 saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
virtual bool ReverseRotator(bool enabled) override
ReverseRotator Reverse the direction of the rotator. CW is usually the normal direction,...
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
virtual bool SyncRotator(double angle) override
SyncRotator Set current angle as the supplied angle without moving the rotator.
virtual bool AbortRotator() override
AbortRotator Abort all motion.
virtual bool Handshake() override
perform handshake with device to check communication
const char * getDeviceName() const
INDI::PropertyText getText(const char *name) 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.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
uint16_t getDriverInterface() const
INumberVectorProperty FocusBacklashNP
virtual bool SetFocuserBacklashEnabled(bool enabled)
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
ISwitchVectorProperty FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INumber FocusBacklashN[1]
INumberVectorProperty FocusMaxPosNP
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.
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
const char * getName() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process Rotator switch properties.
bool saveConfigItems(FILE *fp)
saveConfigItems save focuser properties defined in the interface in config file
INumberVectorProperty GotoRotatorNP
void initProperties(const char *groupName)
Initilize Rotator properties. It is recommended to call this function within initProperties() of your...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
SetRotatorCapability sets the Rotator capabilities. All capabilities must be initialized.
ISwitchVectorProperty ReverseRotatorSP
ISwitch ReverseRotatorS[2]
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process Rotator number properties.
Provides interface to implement Rotator functionality.
a class to store JSON values
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
general exception of the basic_json class
const char * what() const noexcept override
returns the explanatory string
const int id
the id of the exception
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
double range360(double r)
range360 Limits an angle to be between 0-360 degrees.
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.
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 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 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 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_WARN(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
const char * CONNECTION_TAB
#define currentTemperature
struct termios tty_setting