dianlan6397
梁小浩啊
采纳率0%
2017-07-11 03:42 阅读 1.1k

急,求救!用QT5 感觉线程不同步,

用QT5 C++环境编译而成的。
有人能帮我看一下吗,自己发现子线程在不断进入退出,
怎样才能让软件稳定运行呢,发现子线程循环不正常,,
按下开始键,开始采集数据,
按下停止键,(开始键弹起),再按下开始发现出现了线程不同步,发现子线程在不断的进入退出。不知道是哪里的问题。我的想法是在picologger.cpp文件中执行数据地址调用来显示图像,在logdata.cpp文件中进行不断循环采集数据。
picologger.cpp文件

关键是不会弄线程方面的,又能帮助的吗

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

3条回答 默认 最新

  • dianlan6397 梁小浩啊 2017-07-11 03:43
    
    
    

    #include "picologger.h"
    #include "logdata.h"
    #include "ui_picologger.h"
    #include "PicoStatus.h"
    #include "ps5000aApi.h"
    #include
    #include "QPushButton"
    #include "logdata.h"
    #include
    #include
    //#include
    #include "windows.h"
    #include
    //#include
    extern int stop;
    float barh=0;
    float volt=0;

    int32_t w=1024 ;
    int i;
    short sVoltageData[5000]={0};
    short sCurrentData[5000]={0};
    #define BUFFER_SIZE 1024
    #define MAX_CHANNELS 4
    #define QUAD_SCOPE 4
    #define DUAL_SCOPE 2
    short tmpBuff[1024];
    void PREF4 CallBackBlock (short handle, PICO_STATUS status, void *pParameter)
    {
    // flag to say done reading data
    //Picoscope::SetReady(true);
    }

    #include

    /* Headers for Windows */
    #ifdef _WIN32
    #include "windows.h"
    #include
    #include "ps5000aApi.h"
    #else
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #include
    #ifndef PICO_STATUS
    #include
    #endif

    #define Sleep(a) usleep(1000*a)
    #define scanf_s scanf
    #define fscanf_s fscanf
    #define memcpy_s(a,b,c,d) memcpy(a,c,d)

    typedef enum enBOOL{FALSE,TRUE} BOOL;

    /* A function to detect a keyboard press on Linux */
    int32_t _getch()
    {
    struct termios oldt, newt;
    int32_t ch;
    int32_t bytesWaiting;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    setbuf(stdin, NULL);
    do {
    ioctl(STDIN_FILENO, FIONREAD, &bytesWaiting);
    if (bytesWaiting)
    getchar();
    } while (bytesWaiting);

        ch = getchar();
    
        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
        return ch;
    

    }

    int32_t _kbhit()
    {
    struct termios oldt, newt;
    int32_t bytesWaiting;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    setbuf(stdin, NULL);
    ioctl(STDIN_FILENO, FIONREAD, &bytesWaiting);

        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
        return bytesWaiting;
    

    }

    int32_t fopen_s(FILE ** a, const int8_t * b, const int8_t * c)
    {
    FILE * fp = fopen(b,c);
    *a = fp;
    return (fp>0)?0:-1;
    }

    /* A function to get a single character on Linux */
    #define max(a,b) ((a) > (b) ? a : b)
    #define min(a,b) ((a) < (b) ? a : b)
    #endif
    double voltage;

    logData* worker;
    PicoLogger::PicoLogger(QWidget parent) :
    QMainWindow(parent),
    ui(new Ui::PicoLogger)
    {
    short sVoltageData[5000]={0};
    short sCurrentData[5000]={0};
    int i=0;
    //if (InitCVIRTE (0, argv, 0) == 0) return -1; /
    out of memory */

    ui->setupUi(this);
    
    ui->plot->axisRect()->setMinimumSize(300, 180);
    

    // setupPlot();
    // setupRealtimeDataDemo(ui->plot);
    }
    PicoLogger::~PicoLogger()
    {
    delete ui;
    }

    int32_t cycles = 0;

    #define BUFFER_SIZE 1024

    #define QUAD_SCOPE 4
    #define DUAL_SCOPE 2

    #define MAX_PICO_DEVICES 64
    #define TIMED_LOOP_STEP 500

    typedef struct
    {
    int16_t DCcoupled;
    int16_t range;
    int16_t enabled;
    float analogueOffset;
    }CHANNEL_SETTINGS;

    typedef enum
    {
    MODEL_NONE = 0,
    MODEL_PS5242A = 0xA242,
    MODEL_PS5242B = 0xB242,
    MODEL_PS5243A = 0xA243,
    MODEL_PS5243B = 0xB243,
    MODEL_PS5244A = 0xA244,
    MODEL_PS5244B = 0xB244,
    MODEL_PS5442A = 0xA442,
    MODEL_PS5442B = 0xB442,
    MODEL_PS5443A = 0xA443,
    MODEL_PS5443B = 0xB443,
    MODEL_PS5444A = 0xA444,
    MODEL_PS5444B = 0xB444
    } MODEL_TYPE;

    typedef enum
    {
    SIGGEN_NONE = 0,
    SIGGEN_FUNCTGEN = 1,
    SIGGEN_AWG = 2
    } SIGGEN_TYPE;

    typedef struct tTriggerDirections
    {
    PS5000A_THRESHOLD_DIRECTION channelA;
    PS5000A_THRESHOLD_DIRECTION channelB;
    PS5000A_THRESHOLD_DIRECTION channelC;
    PS5000A_THRESHOLD_DIRECTION channelD;
    PS5000A_THRESHOLD_DIRECTION ext;
    PS5000A_THRESHOLD_DIRECTION aux;
    }TRIGGER_DIRECTIONS;

    typedef struct tPwq
    {
    PS5000A_PWQ_CONDITIONS * conditions;
    int16_t nConditions;
    PS5000A_THRESHOLD_DIRECTION direction;
    uint32_t lower;
    uint32_t upper;
    PS5000A_PULSE_WIDTH_TYPE type;
    }PWQ;

    typedef struct
    {
    int16_t handle;
    MODEL_TYPE model;
    int8_t modelString[8];
    int8_t serial[10];
    int16_t complete;
    int16_t openStatus;
    int16_t openProgress;
    PS5000A_RANGE firstRange;
    PS5000A_RANGE lastRange;
    int16_t channelCount;
    int16_t maxADCValue;
    SIGGEN_TYPE sigGen;
    int16_t hasHardwareETS;
    uint16_t awgBufferSize;
    CHANNEL_SETTINGS channelSettings [PS5000A_MAX_CHANNELS];
    PS5000A_DEVICE_RESOLUTION resolution;
    }UNIT;

    uint32_t timebase = 8;
    BOOL scaleVoltages = TRUE;

    uint16_t inputRanges [PS5000A_MAX_RANGES] = {
    10,
    20,
    50,
    100,
    200,
    500,
    1000,
    2000,
    5000,
    10000,
    20000,
    50000};

    int16_t g_autoStopped;
    int16_t g_ready = FALSE;
    uint32_t g_times [PS5000A_MAX_CHANNELS];
    int16_t g_timeUnit;
    int32_t g_sampleCount;
    uint32_t g_startIndex;
    int16_t g_trig = 0;
    uint32_t g_trigAt = 0;
    int16_t g_overflow = 0;

    int8_t blockFile[20] = "block.txt";
    int8_t streamFile[20] = "stream.txt";
    short sReady=0;
    typedef struct tBufferInfo
    {
    UNIT * unit;
    int16_t **driverBuffers;
    int16_t **appBuffers;

    } BUFFER_INFO;
    /****************************************************************************

    • adc_to_mv *
    • Convert an 16-bit ADC count into millivolts将16位ADC转换成毫伏 ****************************************************************************/ int32_t adc_to_mv(int32_t raw, int32_t rangeIndex, UNIT * unit) { return (raw * inputRanges[rangeIndex]) / unit->maxADCValue; }

    /****************************************************************************

    • mv_to_adc *
    • Convert a millivolt value into a 16-bit ADC count将毫伏值转换为16位ADC计数 *
    • (useful for setting trigger thresholds)适用于设置触发器阈值 ****************************************************************************/ int16_t mv_to_adc(int16_t mv, int16_t rangeIndex, UNIT * unit) { return (mv * unit->maxADCValue) / inputRanges[rangeIndex]; }

    int16_t handle;

    void PicoLogger::update_SampleRate()//更新窗口采样率
    {
    timeUnit = ui->TimeUnits->currentIndex();
    sampleInterval = ui->SampleInterval->text().toDouble();

    double sampleRate = 1/(timeUnits[(short) timeUnit]*sampleInterval);
    ui->SampleRate->setText(QString::number(sampleRate));
    

    }

    void PicoLogger::on_SampleInterval_textChanged(const QString &arg1)//采样文本设置
    {
    update_SampleRate();
    }

    void PicoLogger::on_TimeUnits_currentIndexChanged(int index)//时间单元改变
    {
    update_SampleRate();
    }

    int8_t *ch;

    //连接设备
    void PicoLogger::on_Connect_clicked()
    {
    //wd.show();
    //QMessageBox::information(this, QStringLiteral("警告"),QStringLiteral("设备开始连接!"));
    UNIT unit;
    PICO_STATUS status;
    int16_t count=0;
    int16_t serialLg=100;
    int16_t handle=0;
    int8_t serial[100]={0};
    /*********************************************************************************

    • 步骤1设置打开设备 **********************************************************************************/ status=ps5000aEnumerateUnits(&count,serial,&serialLg);// status=ps5000aOpenUnit(&handle,NULL,PS5000A_DR_15BIT);// status=ps5000aChangePowerSource(handle,PICO_POWER_SUPPLY_NOT_CONNECTED);// // ps5000aopenunit 已经没有问题了 count>0 证明可以检测到设备 handle=16384状态即为成功、

    //界面窗口的设计
    rangeA = ui->ChannelA->currentIndex();// + 1; // A范围
    rangeB = ui->ChannelB->currentIndex();// + 1; // B范围
    QString bufferSizeText = ui->BufferSize->text();
    bufferSize = bufferSizeText.toULong();
    timeUnit = ui->TimeUnits->currentIndex();
    sampleInterval = ui->SampleInterval->text().toULong();

    unit.channelSettings[PS5000A_CHANNEL_C].enabled = FALSE;
    unit.channelSettings[PS5000A_CHANNEL_D].enabled = FALSE;
    
    QMainWindow::statusBar()->showMessage("寻找设备……");
    
    QString statusChar = QString::number (handle);
    

    //界面的设计
    //if( count>0){
    if( status==PICO_OK){

        QMainWindow::statusBar()->showMessage("示波器连接设备状态: " + statusChar);
        ui->Connect->setEnabled(false);
        ui->Disconnect->setEnabled(true);
        ui->Start->setEnabled(false);
        ui->Stop->setEnabled(false);
        ui->SetChannels->setEnabled(true);
    
        ui->ChannelA->setEnabled(true);
        ui->ChannelB->setEnabled(true);
        ui->ChannelC->setEnabled(false);
        ui->ChannelD->setEnabled(false);
    
        ui->BufferSize->setEnabled(true);
        ui->SampleInterval->setEnabled(true);
        ui->TimeUnits->setEnabled(true);
    
        ui->SetChannels->setEnabled(true);
    
        ui->Start->setEnabled(false);
        ui->Stop->setEnabled(false);
    

    }else{
    QMainWindow::statusBar()->showMessage("无法连接示波器设备: " + statusChar);
    ui->Connect->setEnabled(true);
    ui->Disconnect->setEnabled(false);
    }
    }

    //通道按键,包括触发的设置
    void PicoLogger::on_SetChannels_clicked()
    {
    PICO_STATUS status;
    int32_t i;

    // char Error[100];
    static int statusOpenUnit=1;
    //PICO_STATUS status=1;
    float PS5000A_CHANNEL_A_OFFSET;
    float PS5000A_CHANNEL_B_OFFSET;
    int iTriggerThresholdADCCount, iAutoTrigger_ms, autoTriggerMilliseconds;
    unsigned int iTriggerDelay;
    short nChannelProperties, thresholdUpper, thresholdUpperHysteresis, thresholdLower, thresholdLowerHysteresis;
    uint32_t timebase;
    int32_t noSamples;
    float timeIntervalNanoseconds;
    int32_t maxSamples;
    uint32_t segmentIndex;
    float maximumVoltage, minimumVoltage;
    int16_t handle=16384;
    status = ps5000aChangePowerSource(handle,PICO_POWER_SUPPLY_NOT_CONNECTED);
    status = ps5000aCurrentPowerSource(handle);
    /*********************************************************************************

    • 步骤2设置通道 **********************************************************************************/ // 配置通道 PS5000A_CHANNEL_A_OFFSET = 0.0; PS5000A_CHANNEL_B_OFFSET = 0.0; status = ps5000aSetChannel(handle, PS5000A_CHANNEL_A, TRUE, PS5000A_DC, //PS5000A_10MV, PS5000A_RANGE(rangeA), //PS5000A_50V, PS5000A_CHANNEL_A_OFFSET); PS5000A_CHANNEL_A_OFFSET = 0.0; status = ps5000aSetChannel(handle, PS5000A_CHANNEL_B, FALSE, PS5000A_DC, PS5000A_1V, PS5000A_CHANNEL_B_OFFSET); if (status==PICO_OK) { QMainWindow::statusBar()->showMessage("通道设置成功"); // Sleep(400); } else if (status== PICO_USER_CALLBACK){ QMainWindow::statusBar()->showMessage("PICO_USER_CALLBACK"); Sleep(400); } else if (status==PICO_INVALID_HANDLE ){ QMainWindow::statusBar()->showMessage("PICO_INVALID_HANDLE"); Sleep(400); } else if (status==PICO_INVALID_CHANNEL ){ QMainWindow::statusBar()->showMessage("PICO_INVALID_CHANNEL"); Sleep(400); } else if (status==PICO_INVALID_VOLTAGE_RANGE){ QMainWindow::statusBar()->showMessage("PICO_USER_CALLBACK"); Sleep(400); } else if (status==PICO_INVALID_COUPLING){ QMainWindow::statusBar()->showMessage("PICO_INVALID_HANDLE"); Sleep(400); } else if (status==PICO_INVALID_ANALOGUE_OFFSET){ QMainWindow::statusBar()->showMessage("PICO_INVALID_ANALOGUE_OFFSET"); Sleep(400); } else if (status==PICO_DRIVER_FUNCTION){ QMainWindow::statusBar()->showMessage("PICO_DRIVER_FUNCTION"); Sleep(400); } else { QMainWindow::statusBar()->showMessage("通道设置不成功"); }

    UNIT unit;

    //int16_t triggerVoltage = mv_to_adc(1000, unit.channelSettings[PS5000A_CHANNEL_A].range, unit);

    struct tPS5000ATriggerChannelProperties CHA_Properties = { 0,//triggerVoltage,
    256 * 10,
    0,// triggerVoltage,
    256 * 10,
    PS5000A_CHANNEL_A,
    PS5000A_LEVEL};

    // 结构触发条件
    struct tPS5000ATriggerConditions CHA_Conditions = { PS5000A_CONDITION_TRUE, // CHA
    PS5000A_CONDITION_DONT_CARE, // CHB
    PS5000A_CONDITION_DONT_CARE, // CHC
    PS5000A_CONDITION_DONT_CARE, // CHD
    PS5000A_CONDITION_DONT_CARE, // external
    PS5000A_CONDITION_DONT_CARE, // aux
    PS5000A_CONDITION_DONT_CARE, // pulseWidthQualifier
    };
    struct tPwq pulseWidth;
    // 结构触发方向
    struct tTriggerDirections CHA_directions = { PS5000A_RISING,
    PS5000A_NONE,
    PS5000A_NONE,
    PS5000A_NONE,
    PS5000A_NONE,
    PS5000A_NONE };
    memset(&pulseWidth, 0, sizeof(struct tPwq));
    // setTrigger(unit, &sourceDetails, 1, &CHA_conditions, 1, & CHA_directions, &pulseWidth, 0, 0, 0);
    // 结构为触发配置
    //PS5000A_TRIGGER_CHANNEL_PROPERTIES CHA_Properties = {1000,0,1000,0,PS5000A_CHANNEL_A,PS5000A_LEVEL };
    float timeIndisposedMs;
    // 获取时间基础,只是为了获取信息
    // 采样时间=5s
    // 例如: 采样率= 1000S/s
    // 采样间隔: 1ms
    // 内存: 5000S/Channel
    // timebase @ 15bit 分辨率: (1ms * 125000000) + 2 = 125002
    timebase = 127;//1002;//3-2^32范围
    noSamples = 1024;//5000;
    segmentIndex = 0;
    // 设置时间(支持浮点型timebase2,另一个支持整型)
    /*********************************************************************************

    • 步骤3设置GetTimebase2数据采集 **********************************************************************************/ while(status = ps5000aGetTimebase2(handle,timebase,noSamples,&timeIndisposedMs,// NULL, //&timeIntervalNanoseconds, NULL, //&maxSamples, segmentIndex) ) { timebase++; } if (status==PICO_OK) { QMainWindow::statusBar()->showMessage("GetTimebase2:运行成功"); Sleep(100); } else { QMainWindow::statusBar()->showMessage("GetTimebase2错误"); Sleep(400); } /*********************************************************************************
    • 步骤4设置触发(包括触发通道条件,触发通道方向,触发通道属性) **********************************************************************************/ // 设置触发条件 status = ps5000aSetTriggerChannelConditions(handle, &CHA_Conditions, 1); // 1 condition structure if (status==PICO_OK) { QMainWindow::statusBar()->showMessage("SetTriggerChannelConditions:运行成功"); Sleep(100); } else { QMainWindow::statusBar()->showMessage("SetTriggerChannelConditions错误"); Sleep(400); } // 配置触发器 status = ps5000aSetTriggerChannelDirections(handle, PS5000A_RISING, // CHA上升 PS5000A_NONE, // CHB PS5000A_NONE, // CHC PS5000A_NONE, // CHD PS5000A_NONE, // ext PS5000A_NONE); // aux if (status==PICO_OK) { QMainWindow::statusBar()->showMessage("SetTriggerChannelDirections:运行成功"); Sleep(100); } else { QMainWindow::statusBar()->showMessage("SetTriggerChannelDirections错误"); Sleep(400); } autoTriggerMilliseconds = 1;//控制触发采集速度

    nChannelProperties = 1; // the size of the channelProperties array. If zero, triggering is switched off. -> 1 channel triggered 通道属性数组的大小。如果零,触发开关关闭。- > 1通道触发
    status = ps5000aSetTriggerChannelProperties(handle,
    &CHA_Properties,
    nChannelProperties,
    NULL,
    autoTriggerMilliseconds);

    if (status==PICO_OK)
    {
    QMainWindow::statusBar()->showMessage("SetTriggerChannelProperties:运行成功");
    Sleep(100);
    }
    else {
    QMainWindow::statusBar()->showMessage("SetTriggerChannelProperties错误");
    Sleep(400);
    }
    // 界面设计
    if (status!=PICO_OK)
    {
    QMainWindow::statusBar()->showMessage("设置一个或多个通道的错误。检查电压范围。如果四频道的范围和电源没有启用,则不需要设置频道C和D.");
    ui->Start->setEnabled(false);
    ui->Stop->setEnabled(false);
    }
    else{
    QMainWindow::statusBar()->showMessage("通道设置。");
    ui->Start->setEnabled(true);
    ui->Stop->setEnabled(false);

        ui->ChannelA->setEnabled(true);
        ui->ChannelB->setEnabled(true);
        ui->ChannelC->setEnabled(false);
        ui->ChannelD->setEnabled(false);
    
        ui->BufferSize->setEnabled(false);
        ui->SampleInterval->setEnabled(false);
        ui->TimeUnits->setEnabled(false);
    
        ui->SetChannels->setEnabled(true);
    }
    

    }

    
    
    
    
    点赞 评论 复制链接分享
  • dianlan6397 梁小浩啊 2017-07-11 03:45
     //按下开始键下面是捕获数据的
    /**************************
     *  START LOGGING开始登录
     *  Opens new worker thread and sends*打开新的工作线程并发送
     *  signal to start logging data信号开始记录数据
     * ***********************/
    void PicoLogger::on_Start_clicked()
    {
       //stop=1;
        // int i;
        //按下开始键下面是捕获数据的程序
        int16_t  start=1;
        status=ps5000aFlashLed(handle,start);
        //int j;
        PICO_STATUS status=1;
        unsigned long maxSamples;
        int noOfPreTriggerSamples =0, noOfPostTriggerSamples = 1024, timeIndisposedMs;
        unsigned int timebase =127,//1002,//3-2^32-2时间采样是一个很重要的控制采样间隔 8ns---------这里决定这个采样间隔。
        segmentIndex = 0;
        int16_t handle=16384;
         //为通道A配置PicoScop数据缓冲区
        int32_t  bufferLth = 1024;//5000;
        uint16_t noOfWantedSamples=1024;//5000;
        int j;
    //short *ChannelA = (short*)calloc(noOfWantedSamples, sizeof(short)*noOfWantedSamples);
    //short *ChannelA = (short*)calloc(noOfWantedSamples, sizeof(short)*noOfWantedSamples);
        //tmpBuff[1024]={0};
    /*********************************************************************************
    * 步骤5设置内存缓冲
    **********************************************************************************/
                status = ps5000aSetDataBuffer(handle,
                                              PS5000A_CHANNEL_A,
                                              tmpBuff,   //* buffer
                                              1024,
                                              segmentIndex,
                                              PS5000A_RATIO_MODE_NONE);//比模式没有分配
                //窗口左下角状态显示
                if (status==PICO_OK)
                {
                    QMainWindow::statusBar()->showMessage("SetDataBuffer:运行成功");
                     Sleep(1000);
                }
                else if (status==PICO_INVALID_HANDLE){
                    QMainWindow::statusBar()->showMessage("SetDataBuffer错误:PICO_INVALID_HANDLE");
                    Sleep(400);
                }
                else if (status==PICO_INVALID_CHANNEL){
                    QMainWindow::statusBar()->showMessage("SetDataBuffer错误:PICO_POWER_SUPPLY_CONNECTED");
                    Sleep(400);
                }
                else if (status==PICO_RATIO_MODE_NOT_SUPPORTED){
                    QMainWindow::statusBar()->showMessage("SetDataBuffer错误:PICO_POWER_SUPPLY_NOT_CONNECTED");
                    Sleep(400);
                }
                else if (status==PICO_SEGMENT_OUT_OF_RANGE){
                    QMainWindow::statusBar()->showMessage("SetDataBuffer错误:PICO_SEGMENT_OUT_OF_RANGE");
                    Sleep(400);
                }
                else if (status==PICO_INVALID_PARAMETER){
                    QMainWindow::statusBar()->showMessage("SetDataBuffer错误:PICO_INVALID_PARAMETER");
                    Sleep(400);
                }
                else if (status==PICO_DRIVER_FUNCTION){
                    QMainWindow::statusBar()->showMessage("SetDataBuffer错误:PICO_DRIVER_FUNCTION");
                    Sleep(400);
                }
                else{
                    QMainWindow::statusBar()->showMessage("SetDataBuffer:不成功");
                }
    
    /*********************************************************************************
    * 步骤6设置block mode 模式启动
    **********************************************************************************/
            status = ps5000aRunBlock(handle,
                                     noOfPreTriggerSamples,//样品的数量返回在触发事件
                                     noOfPostTriggerSamples,//最大数量的数据点(样本)收集
                                     timebase,//在3到2 32 - 1之间的数
                                     &timeIndisposedMs,//在退出时,时间,以毫秒为单位范围将用于收集样本。
                                     segmentIndex,
                                     NULL,  //CallBackBlock,  //lpReady,
                                     NULL);  //* pParameter
                                //     Sleep(100);
            if (status==PICO_OK)
            {
                QMainWindow::statusBar()->showMessage("RunBlock:运行成功");
            }
            else {
                QMainWindow::statusBar()->showMessage("RunBlock错误");
                //Sleep(400);
            }
            unsigned int  startIndex, noOfSamples=1500;
            short overflow;
    
    /*********************************************************************************
    * 步骤7设置block isready 模式等待数据收集完成
    **********************************************************************************/
            while (sReady== 0) {
                status = ps5000aIsReady(handle, &sReady);
                Sleep(25); // PICO HM
    }
        if (status==PICO_OK)
        {
            QMainWindow::statusBar()->showMessage("IsReady:运行成功");
        }
        else {
        QMainWindow::statusBar()->showMessage("IsReady错误");
        //Sleep(400);
    }
    /*********************************************************************************
    * 步骤8设置block GetValues模式等待数据收集完成
    **********************************************************************************/
    //下载通道A的记录数据
            startIndex = 0;
            noOfSamples =1024;
            status = ps5000aGetValues(handle,
                                      startIndex,
                                      &noOfSamples,
                                      1,//PS5000A_RATIO_MODE_NONE,
                                      PS5000A_RATIO_MODE_NONE,
                                      segmentIndex,
                                      &overflow);
    
    //窗口左下角状态显示
            if (status==PICO_OK)
            {
                QMainWindow::statusBar()->showMessage("GetValues:运行成功");
                 Sleep(400);
            }
            else if (status== PICO_NO_SAMPLES_AVAILABLE){
                QMainWindow::statusBar()->showMessage("GetValues错误:PICO_NO_SAMPLES_AVAILABLE");
                Sleep(400);
            }
            else if (status==PICO_POWER_SUPPLY_CONNECTED ){
                QMainWindow::statusBar()->showMessage("GetValues错误:PICO_POWER_SUPPLY_CONNECTED");
                Sleep(400);
            }
            else if (status== PICO_POWER_SUPPLY_NOT_CONNECTED ){
                QMainWindow::statusBar()->showMessage("GetValues错误:PICO_POWER_SUPPLY_NOT_CONNECTED");
                Sleep(400);
            }
            else{
                 QMainWindow::statusBar()->showMessage("GetValues:不成功");
    }
    
        worker = new logData();
        // Move to worker thread移动到工作线程
        QThread* thread = new QThread;
        workerThread = thread;
        worker->moveToThread(thread);
    // Link singal/slots between threads连接线程之间信号/插槽
       QObject::connect(this ,
                        SIGNAL(startLogging(short, unsigned long, short,
                                             unsigned long, unsigned long,
                                             short, PicoLogger*,
                                             short, short, short, short)),
                        worker,
                        SLOT(startLogging(short, unsigned long, short,
                                                    unsigned long, unsigned long,
                                           short, PicoLogger*,
                                           short, short, short, short)));
        QObject::connect(
                         worker ,SIGNAL(stopLogging(QString)), this,
                         SLOT(stopLogging(QString)));
        QObject::connect(
                         worker,SIGNAL(loggingTimer(QString)), this,
                         SLOT(loggingTimer(QString)));
    
        // Start worker thread启动工作线程
        thread->setObjectName(QString("PicoLogger_Streaming"));
        thread->start();
        thread->setPriority(QThread::HighPriority);
    
        // Get data from UI从UI获得数据
        QString loggingDurationText = ui->LoggingTime->text();
        loggingDurationVal = loggingDurationText.toShort();
    
    
    
        // Send signal for starting logging发送启动日志的信号
        ui->Start->setEnabled(false);
        ui->Stop->setEnabled(true);
        emit startLogging(status, sampleInterval,timeUnit,
                          maxSamples, bufferSize, loggingDurationVal,
                          this, rangeA, rangeB, rangeC, rangeD);
    }
    
    void PicoLogger::stopLogging(QString message)
    {
        ui->statusBar->showMessage(message);
        ui->Start->setEnabled(true);
       delete worker;
        workerThread->exit();
    }
    //停止设备
    void PicoLogger::on_Stop_clicked()
    {
        ui->plot->graph(0)->clearData();
        ui->plot->graph(1)->clearData();
        i=0;
        loopLogging = false;
        ui->Start->setEnabled(true);
        plot_timer.stop();
        PICO_STATUS status=1;
        char Error[100];
        int16_t handle=16384;
        QMainWindow::statusBar()->showMessage("示波器停止设备: ");
        float PS5000A_CHANNEL_A_OFFSET=0.0;
        status = ps5000aStop(handle);
      status = ps5000aSetChannel(handle,PS5000A_CHANNEL_A,TRUE,PS5000A_DC,PS5000A_RANGE(rangeA),PS5000A_CHANNEL_A_OFFSET);
       // clearDataBuffers();
    
    }
    //关闭设备
    void PicoLogger::on_Disconnect_clicked()
    {
        PICO_STATUS status=1;
        int16_t handle=16384;
        status = ps5000aCloseUnit(handle);
    
        short statusDisconnect =ps5000aCloseUnit(handle);
        QString statusChar = QString::number (handle);
      //if(statusDisconnect==PICO_OK){
        if(status==PICO_OK)
        {
            QString statusChar = QString::number (handle);
            QMainWindow::statusBar()->showMessage("示波器断开连接设备: " + statusChar);
            ui->Connect->setEnabled(true);
            ui->ChannelA->setEnabled(false);
            ui->ChannelB->setEnabled(false);
            ui->ChannelC->setEnabled(false);
            ui->ChannelD->setEnabled(false);
    
            ui->BufferSize->setEnabled(false);
            ui->SampleInterval->setEnabled(false);
            ui->TimeUnits->setEnabled(false);
    
            ui->SetChannels->setEnabled(false);
        }
        else
        {
            QMainWindow::statusBar()->showMessage("没有发现设备。");
        }
    }
    
    点赞 评论 复制链接分享
  • dianlan6397 梁小浩啊 2017-07-11 03:47
    
    线程文件logdata.cpp
    
    #include "logdata.h"
    #include <QtCore>
    #include <ctime>
    #include "ui_picologger.h"
    #include <string>
    #include <iomanip>
    #include "picologger.h"
    //#include "C:\Program Files (x86)\Pico Technology\SDK\inc\ps3000.h"
    #include "PicoStatus.h"
    #include "ps5000aApi.h"
    #include "windows.h"
    
    #include <fstream>
    #include <QDataStream>
    
    #define BUFFER_SIZE     1024
    
    #define QUAD_SCOPE      4
    #define DUAL_SCOPE      2
    
    #define MAX_PICO_DEVICES 64
    #define TIMED_LOOP_STEP 500
    extern short tmpBuff[1024];
    // Constructor构造函数
    logData::logData(){
        noOfSamplesPerAggregate = 1;
    }
    // Deconstructor拆解
    logData::~logData(){
    
    }
    
    /***************************************************
     *  Declare non-member variables and functions声明非成员变量和函数
     *
     *
     ****************************************************/
    signed short *buffer;
    void __stdcall getBuffer(short **, short, unsigned int, short, short, unsigned int);
    unsigned int samplesPulled;
    
    // Get data buffer from device从设备中获取数据缓冲区
    void __stdcall getBuffer(short ** overviewBuffers,
                            short overflow, unsigned int triggeredAt,
                            short triggered, short auto_stop,
                            unsigned int nValues )
    {
        //Write device buffer to program buffer为程序缓冲区写设备缓冲区
        // Save the samples pulled per channel保存每个通道的样本
        samplesPulled = nValues;
    
        for(unsigned int i = 0; i < samplesPulled; i++){
            buffer[i*4] = overviewBuffers[0][i];
            buffer[i*4 + 1] = overviewBuffers[2][i];
            buffer[i*4 + 2] = overviewBuffers[4][i];
            buffer[i*4 + 3] = overviewBuffers[6][i];
        }
    }
    double voltage2;
    /***************************************************
     * FUNCTION FOR LOGGING STREAMING DATA用于记录流数据
     * Writes directly to binary file during logging在日志记录期间直接写入二进制文件
     * *************************************************/
    int stop;
    void logData::startLogging( short handle, unsigned long sampleInterval,
                       short timeUnit, unsigned long max_samples,
                       unsigned long overviewBufferSize, short loggingDuration,
                                PicoLogger* parentObject,
                                short rangeA, short rangeB, short rangeC, short rangeD)
    {
    
        uint16_t inputRanges [PS5000A_MAX_RANGES] = {
            10,
            20,
            50,
            100,
            200,
            500,
            1000,
            2000,
            5000,
            10000,
            20000,
            50000};
        typedef struct
        {
            int16_t DCcoupled;
            int16_t range;
            int16_t enabled;
            float analogueOffset;
        }CHANNEL_SETTINGS;
        typedef enum
        {
            SIGGEN_NONE = 0,
            SIGGEN_FUNCTGEN = 1,
            SIGGEN_AWG = 2
        } SIGGEN_TYPE;
        typedef enum
        {
            MODEL_NONE = 0,
            MODEL_PS5242A = 0xA242,
            MODEL_PS5242B = 0xB242,
            MODEL_PS5243A = 0xA243,
            MODEL_PS5243B = 0xB243,
            MODEL_PS5244A = 0xA244,
            MODEL_PS5244B = 0xB244,
            MODEL_PS5442A = 0xA442,
            MODEL_PS5442B = 0xB442,
            MODEL_PS5443A = 0xA443,
            MODEL_PS5443B = 0xB443,
            MODEL_PS5444A = 0xA444,
            MODEL_PS5444B = 0xB444
        } MODEL_TYPE;
        typedef struct
        {
            int16_t handle;
            MODEL_TYPE                  model;
            int8_t                      modelString[8];
            int8_t                      serial[10];
            int16_t                     complete;
            int16_t                     openStatus;
            int16_t                     openProgress;
            PS5000A_RANGE               firstRange;
            PS5000A_RANGE               lastRange;
            int16_t                     channelCount;
            int16_t                     maxADCValue;
            SIGGEN_TYPE                 sigGen;
            int16_t                     hasHardwareETS;
            uint16_t                    awgBufferSize;
            CHANNEL_SETTINGS            channelSettings [PS5000A_MAX_CHANNELS];
            PS5000A_DEVICE_RESOLUTION   resolution;
        }UNIT;
    
        // Create file name
        float fs = 1/(timeUnits[(short)timeUnit]*sampleInterval);
        std::string fsChar = std::to_string((long) fs);
        std::string fileName("Picoscope5000_" + fsChar + "Hz_" + timestampStr() + ".bin");
    
        /****************************
         *  OPEN STREAM打开流
         * Little endian, double precision (64 bit precision)小endian,双精度(64位精度)
         * *************************/
        QFile file(fileName.c_str());
        file.open(QIODevice::WriteOnly);
        QDataStream out(&file);
        out.setByteOrder(QDataStream::LittleEndian);
        out.setFloatingPointPrecision(QDataStream::SinglePrecision);
        // Write sample rate as first value将采样率写入第一个值
        out << fs;
    
        PICO_STATUS status=1;
        unsigned long maxSamples;
        int noOfPreTriggerSamples =0, noOfPostTriggerSamples = 1024, timeIndisposedMs;
        unsigned int timebase =127,//8us  1002,//3-2^32-2时间采样是一个很重要的控制采样间隔 8ns---------这里决定这个采样间隔。
        segmentIndex = 0;
        handle=16384;
         //为通道A配置PicoScop数据缓冲区
        int32_t bufferLth = 1024;//5000;
        uint16_t noOfWantedSamples=1024;//5000;
        short sReady=0;
        unsigned int  startIndex=0, noOfSamples=1500;
        short overflow;
        int j;
        UNIT unit;
        double voltage;
       //tmpBuff[1024]={0};
        double maxADCValue=32767;
        //如果停止键stop=0;则为执行程序,
        //如果停止键stop=1,则为停止程序。
        stop=0;
        if( handle=16384)
        {
            status = ps5000aSetDataBuffer(handle,
                                         PS5000A_CHANNEL_A,
                                         tmpBuff,   //* buffer
                                         1024,
                                         segmentIndex,
                                         PS5000A_RATIO_MODE_NONE);
           while(handle=16384)
           {
                sReady=0;
                status = ps5000aRunBlock(handle,noOfPreTriggerSamples,noOfPostTriggerSamples,timebase,&timeIndisposedMs,//在退出时,时间,以毫秒为单位范围将用于收集样本。
                                         segmentIndex,NULL,NULL);
    
                /*********************************************************************************
                *循环----步骤7设置block isready 模式等待数据收集完成
                **********************************************************************************/
                while (sReady== 0)
                    {
                        status = ps5000aIsReady(handle, &sReady);
                   // Sleep(25); // PICO HM
                    }
                /*********************************************************************************
                *循环----步骤8设置block GetValues模式等待数据收集完成
                **********************************************************************************/
                //下载通道A的记录数据
                status = ps5000aGetValues(handle,startIndex,&noOfSamples,PS5000A_RATIO_MODE_NONE,
                                          PS5000A_RATIO_MODE_NONE,segmentIndex,&overflow);
                /*********************************************************************************
                *循环----步骤9设置display显示数据
                **********************************************************************************/
             /*   PS5000A_DEVICE_RESOLUTION resolution = PS5000A_DR_15BIT;
    
                status = ps5000aGetDeviceResolution(handle, &resolution);
                       for(j=0;j<1024;j++)
                       {
                               voltage =(tmpBuff[j]*inputRanges[PS5000A_RANGE(rangeA)]/maxADCValue);
                               int voltage1=(voltage*1000);
                               voltage2=double(voltage1)/1000;
    
                               int n =1024;
                               int i;
                               double phi1;
                               double phi2;
                               phi1 = i/(double)(n-1)*M_PI;
                               phi2 = i/(double)(n-1)*M_PI+M_PI;
                             //  QString str1 = QString::number(voltage, 'd', 3);
                             //  QString str2 = QString::number(voltage/1000, 'd', 3);
                             //  ui->plot->graph(0)->addData(qCos(phi1),//0.6*2*qSin(phi1)+
                             //  voltage2);//-(qrand()/(double)RAND_MAX/5));
                             //  ui->plot->graph(1)->addData(qCos(phi2), 0.6*2*qSin(phi2)+voltage2);
                               if (-1000<voltage<1000)
                               {
                                   qDebug()<<voltage2<<"mV";
                               }
                               else if(voltage>1000||voltage<-1000)
                               {
                                 qDebug()<<voltage2/1000<<"V";
                               }
                               else
                               {
    
                               }
                        }
                  */
                /**********************************************************************************
                *循环----步骤10设置停止显示
                **********************************************************************************/
    
                   status = ps5000aStop(handle);
                   Sleep(400);
            }
                parentObject->loopLogging = true; // initialize loop condition初始化循环条件
                clock_gettime(CLOCK_MONOTONIC, &startTime);
    }
    
    
    /******************************************************************************
     * Write time stamp写时间戳
     * ***************************************************************************/
    std::string logData::timestampStr()
    {
        std::time_t rawtime;
        struct tm * timeinfo;
        char dataBuf[80];
    
        std::time(&rawtime); //get system tume得到系统tume
        timeinfo = std::localtime(&rawtime); // convert ot local time当地时间转换不
    
        std::strftime(dataBuf,sizeof(dataBuf),"%Y-%m-%d_%H-%M-%S",timeinfo);
        // Return a timestamp as a string作为字符串返回时间戳
        return std::string(dataBuf);
    }
    
    点赞 评论 复制链接分享

相关推荐