Compare commits

..

2 Commits

Author SHA1 Message Date
e3d5f52aa2 bug fix; cal/raw display 2025-04-14 18:20:52 +02:00
9c6a9a21a6 init Blake 2025-04-14 14:55:10 +02:00
11 changed files with 213 additions and 48 deletions

View File

@ -39,17 +39,32 @@ void DataReceiver::readData()
std::cout << "packet error. Got" << size_received_bytes << " bytes expected" << expected_size_bytes << std::endl;
continue;
}
else
{
// std::cout << "packet received. Got" << size_received_bytes << " bytes expected" << expected_size_bytes << std::endl;
}
for (int ethb = 0; ethb < ethBunch; ethb++)
{
int baseaddr = ethb * (DATA_PACKET_HEADER_SIZE + DATA_SYNC_HEADER_SIZE + dmaBunch*DATA_BLOCK_SIZE + DATA_RMS_FRAME_SIZE);
//check the header
if (BYTES2SHORT(tmpBuffer+baseaddr+0) != 0x5555)
if (BYTES2SHORT(tmpBuffer+baseaddr+0) != 0x5555){
// std::cerr << "header not found." << std::endl;
continue;
if (BYTES2SHORT(tmpBuffer+baseaddr+2) != COMMAND_DATA_TRANSFER)
}
//else { std::cerr << "header found." << std::endl; }
if (BYTES2SHORT(tmpBuffer+baseaddr+2) != COMMAND_DATA_TRANSFER){
// std::cerr << "transfer not found." << std::endl;
continue;
if ((BYTES2SHORT(tmpBuffer+baseaddr+4)*2) != (DATA_SYNC_HEADER_SIZE + dmaBunch*DATA_BLOCK_SIZE))
}
//else { std::cerr << "transfer found." << std::endl; }
if ((BYTES2SHORT(tmpBuffer+baseaddr+4)*2) != (DATA_SYNC_HEADER_SIZE + dmaBunch*DATA_BLOCK_SIZE/2)){
//std::cerr << "sync header not found." << std::endl;
continue;
}
//else { std::cerr << "sync header found." << std::endl; }
//read sync data;
SyncFrame sync;
@ -66,14 +81,26 @@ void DataReceiver::readData()
framesReceived++;
int baseaddr2 = baseaddr + dmab*DATA_BLOCK_SIZE;
if (outputEnabled)
//if (outputEnabled)
{
BufferData data_to_push(sensorsPerBoard * DATA_SAMPLES_PER_SENSOR);
data_to_push.sync_frame = sync;
int baseaddr3 = baseaddr2 + DATA_PACKET_HEADER_SIZE + DATA_SYNC_HEADER_SIZE;
for (int s = 0; s < (sensorsPerBoard * DATA_SAMPLES_PER_SENSOR); s++)
data_to_push.sensor_data[s] = 65535 - BYTES2INT(tmpBuffer + baseaddr3 + DATA_BYTES_PER_SAMPLE*s); //2 bytes RMS + 2 bytes CAL per channel
{
//uint64_t rawValue = BYTES2INT64(tmpBuffer + baseaddr3 + DATA_BYTES_PER_SAMPLE * s);
char * mybuffer= tmpBuffer + baseaddr3 + DATA_BYTES_PER_SAMPLE * s ;
BYTE2SD(mybuffer, data_to_push.sensorData[s]);
//data_to_push.sensorData[s].raw1 = static_cast<unsigned short>((rawValue << 0 ));
// data_to_push.sensorData[s].raw2 = static_cast<unsigned short>((rawValue << 16 ));
// For CAL values, adjust as needed based on your data format
// data_to_push.sensorData[s].cal1 = static_cast<short>((rawValue << 32));
//data_to_push.sensorData[s].cal2 = static_cast<short>((rawValue << 48));
//printBufferBits(mybuffer, sizeof(mybuffer));
//std::cerr << framesFromLastSig << " " << s << " " << data_to_push.sensorData[s].raw1 << " " <<data_to_push.sensorData[s].raw2 << " " << data_to_push.sensorData[s].cal1 << " " <<data_to_push.sensorData[s].cal2 << std::endl;
}
rms.mean = BYTES2SHORT(tmpBuffer+baseaddr+DATA_PACKET_HEADER_SIZE+DATA_SYNC_HEADER_SIZE+DATA_BLOCK_SIZE);
rms.sigma = BYTES2SHORT(tmpBuffer+baseaddr+DATA_PACKET_HEADER_SIZE+DATA_SYNC_HEADER_SIZE+DATA_BLOCK_SIZE + 2);

View File

@ -6,16 +6,17 @@
#include <QTimer>
#include <QThread>
#include <QSemaphore>
#include <cstring> // For std::memcpy
#include "cbuffer.h"
#define DATA_PACKET_HEADER_SIZE 6
#define DATA_SYNC_HEADER_SIZE 6
#define DATA_RMS_FRAME_SIZE 16 //8 unsigned short
#define DATA_BYTES_PER_SAMPLE 4 //RMS + CAL streamed in data RMSCALRMSCALRMSCAL etc
#define DATA_SAMPLES_PER_SENSOR 64
#define DATA_RMS_FRAME_SIZE 16 // 8 unsigned shorts
#define DATA_BYTES_PER_SAMPLE 8 // RAW1RAW2+CAL1+CAL2
#define DATA_SAMPLES_PER_SENSOR 32 //grab 2 channels per sample RAW1+RAW2
#define DATA_MAX_SENSORS_PER_BOARD 5
#define DATA_MAX_BUNCH 16 //max. product of dmaBunch * ethBunch
#define DATA_MAX_BUNCH 16 // Max. product of dmaBunch * ethBunch
//#define DATA_BLOCK_SIZE (DATA_SENSORS_PER_BOARD * DATA_SAMPLES_PER_SENSOR * DATA_BYTES_PER_SAMPLE)
#define DATA_BLOCK_SIZE (sensorsPerBoard * DATA_SAMPLES_PER_SENSOR * DATA_BYTES_PER_SAMPLE)
@ -35,8 +36,8 @@ typedef struct
unsigned short local_ctr;
unsigned short global_ctr;
unsigned short sma_state;
//these files are additional compared to STM side
unsigned short dummy = 0xFFFF; //for nice structure packing
// These fields are additional compared to STM side
unsigned short dummy = 0xFFFF; // For nice structure packing
int device_nr;
int data_ok;
} SyncFrame;
@ -55,11 +56,18 @@ public:
SyncFrame sync_frame;
RMSFrame rms_frame;
int buffer_size;
int* sensor_data; //4 byte int for RAW + CAL instead of 2byte unsigned short for one
BufferData() : buffer_size(0), sensor_data(NULL) {}
struct SensorData {
unsigned short raw1; // First 16-bit unsigned short
unsigned short raw2; // Second 16-bit unsigned short
signed short cal1; // First 16-bit signed short
signed short cal2; // Second 16-bit signed short
};
SensorData* sensorData; // Renamed from sensor_data
BufferData(int size) : buffer_size(0), sensor_data(NULL)
BufferData() : buffer_size(0), sensorData(nullptr) {}
BufferData(int size) : buffer_size(0), sensorData(nullptr)
{
resize(size);
}
@ -67,33 +75,33 @@ public:
void resize(int size)
{
if (size == buffer_size)
return; //no need to change
if (sensor_data)
return; // No need to change
if (sensorData)
{
delete[] sensor_data;
sensor_data = NULL;
delete[] sensorData;
sensorData = nullptr;
}
buffer_size = size;
if (size) //do not allocate memory for an empty buffer
sensor_data = new int[size];
if (size) // Do not allocate memory for an empty buffer
sensorData = new SensorData[size];
}
BufferData(const BufferData& master) : buffer_size(0), sensor_data(NULL)
BufferData(const BufferData& master) : buffer_size(0), sensorData(nullptr)
{
sync_frame = master.sync_frame;
rms_frame = master.rms_frame;
resize(master.buffer_size);
memcpy(sensor_data, master.sensor_data, buffer_size*sizeof(int));
std::memcpy(sensorData, master.sensorData, buffer_size * sizeof(SensorData));
}
BufferData& operator=(const BufferData& master)
{
if (this == &master)
return *this; //self-assignment
return *this; // Self-assignment
sync_frame = master.sync_frame;
rms_frame = master.rms_frame;
resize(master.buffer_size);
memcpy(sensor_data, master.sensor_data, buffer_size*sizeof(int));
std::memcpy(sensorData, master.sensorData, buffer_size * sizeof(SensorData));
return *this;
}
@ -101,8 +109,6 @@ public:
{
resize(0); // :)
}
//unsigned short sensor_data[DATA_SENSORS_PER_BOARD * DATA_SAMPLES_PER_SENSOR];
};
typedef CBuffer<BufferData> DataBuffer;
@ -111,21 +117,19 @@ class DataReceiver : public QObject
{
Q_OBJECT
public:
explicit DataReceiver(QObject *parent = 0);
explicit DataReceiver(QObject *parent = nullptr);
~DataReceiver();
void configureEthSettings(QHostAddress address_to_set, quint16 port_to_set);
void configureBunchSize(int dma, int eth);
void outputEnable(int en);
int frameRate = 0;
int devNr = 0;
int sensorsPerBoard = 2;
int sensorsPerBoard = 5;
DataBuffer dataBuffer;
signals:
void sigInit();
void sigDeinit();
@ -133,22 +137,22 @@ signals:
void sigDataReady(DataReceiver* ptr);
public slots:
void onTimer();
protected:
void init();
void deinit();
QThread thread;
QSemaphore initSemaphore;
QTimer* timer = NULL;
QUdpSocket* dataSocket = NULL;
QTimer* timer = nullptr;
QUdpSocket* dataSocket = nullptr;
QHostAddress address;
quint16 port;
int outputEnabled = 0;
int dmaBunch = 1;
int ethBunch = 1;
char tmpBuffer[DATA_MAX_PACKET_SIZE];
int framesReceived = 0; //to calculate frame rate
int framesReceived = 0; // To calculate frame rate
int framesFromLastSig = 0;
protected slots:

View File

@ -39,6 +39,10 @@ BPMDisplay::BPMDisplay(QWidget *parent) :
// Gray out the buttons when they are disabled
ui->pushButton_savecalib->setStyleSheet(expertModeEnabled ? "" : "background-color: gray;");
// Check if checkBox_toggleRawCal exists in UI
if (ui->checkBox_toggleRawCal) {
connect(ui->checkBox_toggleRawCal, &QCheckBox::stateChanged, this, &BPMDisplay::onDataToggleChanged);
}
}
@ -465,3 +469,8 @@ void BPMDisplay::updateStatus(unsigned short value)
{
ui->lcdNumber_status->display((value));
}
void BPMDisplay::onDataToggleChanged(int state) {
showCalibrated = (state == Qt::Checked);
plot();
}

