PicoScope 7 Software
Available on Windows, Mac and Linux
Code: Select all
void myStreamDataHandler(int sampling_duration, int sampling_freq, bool IsChannelAOpen, bool IsChannelBOpen, bool CouplingMode[2], int VoltageRange[2]) {
int32_t i, j;
int temp_Count = 0;
uint32_t sampleCount = 50000; /* Make sure buffer large enough */
FILE* fp = NULL;
int16_t* buffers[PS4000_MAX_CHANNEL_BUFFERS/2];
int16_t* appBuffers[PS4000_MAX_CHANNEL_BUFFERS/2];
PICO_STATUS status;
uint32_t sampleInterval = 1;
int32_t index = 0;
int32_t totalSamples = 0;
uint32_t triggeredAt = 0;
int16_t retry = 0;
BUFFER_INFO bufferInfo;
UNIT_MODEL* unit = new UNIT_MODEL;
status = ps4000OpenUnit(&(unit->handle)); // Avvio la comunicazione con il Picoscope
// Avvio casi limiti
if (unit->handle == 0) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL,(LPCTSTR)"ERRORE: Picoscope non trovato, assicurarsi che sia connesso al PC", NULL, 0x00000000L);
}
else if (unit->handle == -1) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: Impossibile avviare il Picoscope, verificare lo stato d'integrità del dispositivo", NULL, 0x00000000L);
}
// Check dello status del Picoscope
if ((status != PICO_OK) && (status == PICO_EEPROM_CORRUPT))
{
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: Picoscope danneggiato (EEPROM_CORRUPT), verificare lo stato d'integrità del dispositivo", NULL, 0x00000000L);
}
get_info(unit); //Setto la variabile unit con tutti i dati specifici del dispositivo
// Calcolo numero di sample necessari al nostro caso, tramite OVERRIDE della variabile pre-dichiarata
if (sampling_duration != 0 && sampling_freq!= 0) {
sampleCount = static_cast(sampling_duration * sampling_freq); // Durata/Periodo per MegaSamples => MS/s => MHz => AGGIUNGERE LIMITE DI 80 MS/s
} // OVERRIDE DEL SAMPLING COUNT LIMITE = 80 MS/s in Real-Time per il nostro 4224 IEPE
// Setto il buffer
for (i = 0; i < unit->channelCount; i++) // create data buffers
{
buffers[i] = (int16_t*)calloc(sampleCount, sizeof(int16_t));
// buffers[i * 2 + 1] = (int16_t*)calloc(sampleCount, sizeof(int16_t));
status = ps4000SetDataBuffers(unit->handle, (PS4000_CHANNEL)i, buffers[i * 2], buffers[i * 2 + 1], sampleCount);
if (status != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: non è stato possibile allocare i buffer, controlla lo stato d'integrità del PC.", NULL, 0x00000000L);
break;
}
// Application buffers to copy data into
appBuffers[i] = (int16_t*)malloc(sampleCount * sizeof(int16_t));
// appBuffers[i * 2 + 1] = (int16_t*)malloc(sampleCount * sizeof(int16_t));
}
bufferInfo.unit = unit;
bufferInfo.driverBuffers = buffers;
bufferInfo.appBuffers = appBuffers;
// Setto i channel per il compito da svolgere
if (IsChannelAOpen == true && IsChannelBOpen != true) { // Solo Channel A
status = ps4000SetChannel(unit->handle, PS4000_CHANNEL_B, int16_t(false), int16_t(CouplingMode[1]), (PS4000_RANGE)VoltageRange[1]);
status = ps4000SetChannel(unit->handle, PS4000_CHANNEL_A, int16_t(true), int16_t(CouplingMode[0]), (PS4000_RANGE)VoltageRange[0]);
if (status != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: non è stato possibile avviare il Channel A, verificare collegamenti e stato integrità dispositivo.", NULL, 0x00000000L);
}
}
else if (IsChannelAOpen != true && IsChannelBOpen == true) { // Solo Channel B
status = ps4000SetChannel(unit->handle, PS4000_CHANNEL_A, int16_t(false), int16_t(CouplingMode[0]), (PS4000_RANGE)VoltageRange[0]);
status = ps4000SetChannel(unit->handle, PS4000_CHANNEL_B, int16_t(true), int16_t(CouplingMode[1]), (PS4000_RANGE)VoltageRange[1]);
if (status != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: non è stato possibile avviare il Channel B, verificare collegamenti e stato integrità dispositivo.", NULL, 0x00000000L);
}
}
else if (IsChannelAOpen == true && IsChannelBOpen == true) { // Tutte due i channel attivi
status = ps4000SetChannel(unit->handle, PS4000_CHANNEL_A, int16_t(true), int16_t(CouplingMode[0]), (PS4000_RANGE)VoltageRange[0]);
if (status != PICO_OK) {
status = ps4000CloseUnit(unit->handle); // Soluzione conservativa: il dispositivo non può volare fino a quando tutto funziona!
// MessageBox(NULL, (LPCTSTR)"ERRORE: non è stato possibile avviare il Channel A, verificare collegamenti e stato integrità dispositivo.", NULL, 0x00000000L);
}
status = ps4000SetChannel(unit->handle, PS4000_CHANNEL_B, int16_t(true), int16_t(CouplingMode[1]), (PS4000_RANGE)VoltageRange[1]);
if (status != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: non è stato possibile avviare il Channel B, verificare collegamenti e stato integrità dispositivo.", NULL, 0x00000000L);
}
}
//Setting dei trigger per l'avvio misurazione
TRIGGER_CONDITIONS conditions;
conditions.channelA = CONDITION_DONT_CARE;
conditions.channelB = CONDITION_DONT_CARE;
conditions.channelC = CONDITION_DONT_CARE;
conditions.channelD = CONDITION_DONT_CARE;
conditions.aux = CONDITION_DONT_CARE;
conditions.pulseWidthQualifier = CONDITION_DONT_CARE;
TRIGGER_CHANNEL_PROPERTIES properties;
properties.thresholdLower = 0;
properties.thresholdUpper = 0;
properties.thresholdLowerHysteresis = 0;
properties.thresholdUpperHysteresis = 300;
properties.channel = PS4000_CHANNEL_A;
properties.thresholdMode = LEVEL;
if (ps4000SetTriggerChannelConditions(unit->handle, &conditions, 1) != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: è stato impossibile settare le condizioni di trigger. Controllare lo stato d'integrità del dispositivo.", NULL, 0x00000000L);
}
if (ps4000SetTriggerChannelDirections(unit->handle, NONE, RISING, NONE, NONE, NONE, NONE) != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: è stato impossibile settare le condizioni di trigger. Controllare lo stato d'integrità del dispositivo.", NULL, 0x00000000L);
}
if (ps4000SetTriggerChannelProperties(unit->handle, &properties, 1, 0, 0) != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: è stato impossibile settare le condizioni di trigger. Controllare lo stato d'integrità del dispositivo.", NULL, 0x00000000L);
}
// Avvio setting dello streaming
float SamplingPeriod = sampling_duration / sampleCount;
uint32_t UsedSamplingPeriod = sampling_freq; // Devo sfruttare un workaround per evitare la cancellazione numerica per rounding
enPS4000TimeUnits SampleUnit;
for (i = 0; i < 6; i++) {
if (UsedSamplingPeriod < 1000 && UsedSamplingPeriod > 1) { // Come funziona: il check parte dallo studio della frequenza, divido sempre per 1000 per poter settare
i++; // il giusto indice, trovato l'indice che permette di avere un valore di 1, questo invertito sarà
UsedSamplingPeriod = 1000 / UsedSamplingPeriod; // il formato del periodo effettivo. Il valore del periodo sarà comunque garantito perché 1/s => s.
SampleUnit = (enPS4000TimeUnits)(5-i); // Qualora avvenga la presenza di ordini decimali non acquisibili dall' uint32_t, allora procedo a indicare
break; // il sampling period di ordine inferiore dividendo 1000/Used Sampling Period ed addizionando l'indice.
} // N.B. Questo workaround è testato per valori interi, non decimali di Sampling Period.
else if (UsedSamplingPeriod == 1) {
SampleUnit = (enPS4000TimeUnits)(5 - i);
break;
}
else {
UsedSamplingPeriod = UsedSamplingPeriod / 1000;
}
}
int16_t Autostop_flag = false;
int16_t StreamingDataReady_flag = false;
int32_t *nMaxSample;
status = ps4000FlashLed(unit->handle, -1);
// status = ps4000MemorySegments(unit->handle, 8192, nMaxSample);
status = ps4000RunStreaming(unit->handle, &UsedSamplingPeriod, SampleUnit, uint32_t(1), uint32_t(sampleCount), int16_t(true), uint32_t(1), sampleCount);
if (status != PICO_OK) {
status = ps4000CloseUnit(unit->handle);
// MessageBox(NULL, (LPCTSTR)"ERRORE: è stato impossibile avviare lo streaming. Controlla connessioni e stato integrità dispositivo.", NULL, 0x00000000L);
}
// Streaming waiting loop
while (Autostop_flag == false && totalSamples != sampleCount) {
// Poll until data is received. Until then, GetStreamingLatestValues wont call the callback.
StreamingDataReady_flag = false;
status = ps4000GetStreamingLatestValues(unit->handle, (ps4000StreamingReady)DeviceFusion::CallBackStream, &bufferInfo);
Sleep(10); // sleep di 10 ms per evitare un sovraccarico di richiesta di dati
index++;
if (StreamingDataReady_flag && g_sampleCount > 0) /* can be ready and have no data, if autoStop has fired */
{
totalSamples += g_sampleCount;
}
}
// Chiusura del dispositivo
status = ps4000Stop(unit->handle);
status = ps4000CloseUnit(unit->handle);
// Libera il buffer
for (i = 0; i < unit->channelCount * 2; i++){
free(buffers[i]);
free(appBuffers[i]);
}
}
*************************************************************************************************************
// IN APPLICATION MAIN
inline void __stdcall CallBackStream(int16_t handle, int32_t noOfSamples, uint32_t startIndex, int16_t overflow, uint32_t triggerAt, int16_t triggered, int16_t autoStop, void* pParameter) {
int32_t channel;
BUFFER_INFO* bufferInfo = NULL;
int32_t g_sampleCount;
int32_t g_startIndex;
int32_t stop_NOW = 0;
int16_t Autostop_flag;
int16_t StreamingDataReady_flag;
if (pParameter != NULL)
{
bufferInfo = (BUFFER_INFO*)pParameter;
}
// Copy data in callback
if (bufferInfo != NULL && noOfSamples)
{
for (channel = 0; channel < bufferInfo->unit->channelCount; channel++)
{
if (bufferInfo->unit->channelSettings[channel].enabled)
{
if (bufferInfo->appBuffers && bufferInfo->driverBuffers)
{
// Max buffers
if (bufferInfo->appBuffers[channel] && bufferInfo->driverBuffers[channel])
{
memcpy_s(&bufferInfo->appBuffers[channel][startIndex], noOfSamples * sizeof(int16_t),
&bufferInfo->driverBuffers[channel][startIndex], noOfSamples * sizeof(int16_t));
}
// Min buffers
/*if (bufferInfo->appBuffers[channel * 2 + 1] && bufferInfo->driverBuffers[channel * 2 + 1])
{
memcpy_s(&bufferInfo->appBuffers[channel * 2 + 1][startIndex], noOfSamples * sizeof(int16_t),
&bufferInfo->driverBuffers[channel * 2 + 1][startIndex], noOfSamples * sizeof(int16_t));
}*/
}
}
}
}
g_sampleCount = noOfSamples;
g_startIndex = startIndex;
MyGraph dlg;
dlg.drawchart(g_startIndex, g_sampleCount, bufferInfo->appBuffers[0]);
Autostop_flag = true;
StreamingDataReady_flag = true;
}