用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;
/****************************************************************************
/****************************************************************************
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};
/*********************************************************************************
//界面窗口的设计
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);
/*********************************************************************************
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,另一个支持整型)
/*********************************************************************************
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);
}