bool NFocus::initProperties() { INDI::Focuser::initProperties(); // No speed for nfocus FocusSpeedN[0].min = FocusSpeedN[0].max = FocusSpeedN[0].value = 1; IUUpdateMinMax(&FocusSpeedNP); /* Focuser temperature */ IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", 0, 65000., 0., 10000.); IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE); /* Settings of the Nfocus */ IUFillNumber(&SettingsN[0], "ON time", "ON waiting time", "%6.0f", 10., 250., 0., 73.); IUFillNumber(&SettingsN[1], "OFF time", "OFF waiting time", "%6.0f", 1., 250., 0., 15.); IUFillNumber(&SettingsN[2], "Fast Mode Delay", "Fast Mode Delay", "%6.0f", 0., 255., 0., 9.); IUFillNumberVector(&SettingsNP, SettingsN, 3, getDeviceName(), "FOCUS_SETTINGS", "Settings", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); /* tick scaling factor. Inward dir ticks times this factor is considered to be the same as outward dir tick numbers. This is to compensate for DC motor incapabilities with regards to exact positioning at least a bit on the mass dependent path.... */ IUFillNumber(&InOutScalarN[0], "In/Out Scalar", "In/Out Scalar", "%1.2f", 0., 2., 1., 1.0); IUFillNumberVector(&InOutScalarNP, InOutScalarN, 1, getDeviceName(), "FOCUS_DIRSCALAR", "Direction scaling factor", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); /* Nfocus should stay within these limits */ IUFillNumber(&MinMaxPositionN[0], "MINPOS", "Minimum Tick", "%6.0f", -65000., 65000., 0., -65000.); IUFillNumber(&MinMaxPositionN[1], "MAXPOS", "Maximum Tick", "%6.0f", 1., 65000., 0., 65000.); IUFillNumberVector(&MinMaxPositionNP, MinMaxPositionN, 2, getDeviceName(), "FOCUS_MINMAXPOSITION", "Extrema", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); IUFillNumber(&MaxTravelN[0], "MAXTRAVEL", "Maximum travel", "%6.0f", 1., 64000., 0., 10000.); IUFillNumberVector(&MaxTravelNP, MaxTravelN, 1, getDeviceName(), "FOCUS_MAXTRAVEL", "Max. travel", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); /* Set Nfocus position register to this position */ IUFillNumber(&SyncN[0], "FOCUS_SYNC_OFFSET", "Offset", "%.f", 0, 64000., 0., 0.); IUFillNumberVector(&SyncNP, SyncN, 1, getDeviceName(), "FOCUS_SYNC", "Sync", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE); /* Relative and absolute movement */ FocusRelPosN[0].min = 0; FocusRelPosN[0].max = MinMaxPositionN[1].value; FocusRelPosN[0].value = 1000; FocusRelPosN[0].step = 100; FocusAbsPosN[0].min = MinMaxPositionN[0].min; FocusAbsPosN[0].max = MinMaxPositionN[0].max; FocusAbsPosN[0].value = 0; FocusAbsPosN[0].step = 10000; addAuxControls(); return true; }
void CCDChip::setResolutoin(int x, int y) { XRes = x; YRes = y; ImagePixelSizeN[0].value=x; ImagePixelSizeN[1].value=y; IDSetNumber(ImagePixelSizeNP, NULL); ImageFrameN[FRAME_W].max = x; ImageFrameN[FRAME_H].max = y; IUUpdateMinMax(ImageFrameNP); }
bool NStep::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) { if (dev != nullptr && strcmp(dev, getDeviceName()) == 0) { // Compensation Settings if (!strcmp(name, CompensationSettingsNP.name)) { // Extract values int change = 0, step = 0, backlash = 0, timer = 0; for (int i = 0; i < n; i++) { if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_CHANGE].name)) { change = values[i]; } else if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_STEP].name)) { step = values[i]; } else if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_BACKLASH].name)) { backlash = values[i]; } else if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_TIMER].name)) { timer = values[i]; } } // Try to update settings if (setCompensationSettings(change, step, backlash, timer)) { IUUpdateNumber(&CompensationSettingsNP, values, names, n); CompensationSettingsNP.s = IPS_OK; } else { CompensationSettingsNP.s = IPS_ALERT; } IDSetNumber(&CompensationSettingsNP, nullptr); return true; } // Stepping Phase if (!strcmp(name, SteppingPhaseNP.name)) { if (setSteppingPhase(static_cast<uint8_t>(values[0]))) { IUUpdateNumber(&SteppingPhaseNP, values, names, n); SteppingPhaseNP.s = IPS_OK; } else SteppingPhaseNP.s = IPS_ALERT; IDSetNumber(&SteppingPhaseNP, nullptr); return true; } // Max Speed if (!strcmp(name, MaxSpeedNP.name)) { if (setMaxSpeed(static_cast<uint8_t>(values[0]))) { IUUpdateNumber(&MaxSpeedNP, values, names, n); MaxSpeedNP.s = IPS_OK; // We must update the Min/Max of focus speed FocusSpeedN[0].max = values[0]; IUUpdateMinMax(&FocusSpeedNP); } else { MaxSpeedNP.s = IPS_ALERT; } IDSetNumber(&MaxSpeedNP, nullptr); return true; } } return INDI::Focuser::ISNewNumber(dev, name, values, names, n); }
bool QSICCD::setupParams() { string name,model; double temperature; double pixel_size_x,pixel_size_y; long sub_frame_x,sub_frame_y; try { QSICam.get_Name(name); QSICam.get_ModelNumber(model); QSICam.get_PixelSizeX(&pixel_size_x); QSICam.get_PixelSizeY(&pixel_size_y); QSICam.get_NumX(&sub_frame_x); QSICam.get_NumY(&sub_frame_y); QSICam.get_CCDTemperature(&temperature); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "Setup Params failed. %s.", err.what()); return false; } DEBUGF(INDI::Logger::DBG_SESSION, "The CCD Temperature is %f.", temperature); TemperatureN[0].value = temperature; /* CCD chip temperatre (degrees C) */ IDSetNumber(&TemperatureNP, NULL); SetCCDParams(sub_frame_x, sub_frame_y, 16, pixel_size_x, pixel_size_y); imageWidth = PrimaryCCD.getSubW(); imageHeight = PrimaryCCD.getSubH(); int nbuf; nbuf=PrimaryCCD.getXRes()*PrimaryCCD.getYRes() * PrimaryCCD.getBPP()/8; // this is pixel count nbuf+=512; // leave a little extra at the end PrimaryCCD.setFrameBufferSize(nbuf); try { QSICam.get_Name(name); } catch (std::runtime_error& err) { DEBUGF(INDI::Logger::DBG_ERROR, "get_Name() failed. %s.", err.what()); return false; } DEBUGF(INDI::Logger::DBG_SESSION, "%s", name.c_str()); int filter_count; try { QSICam.get_FilterCount(filter_count); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_SESSION, "get_FilterCount() failed. %s.", err.what()); return false; } DEBUGF(INDI::Logger::DBG_SESSION,"The filter count is %d", filter_count); FilterSlotN[0].max = filter_count; FilterSlotNP.s = IPS_OK; IUUpdateMinMax(&FilterSlotNP); IDSetNumber(&FilterSlotNP, NULL); FilterSP.s = IPS_OK; IDSetSwitch(&FilterSP,NULL); GetFilterNames(FILTER_TAB); double minDuration=0; try { QSICam.get_MinExposureTime(&minDuration); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_ERROR, "get_MinExposureTime() failed. %s.", err.what()); return false; } PrimaryCCD.setMinMaxStep("CCD_EXPOSURE", "CCD_EXPOSURE_VALUE", minDuration, 3600, 1, true); bool coolerOn=false; try { QSICam.get_CoolerOn(&coolerOn); } catch (std::runtime_error err) { CoolerSP.s = IPS_IDLE; CoolerS[0].s = ISS_OFF; CoolerS[1].s = ISS_ON; DEBUGF(INDI::Logger::DBG_ERROR, "Error: CoolerOn() failed. %s.", err.what()); IDSetSwitch(&CoolerSP, NULL); return false; } CoolerS[0].s = coolerOn ? ISS_ON : ISS_OFF; CoolerS[1].s = coolerOn ? ISS_OFF : ISS_ON; CoolerSP.s = IPS_OK; IDSetSwitch(&CoolerSP, NULL); QSICamera::CameraGain cGain = QSICamera::CameraGainAuto; canSetGain = false; QSICam.get_CanSetGain(&canSetGain); if (canSetGain) { try { QSICam.get_CameraGain(&cGain); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support gain. %s.", err.what()); canSetGain = false; } if (canSetGain) { IUResetSwitch(&GainSP); GainS[cGain].s = ISS_ON; defineSwitch(&GainSP); } } QSICamera::AntiBloom cAB = QSICamera::AntiBloomNormal; canSetAB = true; try { QSICam.get_AntiBlooming(&cAB); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support AntiBlooming control. %s.", err.what()); canSetAB = false; } if (canSetAB) { IUResetSwitch(&ABSP); ABS[cAB].s = ISS_ON; defineSwitch(&ABSP); } QSICamera::FanMode fMode = QSICamera::fanOff; canControlFan = true; try { QSICam.get_FanMode(fMode); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support fan control. %s.", err.what()); canControlFan = false; } if (canControlFan) { IUResetSwitch(&FanSP); FanS[fMode].s = ISS_ON; defineSwitch(&FanSP); } canChangeReadoutSpeed = true; QSICamera::ReadoutSpeed cReadoutSpeed; try { QSICam.get_ReadoutSpeed(cReadoutSpeed); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support changing readout speed. %s.", err.what()); canChangeReadoutSpeed = false; } if (canChangeReadoutSpeed) { // get_ReadoutSpeed succeeds even if the camera does not support that, so the only way to make sure is to set it try { QSICam.put_ReadoutSpeed(cReadoutSpeed); } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support changing readout speed. %s.", err.what()); canChangeReadoutSpeed = false; } if (canChangeReadoutSpeed) { IUResetSwitch(&ReadOutSP); ReadOutS[cReadoutSpeed].s = ISS_ON; defineSwitch(&ReadOutSP); } } // Can flush canFlush = false; try { QSICam.put_PreExposureFlush(QSICamera::FlushNormal); canFlush = true; } catch (std::runtime_error err) { DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not pre-exposure flushing %s.", err.what()); canFlush = false; } return true; }
bool NFocus::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) { int nset = 0, i = 0; if (dev != nullptr && strcmp(dev, getDeviceName()) == 0) { if (strcmp(name, SettingsNP.name) == 0) { /* new speed */ double new_onTime = 0; double new_offTime = 0; double new_fastDelay = 0; int ret = -1; for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the SettingsNP property */ INumber *eqp = IUFindNumber(&SettingsNP, names[i]); /* If the number found is (SettingsN[0]) then process it */ if (eqp == &SettingsN[0]) { new_onTime = (values[i]); nset += static_cast<int>(new_onTime >= 10 && new_onTime <= 250); } else if (eqp == &SettingsN[1]) { new_offTime = (values[i]); nset += static_cast<int>(new_offTime >= 1 && new_offTime <= 250); } else if (eqp == &SettingsN[2]) { new_fastDelay = (values[i]); nset += static_cast<int>(new_fastDelay >= 1 && new_fastDelay <= 9); } } /* Did we process the three numbers? */ if (nset == 3) { if ((ret = updateNFMotorSettings(&new_onTime, &new_offTime, &new_fastDelay)) < 0) { IDSetNumber(&SettingsNP, "Changing to new settings failed"); return false; } currentOnTime = new_onTime; currentOffTime = new_offTime; currentFastDelay = new_fastDelay; SettingsNP.s = IPS_OK; IDSetNumber(&SettingsNP, "Motor settings are now %3.0f %3.0f %3.0f", currentOnTime, currentOffTime, currentFastDelay); return true; } else { /* Set property state to idle */ SettingsNP.s = IPS_IDLE; IDSetNumber(&SettingsNP, "Settings absent or bogus."); return false; } } if (strcmp(name, InOutScalarNP.name) == 0) { double new_ioscalar = 0; for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the InOutScalarNP property */ INumber *eqp = IUFindNumber(&InOutScalarNP, names[i]); /* If the number found is SetBacklash (SetBacklashN[0]) then process it */ if (eqp == &InOutScalarN[0]) { new_ioscalar = (values[i]); /* limits */ nset += static_cast<int>(new_ioscalar >= 0 && new_ioscalar <= 2); } if (nset == 1) { /* Set the nfocus state to BUSY */ InOutScalarNP.s = IPS_BUSY; /* kraemerf IDSetNumber(&InOutScalarNP, nullptr); if(( ret= updateNFInOutScalar(&new_ioscalar)) < 0) { InOutScalarNP.s = IPS_IDLE; IDSetNumber(&InOutScalarNP, "Setting new in/out scalar failed."); return false ; } */ currentInOutScalar = new_ioscalar; InOutScalarNP.s = IPS_OK; IDSetNumber(&InOutScalarNP, "Direction Scalar is now %1.2f", currentInOutScalar); return true; } else { InOutScalarNP.s = IPS_IDLE; IDSetNumber(&InOutScalarNP, "Need exactly one parameter."); return false; } } } if (strcmp(name, MinMaxPositionNP.name) == 0) { /* new positions */ double new_min = 0; double new_max = 0; for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the MinMaxPositionNP property */ INumber *mmpp = IUFindNumber(&MinMaxPositionNP, names[i]); /* If the number found is (MinMaxPositionN[0]) then process it */ if (mmpp == &MinMaxPositionN[0]) { new_min = (values[i]); nset += static_cast<int>(new_min >= 1 && new_min <= 65000); } else if (mmpp == &MinMaxPositionN[1]) { new_max = (values[i]); nset += static_cast<int>(new_max >= 1 && new_max <= 65000); } } /* Did we process the two numbers? */ if (nset == 2) { /* Set the nfocus state to BUSY */ MinMaxPositionNP.s = IPS_BUSY; currentMinPosition = new_min; currentMaxPosition = new_max; MinMaxPositionNP.s = IPS_OK; IDSetNumber(&MinMaxPositionNP, "Minimum and Maximum settings are now %3.0f %3.0f", currentMinPosition, currentMaxPosition); return true; } else { /* Set property state to idle */ MinMaxPositionNP.s = IPS_IDLE; IDSetNumber(&MinMaxPositionNP, "Minimum and maximum limits absent or bogus."); return false; } } if (strcmp(name, MaxTravelNP.name) == 0) { double new_maxt = 0; int ret = -1; for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the MinMaxPositionNP property */ INumber *mmpp = IUFindNumber(&MaxTravelNP, names[i]); /* If the number found is (MaxTravelN[0]) then process it */ if (mmpp == &MaxTravelN[0]) { new_maxt = (values[i]); nset += static_cast<int>(new_maxt >= 1 && new_maxt <= 64000); } } /* Did we process the one number? */ if (nset == 1) { IDSetNumber(&MinMaxPositionNP, nullptr); if ((ret = setNFMaxPosition(&new_maxt)) < 0) { MaxTravelNP.s = IPS_IDLE; IDSetNumber(&MaxTravelNP, "Changing to new maximum travel failed"); return false; } currentMaxTravel = new_maxt; MaxTravelNP.s = IPS_OK; FocusAbsPosN[0].max = currentMaxTravel; IUUpdateMinMax(&FocusAbsPosNP); IDSetNumber(&MaxTravelNP, "Maximum travel is now %3.0f", currentMaxTravel); return true; } else { /* Set property state to idle */ MaxTravelNP.s = IPS_IDLE; IDSetNumber(&MaxTravelNP, "Maximum travel absent or bogus."); return false; } } // Sync if (strcmp(name, SyncNP.name) == 0) { double new_apos = values[0]; int rc = 0; if ((new_apos < currentMinPosition) || (new_apos > currentMaxPosition)) { SyncNP.s = IPS_ALERT; IDSetNumber(&SyncNP, "Value out of limits %5.0f", new_apos); return false; } if ((rc = syncNF(&new_apos)) < 0) { SyncNP.s = IPS_ALERT; IDSetNumber(&SyncNP, "Read out of the set position to %3d failed.", rc); return false; } DEBUGF(INDI::Logger::DBG_DEBUG, "Focuser sycned to %g ticks", new_apos); SyncN[0].value = new_apos; SyncNP.s = IPS_OK; IDSetNumber(&SyncNP, nullptr); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } } return INDI::Focuser::ISNewNumber(dev, name, values, names, n); }
bool FocuserInterface::processNumber(const char * dev, const char * name, double values[], char * names[], int n) { // Move focuser based on requested timeout if (!strcmp(name, FocusTimerNP.name)) { FocusDirection dir; int speed; int t; // first we get all the numbers just sent to us IUUpdateNumber(&FocusTimerNP, values, names, n); // Now lets find what we need for this move speed = FocusSpeedN[0].value; if (FocusMotionS[0].s == ISS_ON) dir = FOCUS_INWARD; else dir = FOCUS_OUTWARD; t = FocusTimerN[0].value; lastTimerValue = t; FocusTimerNP.s = MoveFocuser(dir, speed, t); IDSetNumber(&FocusTimerNP, nullptr); return true; } // Set variable focus speed if (!strcmp(name, FocusSpeedNP.name)) { FocusSpeedNP.s = IPS_OK; int current_speed = FocusSpeedN[0].value; IUUpdateNumber(&FocusSpeedNP, values, names, n); if (SetFocuserSpeed(FocusSpeedN[0].value) == false) { FocusSpeedN[0].value = current_speed; FocusSpeedNP.s = IPS_ALERT; } // Update client display IDSetNumber(&FocusSpeedNP, nullptr); return true; } // Update Maximum Position allowed if (!strcmp(name, FocusMaxPosNP.name)) { uint32_t maxTravel = rint(values[0]); if (SetFocuserMaxPosition(maxTravel)) { IUUpdateNumber(&FocusMaxPosNP, values, names, n); FocusAbsPosN[0].max = FocusSyncN[0].max = FocusMaxPosN[0].value; FocusAbsPosN[0].step = FocusSyncN[0].step = FocusMaxPosN[0].value / 50.0; FocusAbsPosN[0].min = FocusSyncN[0].min = 0; FocusRelPosN[0].max = FocusMaxPosN[0].value / 2; FocusRelPosN[0].step = FocusMaxPosN[0].value / 100.0; FocusRelPosN[0].min = 0; IUUpdateMinMax(&FocusAbsPosNP); IUUpdateMinMax(&FocusRelPosNP); IUUpdateMinMax(&FocusSyncNP); FocusMaxPosNP.s = IPS_OK; } else FocusMaxPosNP.s = IPS_ALERT; IDSetNumber(&FocusMaxPosNP, nullptr); return true; } // Sync if (!strcmp(name, FocusSyncNP.name)) { if (SyncFocuser(rint(values[0]))) { FocusSyncN[0].value = FocusAbsPosN[0].value = rint(values[0]); FocusSyncNP.s = IPS_OK; IDSetNumber(&FocusSyncNP, nullptr); IDSetNumber(&FocusAbsPosNP, nullptr); } else { FocusSyncNP.s = IPS_ALERT; IDSetNumber(&FocusSyncNP, nullptr); } return true; } // Update Absolute Focuser Position if (!strcmp(name, FocusAbsPosNP.name)) { int newPos = rint(values[0]); if (newPos < FocusAbsPosN[0].min) { FocusAbsPosNP.s = IPS_ALERT; IDSetNumber(&FocusAbsPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min); return false; } else if (newPos > FocusAbsPosN[0].max) { FocusAbsPosNP.s = IPS_ALERT; IDSetNumber(&FocusAbsPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max); return false; } IPState ret; if ((ret = MoveAbsFocuser(newPos)) == IPS_OK) { FocusAbsPosNP.s = IPS_OK; IUUpdateNumber(&FocusAbsPosNP, values, names, n); DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser moved to position %d", newPos); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } else if (ret == IPS_BUSY) { FocusAbsPosNP.s = IPS_BUSY; DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser is moving to position %d", newPos); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } FocusAbsPosNP.s = IPS_ALERT; DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position."); IDSetNumber(&FocusAbsPosNP, nullptr); return false; } // Update Relative focuser steps. This moves the focuser CW/CCW by this number of steps. if (!strcmp(name, FocusRelPosNP.name)) { int newPos = rint(values[0]); if (newPos <= 0) { DEBUGDEVICE(dev, Logger::DBG_ERROR, "Relative ticks value must be greater than zero."); FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); return false; } IPState ret; if (CanAbsMove()) { if (FocusMotionS[0].s == ISS_ON) { if (FocusAbsPosN[0].value - newPos < FocusAbsPosN[0].min) { FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min); return false; } } else { if (FocusAbsPosN[0].value + newPos > FocusAbsPosN[0].max) { FocusRelPosNP.s = IPS_ALERT; IDSetNumber(&FocusRelPosNP, nullptr); DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max); return false; } } } if ((ret = MoveRelFocuser((FocusMotionS[0].s == ISS_ON ? FOCUS_INWARD : FOCUS_OUTWARD), newPos)) == IPS_OK) { FocusRelPosNP.s = FocusAbsPosNP.s = IPS_OK; IUUpdateNumber(&FocusRelPosNP, values, names, n); IDSetNumber(&FocusRelPosNP, "Focuser moved %d steps %s", newPos, FocusMotionS[0].s == ISS_ON ? "inward" : "outward"); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } else if (ret == IPS_BUSY) { IUUpdateNumber(&FocusRelPosNP, values, names, n); FocusRelPosNP.s = FocusAbsPosNP.s = IPS_BUSY; IDSetNumber(&FocusAbsPosNP, "Focuser is moving %d steps %s...", newPos, FocusMotionS[0].s == ISS_ON ? "inward" : "outward"); IDSetNumber(&FocusAbsPosNP, nullptr); return true; } FocusRelPosNP.s = IPS_ALERT; DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position."); IDSetNumber(&FocusRelPosNP, nullptr); return false; } return false; }
bool NFocus::initProperties() { INDI::Focuser::initProperties(); // No speed for nfocus FocusSpeedN[0].min = FocusSpeedN[0].max = FocusSpeedN[0].value = 1; IUUpdateMinMax(&FocusSpeedNP); /* Port */ IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyACM0"); IUFillTextVector(&PortTP, PortT, 1, getDeviceName(), "DEVICE_PORT", "Ports", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE); /* Focuser temperature */ IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", 0, 65000., 0., 10000.); IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE); /* Timed move Settings */ IUFillNumber(&FocusTimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%5.0f",0.0,10000.0,10.0,10000.0); IUFillNumberVector(&FocusTimerNP,FocusTimerN,1,getDeviceName(),"FOCUS_TIMER","Timer",MAIN_CONTROL_TAB,IP_RW,60,IPS_OK); /* Settings of the Nfocus */ IUFillNumber(&SettingsN[0], "ON time", "ON waiting time", "%6.0f", 10., 250., 0., 73.); IUFillNumber(&SettingsN[1], "OFF time", "OFF waiting time", "%6.0f", 1., 250., 0., 15.); IUFillNumber(&SettingsN[2], "Fast Mode Delay", "Fast Mode Delay", "%6.0f", 0., 255., 0., 9.); IUFillNumberVector(&SettingsNP, SettingsN, 3, getDeviceName(), "FOCUS_SETTINGS", "Settings", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); /* tick scaling factor. Inward dir ticks times this factor is considered to be the same as outward dir tick numbers. This is to compensate for DC motor incapabilities with regards to exact positioning at least a bit on the mass dependent path.... */ IUFillNumber(&InOutScalarN[0], "In/Out Scalar", "In/Out Scalar", "%1.2f", 0., 2., 1., 1.0); IUFillNumberVector(&InOutScalarNP, InOutScalarN, 1, getDeviceName(), "FOCUS_DIRSCALAR", "Direction scaling factor", OPTIONS_TAB, IP_RW, 0, IPS_IDLE ); /* Nfocus should stay within these limits */ IUFillNumber(&MinMaxPositionN[0], "MINPOS", "Minimum Tick", "%6.0f", -65000., 65000., 0., -65000. ); IUFillNumber(&MinMaxPositionN[1], "MAXPOS", "Maximum Tick", "%6.0f", 1., 65000., 0., 65000.); IUFillNumberVector(&MinMaxPositionNP, MinMaxPositionN, 2, getDeviceName(), "FOCUS_MINMAXPOSITION", "Extrema", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); IUFillNumber(&MaxTravelN[0], "MAXTRAVEL", "Maximum travel", "%6.0f", 1., 64000., 0., 10000.); IUFillNumberVector(&MaxTravelNP, MaxTravelN, 1, getDeviceName(), "FOCUS_MAXTRAVEL", "Max. travel", OPTIONS_TAB, IP_RW, 0, IPS_IDLE ); /* Set Nfocus position register to this position */ IUFillNumber(&SetRegisterPositionN[0], "SETPOS", "Position", "%6.0f", 0, 64000., 0., 0. ); IUFillNumberVector(&SetRegisterPositionNP, SetRegisterPositionN, 1, getDeviceName(), "FOCUS_REGISTERPOSITION", "Set register", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); /* Backlash */ IUFillNumber(&SetBacklashN[0], "SETBACKLASH", "Backlash", "%6.0f", -255., 255., 0., 0.); IUFillNumberVector(&SetBacklashNP, SetBacklashN, 1, getDeviceName(), "FOCUS_BACKLASH", "Set Register", OPTIONS_TAB, IP_RW, 0, IPS_IDLE); /* Relative and absolute movement */ FocusRelPosN[0].min = -65000.; FocusRelPosN[0].max = 65000.; FocusRelPosN[0].value = 0; FocusRelPosN[0].step = 100; FocusAbsPosN[0].min = 0.; FocusAbsPosN[0].max = 65000.; FocusAbsPosN[0].value = 0; FocusAbsPosN[0].step = 10000; addDebugControl(); return true; }