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

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

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



#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);
}

}




 //按下开始键下面是捕获数据的
/**************************
 *  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("没有发现设备。");
    }
}

线程文件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);
}