diff --git a/drivers.xml b/drivers.xml index 4bfadac863..bb85e52bf5 100644 --- a/drivers.xml +++ b/drivers.xml @@ -683,6 +683,10 @@ indi_pegasusindigo_wheel 1.0 + + indi_ioptron_wheel + 1.0 + diff --git a/drivers/filter_wheel/CMakeLists.txt b/drivers/filter_wheel/CMakeLists.txt index 8975ff93cd..ed6069c164 100644 --- a/drivers/filter_wheel/CMakeLists.txt +++ b/drivers/filter_wheel/CMakeLists.txt @@ -78,3 +78,11 @@ add_executable(indi_pegasusindigo_wheel ${pegasus_indigo_SRC}) target_link_libraries(indi_pegasusindigo_wheel indidriver) install(TARGETS indi_pegasusindigo_wheel RUNTIME DESTINATION bin) + +# ############### iOptron Filter Wheel ################ +SET(ioptron_wheel_SRC + ioptron_wheel.cpp) + +add_executable(indi_ioptron_wheel ${ioptron_wheel_SRC}) +target_link_libraries(indi_ioptron_wheel indidriver) +install(TARGETS indi_ioptron_wheel RUNTIME DESTINATION bin) diff --git a/drivers/filter_wheel/ioptron_wheel.cpp b/drivers/filter_wheel/ioptron_wheel.cpp new file mode 100644 index 0000000000..0201e1f041 --- /dev/null +++ b/drivers/filter_wheel/ioptron_wheel.cpp @@ -0,0 +1,310 @@ +/******************************************************************************* + Copyright(c) 2024 Joe Zhou. All rights reserved. + + iOptron Filter Wheel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*******************************************************************************/ + +#include "ioptron_wheel.h" + +#include "indicom.h" +#include +#include +#include +#include + +#define iEFW_TIMEOUT 4 + +/* +command : +:WMnn# Response: 1 +get position ,nn filter num。 + +:WP# Response: nn# or -1# +get curr position,nn =curr position,if is moving,return -1。 + +:WOnnsnnnnn# Response: 1 +set offset。nn =filter num , snnnnn=offset + +:WFnn# Response: snnnnn# +get offset 。nn = filter num , snnnnn=offset + +“:DeviceInfo#” Response: “nnnnnnnnnnnn#” +This command includes 12 digits. +The 7th and 8th digit means model of filter wheel. +Model number 99 is iEFW-15, 98 is iEFW18 + +:FW1# Response: nnnnnnnnnnnn# +get firmware version + + +*/ + + +static std::unique_ptr iefw_wheel(new iEFW()); + +iEFW::iEFW() +{ + setVersion(1, 0); + setFilterConnection(CONNECTION_SERIAL); +} + +const char *iEFW::getDefaultName() +{ + return "iOptron Wheel"; +} + +bool iEFW::initProperties() +{ + INDI::FilterWheel::initProperties(); +// serialConnection->setDefaultPort("/dev/ttyUSB3"); + serialConnection->setDefaultBaudRate(Connection::Serial::B_115200); + FilterSlotN[0].min = 1; + FilterSlotN[0].max = 8; + FirmwareTP[0].fill("FIRMWARE", "Firmware", "240101240101"); + FirmwareTP.fill(getDeviceName(), "FIRMWARE_ID", "iEFW Firmware", FILTER_TAB, IP_RO, 60, IPS_IDLE); + WheelIDTP[0].fill("MODEL", "Model", "iEFW"); + WheelIDTP.fill(getDeviceName(), "MODEL_ID", "iEFW Model", FILTER_TAB, IP_RO, 60, IPS_IDLE); + return true; +} + +bool iEFW::updateProperties() +{ + INDI::FilterWheel::updateProperties(); + + if (isConnected()) + { + defineProperty(HomeSP); + defineProperty(FirmwareTP); + defineProperty(WheelIDTP); + bool rc1=getiEFWInfo(); + bool rc2=getiEFWfirmwareInfo(); + getFilterPos(); + return (rc1 && rc2); + } + else + { + deleteProperty(HomeSP); + deleteProperty(FirmwareTP); + deleteProperty(WheelIDTP); + } + return true; +} + +bool iEFW::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) +{ + if (dev != nullptr && strcmp(dev, getDeviceName()) == 0) + { + if (HomeSP.isNameMatch(name)) + { + if (getiEFWID()) + { + LOG_INFO("Filter is at home position"); + HomeSP.setState(IPS_OK); + HomeSP.apply(); + } + else + HomeSP.setState(IPS_ALERT); + HomeSP.apply(); + return true; + } + } + + return INDI::FilterWheel::ISNewSwitch(dev, name, states, names, n); +} + +bool iEFW::Handshake() +{ + + return getiEFWID(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +bool iEFW::getiEFWInfo() +{ + int nbytes_written = 0, nbytes_read = 0, rc = -1; + char resp[16]; + int iefwpos, iefwmodel, iefwlast; + sleep(2); + tcflush(PortFD, TCIOFLUSH); + if ( (rc = tty_write(PortFD, ":DeviceInfo#", strlen(":DeviceInfo#"), &nbytes_written)) != TTY_OK) + { + char errstr[MAXRBUF] = {0}; + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "Init send iEFW deviceinfo error: %s.", errstr); + return false; + }; + + if ( (rc = tty_read_section(PortFD, resp, '#', iEFW_TIMEOUT * 2, &nbytes_read)) != TTY_OK) + { + char errstr[MAXRBUF] = {0}; + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "Init read iEFW deviceinfo error: %s.", errstr); + return false; + }; + tcflush(PortFD, TCIOFLUSH); + resp[nbytes_read] = '\0'; + sscanf(resp, "%6d%2d%4d", &iefwpos, &iefwmodel, &iefwlast); + if ((iefwmodel == 98)|| (iefwmodel == 99)) + { + if (iefwmodel==99) + { + FilterSlotN[0].max = 5; + WheelIDTP.setState(IPS_OK); + WheelIDTP[0].setText("iEFW-15"); + WheelIDTP.apply(); + }; + if (iefwmodel==98) + { + FilterSlotN[0].max = 8; + WheelIDTP.setState(IPS_OK); + WheelIDTP[0].setText("iEFW-18"); + WheelIDTP.apply(); + + }; + return true; + } + else + { + LOGF_ERROR( "iEFW getinfo Response: %s", resp); + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////// +bool iEFW::getiEFWfirmwareInfo() +{ + int nbytes_written = 0, nbytes_read = 0, rc = -1; + char errstr[MAXRBUF]; + char resp[16] = {0}; + char iefwfirminfo[16] = {0}; + tcflush(PortFD, TCIOFLUSH); + if ( (rc = tty_write(PortFD, ":FW1#", 5, &nbytes_written)) != TTY_OK) + { + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "get iEFW FiremwareInfo error: %s.", errstr); + } + if ( (rc = tty_read_section(PortFD, resp, '#', iEFW_TIMEOUT, &nbytes_read)) != TTY_OK) + { + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "get iEFW FirmwareInfo error: %s.", errstr); + return false; + } + tcflush(PortFD, TCIOFLUSH); + resp[nbytes_read] = '\0'; + sscanf(resp, "%12s", iefwfirminfo); + FirmwareTP.setState(IPS_OK); + FirmwareTP[0].setText(iefwfirminfo); + FirmwareTP.apply(); + LOGF_DEBUG("Success, response from iEFW is : %s", iefwfirminfo); + return true; +} + +int iEFW::getFilterPos() +{ + int nbytes_written = 0, nbytes_read = 0, rc = -1; + char errstr[MAXRBUF]; + char resp[16] = {0}; + int iefwpos = 1; + tcflush(PortFD, TCIOFLUSH); + if ( (rc = tty_write(PortFD, ":WP#", 4, &nbytes_written)) != TTY_OK) + { + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "send iEFW filter pos Info error: %s.", errstr); + } + if ( (rc = tty_read_section(PortFD, resp, '#', iEFW_TIMEOUT, &nbytes_read)) != TTY_OK) + { + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "read iEFW filter pos Info error: %s.", errstr); + return false; + } + tcflush(PortFD, TCIOFLUSH); + resp[nbytes_read] = '\0'; + LOGF_DEBUG("Success, response from iEFW is : %s", resp); + rc=sscanf(resp, "%2d", &iefwpos); + if (rc > 0) + { + if (iefwpos>=0) + { + CurrentFilter=iefwpos+1; + FilterSlotN[0].value = CurrentFilter; + FilterSlotNP.s = IPS_OK; + return CurrentFilter; + } + else + return -1; + } + else + return 999; + +} + + +bool iEFW::getiEFWID() +{ + return getiEFWInfo(); +} + +bool iEFW::SelectFilter(int f) +{ + int nbytes_written = 0, rc = -1; + char errstr[MAXRBUF]; + // char resp[16] = {0}; + // char iefwposinfo[16] = {0}; + int iefwpos=-1; + char cmd[7]={0}; + if (CurrentFilter == f) + { + SelectFilterDone(CurrentFilter); + return true; + } + f = f - 1; + + if (f < 0 || f > (FilterSlotN[0].max-1)) + return false; + + tcflush(PortFD, TCIOFLUSH); + snprintf(cmd,7, ":WM0%d#", f); + if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK) + { + tty_error_msg(rc, errstr, MAXRBUF); + LOGF_ERROR( "select iEFW send pos Info error: %s.", errstr); + } + tcflush(PortFD, TCIOFLUSH); + // check current position -1 is moving + do + { + usleep(100 * 1000); + iefwpos=getFilterPos(); + } + while (iefwpos == -1); + // return current position to indi + CurrentFilter = f + 1; + SelectFilterDone(CurrentFilter); + FilterSlotNP.s = IPS_OK; + IDSetNumber(&FilterSlotNP, "Selected filter position reached"); + LOGF_DEBUG("CurrentFilter set to %d", CurrentFilter); + return true; +} + +int iEFW::QueryFilter() +{ + return CurrentFilter; +} + diff --git a/drivers/filter_wheel/ioptron_wheel.h b/drivers/filter_wheel/ioptron_wheel.h new file mode 100644 index 0000000000..659348e621 --- /dev/null +++ b/drivers/filter_wheel/ioptron_wheel.h @@ -0,0 +1,51 @@ +/******************************************************************************* + Copyright(c) 2024 Joe Zhou. All rights reserved. + + iOptron Filter Wheel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*******************************************************************************/ + +#pragma once + +#include "indifilterwheel.h" + +class iEFW : public INDI::FilterWheel +{ + public: + iEFW(); + virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override; + + protected: + const char *getDefaultName() override; + bool initProperties() override; + bool updateProperties() override; + bool Handshake() override; + int QueryFilter() override; + bool SelectFilter(int) override; +// void TimerHit() override; + int getFilterPos(); + // Firmware of the iEFW + INDI::PropertyText FirmwareTP {1}; + INDI::PropertyText WheelIDTP {1};; + + private: + + bool getiEFWID(); + bool getiEFWInfo(); + bool getiEFWfirmwareInfo(); + void initOffset(); + INDI::PropertySwitch HomeSP{1}; +}; diff --git a/drivers/focuser/ieaffocus.cpp b/drivers/focuser/ieaffocus.cpp index d698c13831..a1421bf671 100644 --- a/drivers/focuser/ieaffocus.cpp +++ b/drivers/focuser/ieaffocus.cpp @@ -153,7 +153,8 @@ bool iEAFFocus::Ack() tcflush(PortFD, TCIOFLUSH); resp[nbytes_read] = '\0'; sscanf(resp, "%6d%2d%4d", &ieafpos, &ieafmodel, &ieaflast); - if (ieafmodel == 2) + //add iAFS Focuser + if ((ieafmodel == 2)||(ieafmodel == 3)) { return true; }