Help with UART DataReceived

Im asking for some example code on how to properly break it at AA?

My example above in the post breaks it at AA, but i think it also discards the rest of the chunks until the 3rd AA comes in. So i get every other AA and rest of the chunks

I am now assuming you are a high school student just getting into programming. Here is some code to start you on a solution.

using System.Threading;

namespace AssemblyTest
{
    class Program
    {
        static byte[] inputBuffer = new byte[128];
        static byte[] assemblyBuffer = new byte[64];
        static int nextInAssemblyBuffer = 0;

        static void Main()
        {
            var comPort = ...; // initialization of comPort

            while (true)
            {
                if (comPort.BytestoRead > 0)
                {
                    // need to check to make sure BytesToRead is not greater than size of input
                    // buffer
                    var bytesRead = comPort.Read(inputBuffer, 0, comPort.BytesToRead);
                    for (int i = 0; i < bytesRead; i++)
                    {
                        byte b = inputBuffer[i];
                        if (b == 0xAA)
                        {
                            // assembly buffer contains full message
                            ProcessMessage();

                            // get ready for next message
                            assemblyBuffer[0] = b;
                            nextInAssemblyBuffer = 1;
                        }
                        else
                        {
                            assemblyBuffer[nextInAssemblyBuffer++] = b;
                        }
                    }
                    continue;
                }

                Thread.Sleep(10);
            }
        }
    }
}
7 Likes

Thanks, works perfectly! :smile: edit: NOT

File this one under “Further evidence of the maturity and infinite patience of this community”. Well done Mike.

5 Likes

I do this type of thing with serial all the time. I don’t have code just now as I am at work but you can also read 1 byte at a time (as long as there are bytes available) and check for your 0xAA and then wait for other bytes to be available (or timeout) and the read and process them.

Keep you thread sleep as short as possible, even zero if you want to be sure to capture faster serial data.

Ok, so after implementing the rest of the functionality with code Mike provided, this generates a CLR_E_WRONG_TYPE here:

assemblyBuffer[nextInAssemblyBuffer++] = b;

a collosal fail. I think when i process all the rest of the logic (which has thread.sleep), the seperate UART thread keeps filling the buffer and i dont know how to transfer from one thread to another.

Ill try reverting back to DataReceived event

The error is CLR_E_WRONG_TYPE, not CLR_E_WRONG_TYPE_OF_APPROACH. This looks like a type system error in the interpreter. The compiler thinks the types are ok, but the interpreter disagrees and threw. Might be able to work around it with an explicit cast or an intermediate variable. It has nothing to do with the algo that Mike provided.

How is this different from a gigantic or fatal failure?

Generally it is a good idea to understand what is causing an error rather changing the code to something that appears to work. Not understanding what has gone wrong means that you will have the opportunity to make the same mistake again.

3 Likes

In your example you are providing byte to byte array. I’ve tried explicit cast, it just tells its not needed. Stepping through code (when its not crashing) i can see that “b” is in fact byte, so i dont know where that error comes from.

Also I get “failed allocating blocks…” error after a few dozen actual receives - hence the collosal fail :stuck_out_tongue:

Im invoking an event after I assemble the message, that might be an issue.
Im gonna try to just set a flag to know when to process data in main thread, if that doesent work, im ditching the thread idea.

That error message usually means you are out of memory?

I don’t think this is a thread versus event issue.

Invoking an event from a thread should not be a problem.

Actually, threads do require heap space to save the thread context, including a whole new stack structure. This is one of several reasons that I use thread pools instead of threads, and/or rely on state machine constructs instead of threads. Threads can be necessary or, more often, are a programming crutch, but they always consume meaningful amounts of heap memory.

See also: Stairs project
One loop to run two separate asynchronous animation loops instead of a thread per animation loop.

Iike pornography it is difficult to define exactly what is a thread situation. But I know it when I see it.

And, don’t post in forums when you have been drinking in the sun.

2 Likes

So i ended up with a hybrid of my code and bits from Mike’s, its working now more then OK, no wrong types and out of mem, but its not perfect, still 2-3 fails per 2-3 dozen receives, its good i know how data should start so i can also check for that. All in all its now finished.

Thanks all who helped. I may post a video of what this is doing.

1 Like

One out of twelve messages fail? I hope you are not building airplanes. :face_with_raised_eyebrow:

1 Like

Hard time imaging airplane engineers use a single UART connection for anything that is important :smiley:

@Mike you want to fix that so its no fails? i can set up TeamViewer and connect all the hardware

You got me! I don’t really care about the failures. :grinning:

What baud rate are you using? With SITcore, there is more than enough processing speed to be able to handle high baud rates. I used the old G120 with a 57600 baud rate to process RS232 from a control system passing CAN bus data and it never lotst any packets.

1 Like

9600, its not the rate, its how i process data after receive “event” occurs.
Im open to someone with more experience then me looking at it on my machine.

You need to listen for the AA 55 as that appears to be constant and then wait until the correct number of bytes are in the RX buffer, then read them out and then process. If the data is fixed length, this is easy. If variable, you need to wait. Use state flags to know where in the RX stream you are.

Have a look at the Modbus library. It handles the received data in a thread and the length varies. It would be a good starting point as to how to handle the incoming data.