View File

@ -29,8 +29,9 @@ public:
void setTitle(QString title);
QVector<signed short> buffer;
QVector<signed short> buffer; //unsigned short raw; signed short cal
QVector<signed short> rmsbuffer;
bool showCalibrated = false;
public slots:
@ -47,6 +48,7 @@ public slots:
void updateRms(unsigned short value);
void updateMax(unsigned short value);
void updateStatus(unsigned short value);
void onDataToggleChanged(int state);
@ -57,11 +59,16 @@ protected:
QVector<signed short> dataRMS;
private:
Ui::display *ui;
QRadioButton *radioButtonFixedScale; // Pointer to the Fixed Scale radio button
QRadioButton *radioButtonAutoscale; // Pointer to the Autoscale radio button
QButtonGroup *buttonGroup;
QCheckBox *checkBoxToggleRawCal; //for show raw or cal data
QMap<QString, QVector<signed short>> backgroundDataMap; // Map to store background data for each plane
bool subtractBackground = false; // Flag to track if background subtraction is enabled

View File

@ -167,10 +167,9 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkBox_expertmode">
<widget class="QCheckBox" name="checkBox_toggleRawCal">
<property name="text">
<string>expert
mode</string>
<string>Show caled</string>
</property>
</widget>
</item>
@ -182,6 +181,14 @@ calibration</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_expertmode">
<property name="text">
<string>expert
mode</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_loadcalib">
<property name="text">

