Main Site Documentation

Fez Cerb 40 II Uart Performance


#1

In my application, the module is communicating via uart at a baud rate of 115200. I have to compute 30 bytes that arrive every 20ms. I already tried several implementations using either events or polling. I also tried to decouple reading the data from computing it, using multithreading. It seems that I still cannot handle that amount of data. Maybe I should stick to RLP, but I was not able to find a good tutorial on how to set up serial communication with RLP. Any suggestions? Maybe stick to G400 although using 400 mhz cpu for such a tiny application seems to be a little overkill…

Best regards!


#2

I do not think you need rlp. I would loo and read the data in a thread continuously into a local static buffer, no allocation.

I always do GPS with no problems


#3

you say that you can not handle the data. What is happening?

The first question is how long does it take to process the 30 byte message? If it takes more than < 20ms, the RLP may be a solution, assuming you have coded the processing and serial communications very efficiently.

You have not entered your user profile, so we have no idea what is your level of experience with .net and the micro framework.

The first thing I would suggest is that you build a simple program which shows how you are handling serial communications. it should just read the serial data. If this simple program can not keep up, then post it here. You should be able to keep up with 1500 bytes per second.

Oh, welcome to the forums!


#4

Thanks for your replies. I used the following code to dig a little deeper:

public class Program
{
    static SerialPort _uart;
    static byte[] _receiverBuffer = new byte[25];
    static byte[] _tmpBuffer = new byte[1024];
    static int head = 0;
    public static void Main()
    {
        _uart = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);        
        _uart.Open();

        while (true)
        {
            int bytecount = _uart.BytesToRead;
            if (bytecount > 0)
            {
                if (bytecount <= _receiverBuffer.Length)
                {
                    if (_receiverBuffer.Length < head + bytecount)
                    {
                        head = 0;
                        Debug.Print("frame received with start byte: " + _receiverBuffer[0]);
                    }
                    // read from uart
                    head += _uart.Read(_receiverBuffer, head, bytecount);     
                }
                else
                {
                    _uart.Read(_tmpBuffer, 0, bytecount);
                    Debug.Print("Uart flushed");
                }
            }
        }
    }
}

The Input signal generated with a little console program looks like the one attached as image. The question, why I think the data cannot be handled fast enough, was actually the clue here. It seems that reading from the serial port also clears the register as well. If I don’t read fast enough, the fifo gets filled up with 1024 bytes which made me think it could not handle the data. This of course also happens when breaking during debug.

My last question (which should probably be part of an extra thread): Is there any other way to identify whole data packets then looking for some start byte?

Thanks for your effort and best regards!


#5

If bytes are less than zero then you need to sleep. Also, debug print is very slow. Only use it to show errors.


#6

@ altbrot - Yes, debugging can cause problems because you are not servicing the serial stream, and you can/will overrun the input buffer.

There is no builtin methodology for finding a packet. Serial is a stream. Bytes arrive in variable sized “bunches” of bytes. You can not depend upon reading a 30 byte message with one read.

If the 30 byte messages arrive every 20ms, and take less than 1ms @ 115200baud, then if a 10ms period passes without any data, then the next bytes to arrive is the start of a packet. Once you sync with the first packet, then it should be easy to stay in sync, unless you lose bytes.

I prefer to use a DataReceived event handler for serial data. I usually place the received bytes in a queue, for processing by another thread, but since your data arrives at a fixed interval, you could process your data in the event handler. Of course, you have to be out of the event handler in time to receive the next DataReceived event. That would be less than 20MS.