Пример #1
0
bool QHYCCD::UpdateCCDBin(int hor, int ver)
{
    int ret = QHYCCD_ERROR;

    if (hor != ver)
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Invalid binning mode. Asymmetrical binning not supported.");
        return false;
    }

    if (hor == 3)
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Invalid binning mode. Only 1x1, 2x2, and 4x4 binning modes supported.");
        return false;
    }


    if (hor > 1 && GetCCDCapability() & CCD_HAS_BAYER)
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Binning not supported for color CCDs.");
        return false;
    }

    //PrimaryCCD.setBin(hor,ver);
    //camxbin = hor;
    //camybin = ver;
    //return UpdateCCDFrame(PrimaryCCD.getSubX(), PrimaryCCD.getSubY(), PrimaryCCD.getSubW(), PrimaryCCD.getSubH());

    if(hor == 1 && ver == 1)
    {
        ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN1X1MODE);
    }
    else if(hor == 2 && ver == 2)
    {
        ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN2X2MODE);  
    }
    else if(hor == 3 && ver == 3)
    {
        ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN3X3MODE);
    }
    else if(hor == 4 && ver == 4)
    {
        ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN4X4MODE); 
    }

    if(ret == QHYCCD_SUCCESS)
    {
        PrimaryCCD.setBin(hor,ver);
        camxbin = hor;
        camybin = ver;
        return UpdateCCDFrame(PrimaryCCD.getSubX(), PrimaryCCD.getSubY(), PrimaryCCD.getSubW(), PrimaryCCD.getSubH());
    }

    DEBUGF(INDI::Logger::DBG_ERROR, "SetBin mode failed. Invalid bin requested %dx%d",hor,ver);
    return false;
}
Пример #2
0
bool QHYCCD::UpdateCCDBin(int hor, int ver)
{
    int ret = QHYCCD_ERROR;

    if (hor != ver)
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Invalid binning mode. Asymmetrical binning not supported.");
        return false;
    }

    if (hor == 3)
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Invalid binning mode. Only 1x1, 2x2, and 4x4 binning modes supported.");
        return false;
    }

    if (hor > 1 && GetCCDCapability() & CCD_HAS_BAYER)
    {
        DEBUG(INDI::Logger::DBG_ERROR, "Binning not supported for color CCDs.");
        return false;
    }

    if (useSoftBin)
        ret = QHYCCD_SUCCESS;
    else if (hor == 1 && ver == 1)
    {
        ret = IsQHYCCDControlAvailable(camhandle, CAM_BIN1X1MODE);
    }
    else if (hor == 2 && ver == 2)
    {
        ret = IsQHYCCDControlAvailable(camhandle, CAM_BIN2X2MODE);
    }
    else if (hor == 3 && ver == 3)
    {
        ret = IsQHYCCDControlAvailable(camhandle, CAM_BIN3X3MODE);
    }
    else if (hor == 4 && ver == 4)
    {
        ret = IsQHYCCDControlAvailable(camhandle, CAM_BIN4X4MODE);
    }

    // Binning ALWAYS succeeds
    if (ret != QHYCCD_SUCCESS)
    {
        useSoftBin = true;
    }

    // We always use software binning so QHY binning is always at 1x1
    camxbin = 1;
    camybin = 1;

    PrimaryCCD.setBin(hor, ver);

    return UpdateCCDFrame(PrimaryCCD.getSubX(), PrimaryCCD.getSubY(), PrimaryCCD.getSubW(), PrimaryCCD.getSubH());
}
Пример #3
0
bool QHYCCD::Connect()
{
    unsigned int ret = 0;
    uint32_t cap;

    sim = isSimulation();

    if (sim)
    {
        cap = CCD_CAN_SUBFRAME | CCD_CAN_ABORT | CCD_CAN_BIN | CCD_HAS_COOLER | CCD_HAS_ST4_PORT;
        SetCCDCapability(cap);

        HasUSBTraffic = true;
        HasUSBSpeed   = true;
        HasGain       = true;
        HasOffset     = true;
        HasFilters    = true;

        return true;
    }

    // Query the current CCD cameras. This method makes the driver more robust and
    // it fixes a crash with the new QHC SDK when the INDI driver reopens the same camera
    // with OpenQHYCCD() without a ScanQHYCCD() call before.
    // 2017-12-15 JM: No this method ReleaseQHYCCDResource which ends up clearing handles for multiple
    // cameras
    /*std::vector<std::string> devices = GetDevicesIDs();

    // The CCD device is not available anymore
    if (std::find(devices.begin(), devices.end(), std::string(camid)) == devices.end())
    {
        DEBUGF(INDI::Logger::DBG_ERROR, "Error: Camera %s is not connected", camid);
        return false;
    }*/
    camhandle = OpenQHYCCD(camid);

    if (camhandle != NULL)
    {
        DEBUGF(INDI::Logger::DBG_SESSION, "Connected to %s.", camid);

        cap = CCD_CAN_ABORT | CCD_CAN_SUBFRAME | CCD_HAS_STREAMING;

        // Disable the stream mode before connecting
        ret = SetQHYCCDStreamMode(camhandle, 0);
        if (ret != QHYCCD_SUCCESS)
        {
            DEBUGF(INDI::Logger::DBG_ERROR, "Error: Can not disable stream mode (%d)", ret);
        }
        ret = InitQHYCCD(camhandle);
        if (ret != QHYCCD_SUCCESS)
        {
            DEBUGF(INDI::Logger::DBG_ERROR, "Error: Init Camera failed (%d)", ret);
            return false;
        }

        ret = IsQHYCCDControlAvailable(camhandle, CAM_MECHANICALSHUTTER);
        if (ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_HAS_SHUTTER;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Shutter Control: %s", cap & CCD_HAS_SHUTTER ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_COOLER);
        if (ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_HAS_COOLER;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Cooler Control: %s", cap & CCD_HAS_COOLER ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_ST4PORT);
        if (ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_HAS_ST4_PORT;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Guider Port Control: %s", cap & CCD_HAS_ST4_PORT ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_SPEED);
        if (ret == QHYCCD_SUCCESS)
        {
            HasUSBSpeed = true;

            // Force a certain speed on initialization of QHY5PII-C:
            // CONTROL_SPEED = 2 - Fastest, but the camera gets stuck with long exposure times.
            // CONTROL_SPEED = 1 - This is safe with the current driver.
            // CONTROL_SPEED = 0 - This is safe, but slower than 1.
            if (isQHY5PIIC())
                SetQHYCCDParam(camhandle, CONTROL_SPEED, 1);
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "USB Speed Control: %s", HasUSBSpeed ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_GAIN);
        if (ret == QHYCCD_SUCCESS)
        {
            HasGain = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Gain Control: %s", HasGain ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_OFFSET);
        if (ret == QHYCCD_SUCCESS)
        {
            HasOffset = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Offset Control: %s", HasOffset ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_CFWPORT);
        if (ret == QHYCCD_SUCCESS)
        {
            HasFilters = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Has Filters: %s", HasFilters ? "True" : "False");

        // Using software binning
        cap |= CCD_CAN_BIN;
        camxbin = 1;
        camybin = 1;

        // Always use INDI software binning
        //useSoftBin = true;


        ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN1X1MODE);
        if(ret == QHYCCD_SUCCESS)
        {
            camxbin = 1;
            camybin = 1;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Bin 1x1: %s", (ret == QHYCCD_SUCCESS) ? "True" : "False");

        ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN2X2MODE);
        ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN3X3MODE);
        ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN4X4MODE);

        // Only use software binning if NOT supported by hardware
        //useSoftBin = !(ret == QHYCCD_SUCCESS);

        DEBUGF(INDI::Logger::DBG_DEBUG, "Binning Control: %s", cap & CCD_CAN_BIN ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CONTROL_USBTRAFFIC);
        if (ret == QHYCCD_SUCCESS)
        {
            HasUSBTraffic = true;
            // Force the USB traffic value to 30 on initialization of QHY5PII-C otherwise
            // the camera has poor transfer speed.
            if (isQHY5PIIC())
                SetQHYCCDParam(camhandle, CONTROL_USBTRAFFIC, 30);
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "USB Traffic Control: %s", HasUSBTraffic ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle, CAM_COLOR);
        //if(ret != QHYCCD_ERROR && ret != QHYCCD_ERROR_NOTSUPPORT)
        if (ret != QHYCCD_ERROR)
        {
            if (ret == BAYER_GB)
                IUSaveText(&BayerT[2], "GBRG");
            else if (ret == BAYER_GR)
                IUSaveText(&BayerT[2], "GRBG");
            else if (ret == BAYER_BG)
                IUSaveText(&BayerT[2], "BGGR");
            else
                IUSaveText(&BayerT[2], "RGGB");

            DEBUGF(INDI::Logger::DBG_DEBUG, "Color CCD: %s", BayerT[2].text);

            cap |= CCD_HAS_BAYER;
        }

        SetCCDCapability(cap);

        terminateThread = false;

        pthread_create(&primary_thread, NULL, &streamVideoHelper, this);
        return true;
    }

    DEBUGF(INDI::Logger::DBG_ERROR, "Connecting to CCD failed (%s)", camid);

    return false;
}
Пример #4
0
bool Camera_QHY::Connect(const wxString& camId)
{
    if (QHYSDKInit())
    {
        wxMessageBox(_("Failed to initialize QHY SDK"));
        return true;
    }

    int num_cams = ScanQHYCCD();
    std::vector<std::string> camids;

    for (int i = 0; i < num_cams; i++)
    {
        char camid[32] = "";
        GetQHYCCDId(i, camid);
        bool st4 = false;
        qhyccd_handle *h = OpenQHYCCD(camid);
        if (h)
        {
            uint32_t ret = IsQHYCCDControlAvailable(h, CONTROL_ST4PORT);
            if (ret == QHYCCD_SUCCESS)
                st4 = true;
                //CloseQHYCCD(h); // CloseQHYCCD() would proform a reset, so the other software that use QHY camera would be impacted.
                                  // Do not call this,would not cause memory leak.The SDk has already process this.
        }
        Debug.Write(wxString::Format("QHY cam [%d] %s avail %s st4 %s\n", i, camid, h ? "Yes" : "No", st4 ? "Yes" : "No"));
        if (st4)
            camids.push_back(camid);
    }

    if (camids.size() == 0)
    {
        wxMessageBox(_("No compatible QHY cameras found"));
        return true;
    }

    std::string camid;

    if (camids.size() > 1)
    {
        wxArrayString names;
        int n = 1;
        for (auto it = camids.begin(); it != camids.end(); ++it, ++n)
            names.Add(wxString::Format("%d: %s", n, *it));

        int i = wxGetSingleChoiceIndex(_("Select QHY camera"), _("Camera choice"), names);
        if (i == -1)
            return true;
        camid = camids[i];
    }
    else
        camid = camids[0];

    char *s = new char[camid.length() + 1];
    memcpy(s, camid.c_str(), camid.length() + 1);
    m_camhandle = OpenQHYCCD(s);
    delete[] s;

    Name = camid;

    if (!m_camhandle)
    {
        wxMessageBox(_("Failed to connect to camera"));
        return true;
    }

    // before calling InitQHYCCD() we must call SetQHYCCDStreamMode(camhandle, 0 or 1)
    //   0: single frame mode  
    //   1: live frame mode 
    uint32_t ret = SetQHYCCDStreamMode(m_camhandle, 0);
    if (ret != QHYCCD_SUCCESS)
    {
        CloseQHYCCD(m_camhandle);
        m_camhandle = 0;
        wxMessageBox(_("SetQHYCCDStreamMode failed"));
        return true;
    }

    ret = InitQHYCCD(m_camhandle);
    if (ret != QHYCCD_SUCCESS)
    {
        CloseQHYCCD(m_camhandle);
        m_camhandle = 0;
        wxMessageBox(_("Init camera failed"));
        return true;
    }

    ret = GetQHYCCDParamMinMaxStep(m_camhandle, CONTROL_GAIN, &m_gainMin, &m_gainMax, &m_gainStep);
    if (ret != QHYCCD_SUCCESS)
    {
        CloseQHYCCD(m_camhandle);
        m_camhandle = 0;
        wxMessageBox(_("Failed to get gain range"));
        return true;
    }

    double chipw, chiph, pixelw, pixelh;
    uint32_t imagew, imageh, bpp;
    ret = GetQHYCCDChipInfo(m_camhandle, &chipw, &chiph, &imagew, &imageh, &pixelw, &pixelh, &bpp);
    if (ret != QHYCCD_SUCCESS)
    {
        CloseQHYCCD(m_camhandle);
        m_camhandle = 0;
        wxMessageBox(_("Failed to get camera chip info"));
        return true;
    }

    int bayer = IsQHYCCDControlAvailable(m_camhandle, CAM_COLOR);
    Debug.Write(wxString::Format("QHY: cam reports bayer type %d\n", bayer));

    Color = false;
    switch ((BAYER_ID)bayer) {
    case BAYER_GB:
    case BAYER_GR:
    case BAYER_BG:
    case BAYER_RG:
        Color = true;
    }

    // check bin modes
    CONTROL_ID modes[] = { CAM_BIN2X2MODE, CAM_BIN3X3MODE, CAM_BIN4X4MODE, };
    int bin[] = { 2, 3, 4, };
    int maxBin = 1;
    for (int i = 0; i < WXSIZEOF(modes); i++)
    {
        ret = IsQHYCCDControlAvailable(m_camhandle, modes[i]);
#if 0
        // FIXME- IsQHYCCDControlAvailable is supposed to return QHYCCD_ERROR_NOTSUPPORT for a
        // bin mode that is not supported, but in fact it returns QHYCCD_ERROR, so we cannot
        // distinguish "not supported" from "error".
        if (ret != QHYCCD_SUCCESS && ret != QHYCCD_ERROR_NOTSUPPORT)
        {
            CloseQHYCCD(m_camhandle);
            m_camhandle = 0;
            wxMessageBox(_("Failed to get camera bin info"));
            return true;
        }
#endif
        if (ret == QHYCCD_SUCCESS)
            maxBin = bin[i];
        else
            break;
    }
    Debug.Write(wxString::Format("QHY: max binning = %d\n", maxBin));
    MaxBinning = maxBin;
    if (Binning > MaxBinning)
        Binning = MaxBinning;

    Debug.Write(wxString::Format("QHY: call SetQHYCCDBinMode bin = %d\n", Binning));
    ret = SetQHYCCDBinMode(m_camhandle, Binning, Binning);
    if (ret != QHYCCD_SUCCESS)
    {
        CloseQHYCCD(m_camhandle);
        m_camhandle = 0;
        wxMessageBox(_("Failed to set camera binning"));
        return true;
    }
    m_curBin = Binning;

    m_maxSize = wxSize(imagew, imageh);
    FullSize = wxSize(imagew / Binning, imageh / Binning);

    delete[] RawBuffer;
    size_t size = GetQHYCCDMemLength(m_camhandle);
    RawBuffer = new unsigned char[size];

    m_devicePixelSize = sqrt(pixelw * pixelh);

    m_curGain = -1;
    m_curExposure = -1;
    m_roi = wxRect(0, 0, FullSize.GetWidth(), FullSize.GetHeight());  // binned coordinates

    Debug.Write(wxString::Format("QHY: call SetQHYCCDResolution roi = %d,%d\n", m_roi.width, m_roi.height));
    ret = SetQHYCCDResolution(m_camhandle, 0, 0, m_roi.GetWidth(), m_roi.GetHeight());
    if (ret != QHYCCD_SUCCESS)
    {
        CloseQHYCCD(m_camhandle);
        m_camhandle = 0;
        wxMessageBox(_("Init camera failed"));
        return true;
    }

    Debug.Write(wxString::Format("QHY: connect done\n"));
    Connected = true;
    return false;
}
Пример #5
0
bool QHYCCD::Connect()
{

    sim = isSimulation();

    int ret;

    uint32_t cap;

    if (sim)
    {
        cap = CCD_CAN_SUBFRAME | CCD_CAN_ABORT | CCD_CAN_BIN | CCD_HAS_COOLER | CCD_HAS_ST4_PORT;
        SetCCDCapability(cap);

        HasUSBTraffic = true;
        HasUSBSpeed = true;
        HasGain = true;
        HasOffset = true;
        HasFilters = true;

        return true;
    }

    camhandle = OpenQHYCCD(camid);

    if(camhandle != NULL)
    {
        DEBUGF(INDI::Logger::DBG_SESSION, "Connected to %s.",camid);

#ifdef OSX_EMBEDED_MODE
        cap = CCD_CAN_ABORT | CCD_CAN_SUBFRAME;
#else
        cap = CCD_CAN_ABORT | CCD_CAN_SUBFRAME | CCD_HAS_STREAMING;
#endif
        ret = InitQHYCCD(camhandle);
        if(ret != QHYCCD_SUCCESS)
        {
            DEBUGF(INDI::Logger::DBG_ERROR, "Error: Init Camera failed (%d)", ret);
            return false;
        }

        ret = IsQHYCCDControlAvailable(camhandle,CAM_MECHANICALSHUTTER);
        if(ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_HAS_SHUTTER;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Shutter Control: %s", cap & CCD_HAS_SHUTTER ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CONTROL_COOLER);
        if(ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_HAS_COOLER;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Cooler Control: %s", cap & CCD_HAS_COOLER ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CONTROL_ST4PORT);
        if(ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_HAS_ST4_PORT;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Guider Port Control: %s", cap & CCD_HAS_ST4_PORT  ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CONTROL_SPEED);
        if(ret == QHYCCD_SUCCESS)
        {
            HasUSBSpeed = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "USB Speed Control: %s", HasUSBSpeed ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CONTROL_GAIN);
        if(ret == QHYCCD_SUCCESS)
        {
            HasGain = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Gain Control: %s", HasGain ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CONTROL_OFFSET);
        if(ret == QHYCCD_SUCCESS)
        {
            HasOffset = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Offset Control: %s", HasOffset ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CONTROL_CFWPORT);
        if(ret == QHYCCD_SUCCESS)
        {
            HasFilters = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Has Filters: %s", HasFilters ? "True" : "False");

        // Using software binning
        cap |= CCD_CAN_BIN;
        camxbin = 1;
        camybin = 1;

        ret = IsQHYCCDControlAvailable(camhandle,CAM_BIN1X1MODE);
        if(ret == QHYCCD_SUCCESS)
        {
            camxbin = 1;
            camybin = 1;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Bin 1x1: %s", (ret == QHYCCD_SUCCESS) ? "True" : "False");

        ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN2X2MODE);
        ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN3X3MODE);
        ret &= IsQHYCCDControlAvailable(camhandle,CAM_BIN4X4MODE);
        if(ret == QHYCCD_SUCCESS)
        {
            cap |= CCD_CAN_BIN;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "Binning Control: %s", cap & CCD_CAN_BIN ? "True" : "False");        

        ret= IsQHYCCDControlAvailable(camhandle, CONTROL_USBTRAFFIC);
        if (ret == QHYCCD_SUCCESS)
        {
            HasUSBTraffic = true;
        }

        DEBUGF(INDI::Logger::DBG_DEBUG, "USB Traffic Control: %s", HasUSBTraffic ? "True" : "False");

        ret = IsQHYCCDControlAvailable(camhandle,CAM_COLOR);
        //if(ret != QHYCCD_ERROR && ret != QHYCCD_ERROR_NOTSUPPORT)
        if(ret != QHYCCD_ERROR)
        {
             if(ret == BAYER_GB)
                 IUSaveText(&BayerT[2], "GBGR");
             else if (ret == BAYER_GR)
                 IUSaveText(&BayerT[2], "GRGB");
             else if (ret == BAYER_BG)
                 IUSaveText(&BayerT[2], "BGGR");
             else
                 IUSaveText(&BayerT[2], "RGGB");

             DEBUGF(INDI::Logger::DBG_DEBUG, "Color CCD: %s", BayerT[2].text);

             cap |= CCD_HAS_BAYER;

        }

        SetCCDCapability(cap);

#ifndef OSX_EMBEDED_MODE
        pthread_create( &primary_thread, NULL, &streamVideoHelper, this);
#endif
        return true;
    }

    DEBUGF(INDI::Logger::DBG_ERROR, "Connecting to CCD failed (%s)",camid);

    return false;

}