View File

@ -1,4 +1,5 @@
#include "displayserver.h"
#include "helpers.h"
DisplayServer::DisplayServer(QObject *parent) : QObject(parent)
{
@ -106,6 +107,10 @@ void DisplayServer::plot()
//fill with data
int current_base = 0;
// Assuming 'sensor_data' is an array of ints and 'buffer' is a QVector<short>
BufferData::SensorData rawValue;
for (int dev_nr = 0; dev_nr < planeConfig[plane]->nr_devices; dev_nr++)
{
int dev_id = planeConfig[plane]->devices[dev_nr]->deviceConfig.device_id;
@ -113,8 +118,24 @@ void DisplayServer::plot()
if (nr_channels > lastFrame[dev_id].buffer_size)
nr_channels = lastFrame[dev_id].buffer_size; //check if there's really some data in the buffer
//WARNING!!! Device order is not yet implemented!!! (probably)
for (int i = 0; i < nr_channels; i++)
displays[plane]->buffer[current_base+i] = lastFrame[dev_id].sensor_data[i];
for (int i = 0; i < planeConfig[plane]->nr_sensors * 64 / 2 ; i++){ //should be 32
//displays[plane]->buffer[current_base+i] = lastFrame[dev_id].sensor_data[i]; //old code
// Use RAW values (index 2*i) or CAL values (index 2*i + 1)
rawValue = lastFrame[dev_id].sensorData[i]; // Get int(RAW1+RAW2)
//std::cerr << i <<" " << rawValue.raw1 << " " << rawValue.raw2 << " " <<rawValue.cal1 << " " <<rawValue.cal2 << " " <<std::endl;
if (!displays[plane]->showCalibrated) //RAW1, RAW2, ...
{
displays[plane]->buffer[current_base + 2*i] = static_cast<short>(rawValue.raw1);
displays[plane]->buffer[current_base + 2*i + 1] = static_cast<short>(rawValue.raw2);
}
else //CAL1, CAL2
{
displays[plane]->buffer[current_base + 2*i] = static_cast<short>(rawValue.cal1);
displays[plane]->buffer[current_base + 2*i + 1] = static_cast<short>(rawValue.cal2);
}
}
current_base += nr_channels;
displays[plane]->rmsbuffer[0] = lastFrame[dev_id].rms_frame.mean;
displays[plane]->rmsbuffer[1] = lastFrame[dev_id].rms_frame.sigma;

View File

@ -30,6 +30,9 @@ public:
int isActive();
~DisplayServer();
void unsetup();
// New boolean flag to control display of RAW or CAL data
bool showRawData = true; // Default is to show RAW data // use displays[plane]->showCalibrated instead
signals:
public slots:

View File

@ -34,7 +34,6 @@ EventBuilder::~EventBuilder()
//main processing slot
void EventBuilder::onNewData(DataReceiver* receiver)
{
short * newcopy_sensor_data = new short int[320];
while (checkBufferOccupancies())
{
//find lowest global sync value
@ -206,7 +205,7 @@ void EventBuilder::logDataToFile()
for (int board = 0; board < totalBoards; board++)
{
logFile.write((const char*)&(currentFrame[board].sync_frame), sizeof(SyncFrame));
logFile.write((const char*)currentFrame[board].sensor_data, currentFrame[board].buffer_size*sizeof(unsigned short));
logFile.write((const char*)currentFrame[board].sensorData, currentFrame[board].buffer_size*sizeof(int));
logFile.write((const char*)&(currentFrame[board].rms_frame), sizeof(RMSFrame));
}

View File

@ -95,3 +95,67 @@ void saveCsvFile(QString filename, QList<QVector<double>> params, QList<QVector<
file.close();
}
uint8_t reverseBits(uint8_t byte) {
uint8_t reversedByte = 0;
for (int i = 0; i < 8; ++i) {
reversedByte = (reversedByte << 1) | (byte & 1);
byte >>= 1;
}
return reversedByte;
}
void invertBits(char* buffer, size_t size) {
if (buffer == nullptr) {
// Handle error: buffer is null
return;
}
for (size_t i = 0; i < size; ++i) {
buffer[i] = ~buffer[i]; // Perform bitwise NOT operation
}
}
void swapEndian(char* buffer, size_t size) {
for (size_t i = 0; i < size; i += 2) {
std::swap(buffer[i], buffer[i + 1]);
}
}
void BYTE2SD(char* mybuffer, BufferData::SensorData& data) {
// Ensure the buffer has at least 8 bytes
if (mybuffer == nullptr) {
// Handle error: buffer is null
return;
}
// // Reverse bits of each byte in the buffer
// for (size_t i = 0; i < 8; ++i) {
// mybuffer[i] = reverseBits(static_cast<uint8_t>(mybuffer[i]));
// }
// Invert bits of each byte in the buffer
invertBits(mybuffer, sizeof(mybuffer));
swapEndian(mybuffer, sizeof(mybuffer));
// Combine the first 4 bytes into raw1 and raw2
uint32_t raw_value;
std::memcpy(&raw_value, mybuffer, sizeof(raw_value));
data.raw1 = static_cast<uint16_t>(raw_value & 0xFFFF); // Lower 16 bits
data.raw2 = static_cast<uint16_t>((raw_value >> 16) & 0xFFFF); // Upper 16 bits
// Combine the next 4 bytes into cal1 and cal2
int32_t cal_value;
std::memcpy(&cal_value, mybuffer + 4, sizeof(cal_value));
data.cal1 = static_cast<int16_t>(cal_value & 0xFFFF); // Lower 16 bits
data.cal2 = static_cast<int16_t>((cal_value >> 16) & 0xFFFF); // Upper 16 bits
}
void printBufferBits(const char* buffer, size_t size) {
for (size_t i = 0; i < size; ++i) {
// Print each byte in binary
std::bitset<8> bits(static_cast<unsigned char>(buffer[i]));
std::cerr << bits << ' ';
}
std::cerr << std::endl;
}

View File

@ -11,6 +11,18 @@
#include <QVector>
#include <QFile>
#include <QTextStream>
#include <cstdint>
#include <cstring> // for std::memcpy
#include "datareceiver.h"
#include <iostream>
#include <bitset>
void BYTE2SD(char* mybuffer, BufferData::SensorData& data);
void printBufferBits(const char* buffer, size_t size) ;
uint8_t reverseBits(uint8_t byte);
void invertBits(char* buffer, size_t size);
void swapEndian(char* buffer, size_t size);
//byte array <-> unsiged short conversion
#define SHORT2BYTES(sh,by) {by[0] = (sh>>8) & 0xFF; by[1] = sh & 0xFF;}
@ -31,7 +43,17 @@
(static_cast<unsigned char>((by)[2]) << 8) | \
(static_cast<unsigned char>((by)[3]))\
)
#define BYTES2INT64(by) \
( \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[0])) << 56) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[1])) << 48) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[2])) << 40) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[3])) << 32) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[4])) << 24) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[5])) << 16) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[6])) << 8) | \
(static_cast<uint64_t>(static_cast<unsigned char>((by)[7])) ) \
)
QString ip2num(QString input, unsigned char* numbers = NULL);
//go to the main branch of settings

View File

@ -33,4 +33,6 @@ protected:
};
#endif // HISTOGRAM_H