0

I am a beginner at C# and would like some advice on how to solve the following problem:

My main code include 2 thread, first thread is for sending and receiving data and second thread is just for plotting chart and label of calculated values.

First thread first send read command for register 1 to ADC true FTDI direct command and get 24 bit from ADC. Than my code send read command for register 2 to ADC and get 24 bit from ADC and everything spins in a loop again. Second thread is just for plotting chart and label of calculated values with some built-in delay for better monitoring.

The FTDI and ADC are capable running at 120000 baud rates. Problem is that if I set the baud rate 9600 or 115200, the speed of reading data is always the same. While loop spins only cca 40-50 time/s (I set counter to detect). I detect that the slowest part of the code is waiting for all bytes (while (numBytesAvailable < numBytesNeed)), so I increased a lot baud rate and there is no improvements. What could be wrong?

FTDI settings:

         ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
        // Open first device in our list by serial number
        if (ftdiDeviceCount != 0) { 
            ftStatus = myFtdiDevice.OpenBySerialNumber(ftdiDeviceList[0].SerialNumber);
            // Set Baud rate to 115200
            ftStatus = myFtdiDevice.SetBaudRate(115200);
            // Set data characteristics - Data bits, Stop bits, Parity
            ftStatus = myFtdiDevice.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, 
        }

Main code Thread1:

        UInt32 numBytesWritten = 0;
        UInt32 numBytesRead = 0;
        UInt32 numBytesAvailable = 0;
        UInt32 numBytesNeed = 3;
while (read_data)
        {
            ftStatus = myFtdiDevice.Write(sync3, sync3.Length, ref numBytesWritten); //set reg1
            ftStatus = myFtdiDevice.Write(sync10, sync10.Length, ref numBytesWritten); //READ command

            //wait for all data 
            do
            {
                ftStatus = myFtdiDevice.GetRxBytesAvailable(ref numBytesAvailable);

            }
            while (numBytesAvailable < numBytesNeed);

            //read data
            byte[] readData1 = new byte[3];
            ftStatus = myFtdiDevice.Read(readData1, numBytesAvailable, ref numBytesRead);
            int left_justified1 = (readData1[2] << 24) | (readData1[1] << 16) | (readData1[0] << 8);
            int result = left_justified1 >> 8;

            v = ((((4.096 / 16777216) * result) / 4) * 250); //calculate voltage

            ftStatus = myFtdiDevice.Write(sync4, sync4.Length, ref numBytesWritten); //set reg2
            ftStatus = myFtdiDevice.Write(sync10, sync10.Length, ref numBytesWritten); //READ command

            //wait for all data to read
            do
            {
                ftStatus = myFtdiDevice.GetRxBytesAvailable(ref numBytesAvailable);

            } while (numBytesAvailable < numBytesNeed);

            //read data
            byte[] readData2 = new byte[3];
            ftStatus = myFtdiDevice.Read(readData2, numBytesAvailable, ref numBytesRead);
            int left_justified2 = (readData2[2] << 24) | (readData2[1] << 16) | (readData2[0] << 8);
            result = left_justified2 >> 8;

            a = ((((4.096 / 16777216) * result) / 4) / 0.1); //calculate current
        }
mrkefca
  • 55
  • 8
  • Maybe it doesn't generate data any faster? – CodeCaster Feb 26 '21 at 11:25
  • Probably nothing. Bits per seonds and you are reading bytes so the character rate is 1/10 the Baud. Windows have times that pass the data to/from the UART which can slow the rate. It is better to use Async (than Sync) which bypasses some of these timers. The code is also slowing down operation. The while/do is loops is just wasting time. The async methods don't significantly slow down the processor the way the loops do. – jdweng Feb 26 '21 at 11:29
  • On oscilloscope I see that right after read command we get 24 bit back from ADC, and than take a long time for c# to process data and than send another read command and get immediately 24 bit back from ADC. – mrkefca Feb 26 '21 at 11:32
  • 1
    Use ASYNC method. I'm an EE and being using serial port on PC since the 1980s. Every Microsoft operating system since DOS the serial port is very slow using SYNC methods. Alway have to switch to ASYNC to speed up interface. there is a delay in windows from the time data is received by UART to the time your software actually gets data. If you put Console.Writeline() with the time you receive the data is will actually be delayed from time you see on scope. – jdweng Feb 26 '21 at 13:28

0 Answers0