梁小浩啊 2017-07-11 03:42 采纳率: 0%
浏览 1074

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

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

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

  • 写回答

3条回答 默认 最新

  • 梁小浩啊 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);
    }
    

    }

    
    
    
    
    评论

报告相同问题?

悬赏问题

  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