0

I had a Matlab function performing serial read(fread) from a serial device, the senor i get data from send 150 packets of 42 bytes per second it means it actually writes 6300 bytes per second to the serial port.

Recently i implemented the exactly the same code to read date packets from the port using c++ and it's ReadFile from port handler. in matlab i used availableBytes witch represents the data in read buffer and in c++ i read the cbInQue from the port handler, in matlab it is always close to zero but in c++ code i wrote it's getting bigger and bigger.

I should add here than i do just read the data and there is no other burdening over cpu by doing excessive job in c++ code.

Matlab Code is Exactly this:

s                       = serial(COMPort,'BaudRate',115200,'DataBits',8);
s.InputBufferSize       = 1000*1000*100;
fopen(s);
fwrite(s,hex2dec('C4'));fwrite(s,hex2dec('C1'));fwrite(s,hex2dec('29'));
fwrite(s,hex2dec('CB'));fread(s,8);%flushinput(s)
i                       = 0; % Counter
j                       = 0;
lost                    = 0;
PacketSize              = 42;
clc;disp('Started Sampling');
while i < Samples
    j                   = j + 1;
    Header              = fread(s,1);
    if Header == hex2dec('CB')

        pack                    = fread(s, PacketSize);
        cks                     = convert2int16(pack(41:42)) ;
        cksc                    = sum(pack(1:40)) + hex2dec('CB');

        if(cks - cksc == 0)
            i                       = i + 1;
            a_x(i,1)                = convert2float32bin(pack(1:4));
            a_y(i,1)                = convert2float32bin(pack(5:8));
            a_z(i,1)                = convert2float32bin(pack(9:12));
            w1(i,1)                 = convert2float32bin(pack(13:16));
            w2(i,1)                 = convert2float32bin(pack(17:20));
            w3(i,1)                 = convert2float32bin(pack(21:24));
            m1(i,1)                 = convert2float32bin(pack(25:28));
            m2(i,1)                 = convert2float32bin(pack(29:32));
            m3(i,1)                 = convert2float32bin(pack(33:36));
            tspan(i,1)              = convert2int32(pack(37:40))/19660800;
                if(mod(i,Rate) == 0)
                    if( i < CalibrCount)
                        disp(['Calibratuing ... [', num2str(100*i/CalibrCount),'%]']);
                    else
                        disp(['Time: ', num2str((i - CalibrCount)/Rate),'sec/ [', num2str(100*(i - CalibrCount)/(SampleCount - CalibrCount)) ,'%] AwPacks: ', num2str(floor(s.BytesAvailable/PacketSize))]);
                    end
                end
        else
            lost = lost + 1;
            disp('Packet Lost !!!!!!');
            disp(['Lost Count: ', num2str(lost), ' LossRatio:[' , num2str(100*lost/i), '%]']);
        end
    end

and the c++ code is something like this:

    int i{0};
    while (true)
    {
        Sensor->read(&header, sizeof(ReadType));
        if (header == Header_CB)
        {
            int add{0};
            GX2->read(packet, sizeof(packet));

            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].accX);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].accY);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].accZ);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].gyrX);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].gyrY);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].gyrZ);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].magX);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].magY);
            Bytes2Float(&packet[3] + 4 * add++, &imuData[i].magZ);
            // Bytes2Float(packet + 3, accX);
            // Bytes2Float(packet + 11, accZ);

            printf("accX: %+1.4f \taccY: %+1.4f \taccZ: %+1.4f i:%d buff: %d\n", imuData[i].accX,imuData[i].accY,imuData[i].accZ, i, GX2->Get_cbInQue());
            //system("@cls||clear");
            i++;
        }

in witch the Read Mthod of Serialport class is like this:

int SerialPort::read(void *buffer, unsigned int buf_size)
{
    DWORD bytesRead;
    unsigned int toRead = 0;

    ClearCommError(this->handler, &this->errors, &this->status);

    if (this->status.cbInQue > 0)
    {
        if (this->status.cbInQue > buf_size)
        {
            toRead = buf_size;
        }
        else
            toRead = this->status.cbInQue;
    }

    memset(buffer, 0, buf_size);

    if (ReadFile(this->handler, buffer, toRead, &bytesRead, NULL))
        return bytesRead;

    return 0;
}

just to mention: I removed all of ByeToFloat calls from the c++ code and i still got the problem of buffer getting bigger and bigger.

Compilation:

g++ -g main.cpp include/SerialPort.cpp include/Sensor.cpp  -o bin/main.exe -Iinclude
yekanchi
  • 813
  • 1
  • 12
  • 30
  • when comparing performance you should always mention what compiler options you used. I bet your code is limited by i/o, though still compiler optimizations turned on or not makes a difference – 463035818_is_not_an_ai Dec 13 '18 at 10:06
  • i simply use `g++ -g main.cpp -o main.exe` – yekanchi Dec 13 '18 at 10:08
  • I guess your problem is something else, nevertheless try to turn on compiler optimizations via `-O2` / `-O3`, the default is no optimizations – 463035818_is_not_an_ai Dec 13 '18 at 10:12
  • @yekanchi `g++ -g main.cpp -o main.exe` -- There is no point in measuring code that is not optimized. You are timing unoptimized code, thus the timings you're showing are meaningless. Turn on optimizations (`-O2` or `-O3`), recompile, and retest. – PaulMcKenzie Dec 13 '18 at 10:28
  • Also, if you're including `printf` in the C++ code, that alone could kill any performance. – PaulMcKenzie Dec 13 '18 at 10:32
  • I tired to use -O2 -O3, but the compiler throws lost of `first defined here` errors – yekanchi Dec 13 '18 at 10:34
  • What do you mean by "first defined here" errors? Your compiler is broken if you can't use the optimization switch. What exactly is the command-line you're using to compile? – PaulMcKenzie Dec 13 '18 at 10:43
  • itis here:https://paste.ubuntu.com/p/97xkKjtHpg/ when using Optimization, but without optimization, there is no compiler error – yekanchi Dec 13 '18 at 10:45
  • Look at the last line -- that is a linker error (`ld`), not a compiler error. You need to fix your broken project, as [this link](https://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there) describes all of the available optimization settings available. – PaulMcKenzie Dec 13 '18 at 10:48

0 Answers0