Nieprawidłowy odbior danych z uC

0

Cześć!

Wysyłam dane (bajty) z mikrokontrolera w postaci: "rozpoznawczy", "rozpoznawczy", "starszy", "młodszy", "starszy", "młodszy", ... , "rozpoznawczy", "rozpoznawczy", "starszy" ...
Bajtem rozpoznawczym jest 11111111, po dwóch takich bajtach idzie paczka danych.
Problem polega na tym, że dane mi się rozjeżdżają, wygląda to tak:

/16bit/starszy bajt/młodszy bajt/ - wyświetlone dane na richtextboxie
.../927/3/159/, /65535/255/255/ , /927/3/159/ , /927/3/159/ ... /927/3/159/ , /927/3/255/ , /65283/255/3/, /40707/159/3/ , /40707/159/3/ , /40707/159/3/ ...

Nie wiem, co jest przyczyną tego zjawiska - myślę, że może tu być problem z czyszczeniem buforu odbiorczego w odpowiedniej chwili.
Ma może ktoś pomysł na rozwiązanie tego problemu?

Myślałem nad czymś, co zaznaczyłem jako komentarz, tylko trzeba byłoby dodać czyszczenie buforu w odpowiednim momencie (jeśli moje podejrzenia są słuszne)

private void button1_Click(object sender, EventArgs e)
        {
            if (!SerialPort1.IsOpen)
            {
                SerialPort1.Open();

                /*byte current_byte = new byte();
                byte previous_byte = new byte(); previous_byte = 0;
                bool positioned = true;

                do
                {
                    if (positioned == true)
                    {
                        current_byte = (byte)SerialPort1.ReadByte();
                        positioned = false;
                    }
                    else
                    {
                        previous_byte = (byte)SerialPort1.ReadByte();
                        positioned = false;
                    }
                }
                while (current_byte != 255 && previous_byte != 255);*/

            }
            else
            {
                SerialPort1.Close();
            }
        }

        private byte First_byte;
        private byte Second_byte;
        private static bool Need_join = false; //co dwa bajty następuje łączenie 2x 8bitów na 16bitów

        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte this_byte = (byte)SerialPort1.ReadByte();

            if (Need_join == false)
            {
                    Need_join = true;
                    First_byte = this_byte;
            }
            else
            {
                Need_join = false;
                Second_byte = this_byte;
                this.Invoke(new EventHandler(display));
            }
        }

        private void display(object o, EventArgs e)
        {
            ushort Bytes = Join_bytes(First_byte, Second_byte);

            Rich1.AppendText(Bytes.ToString() + ' ' + First_byte.ToString() + ' ' + Second_byte.ToString() + '\n');
        }

        private static ushort Join_bytes(byte High, byte Low)
        {
            return (ushort)((High << 8) | Low);
        }
 

Bardzo prosiłbym o pomoc / wskazówkę,
Dzięki wielkie!

0

Nie znam C#, ale metoda SerialPort1_DataReceived() nie musi być chyba wywoływana za każdym razem gdy dotrze bajt. Wydaje mi się, że może się zdarzyć, że np. dwa bajty docierają zaraz po sobie, a wywoływany event(tak to się nazywa?) jest tylko raz. Sprawdzałeś to?

0

Racja, sprawdziłem to, lecz nadal pojawiały się błędy:

private void button1_Click(object sender, EventArgs e)
        {
            if (!SerialPort1.IsOpen)
            {
                SerialPort1.Open();
                SerialPort1.DiscardInBuffer();
            }
            else
            {
                SerialPort1.Close();
            }
        }

        private ushort two_bytes;

        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte first_byte, second_byte;
            first_byte = (byte)SerialPort1.ReadByte();
            second_byte = (byte)SerialPort1.ReadByte();

            two_bytes = Join_bytes(first_byte, second_byte);

            this.Invoke(new EventHandler(display));
        }
        ushort index = 0;
        private void display(object o, EventArgs e)
        {
            if (two_bytes == 65535)
            {
                Rich2.AppendText(index.ToString() + '\n');
                index = 0;
            }
            else index++;
            Rich1.AppendText(index.ToString() + ' ' + two_bytes.ToString() + '\n');
        }

        private static ushort Join_bytes(byte High, byte Low)
        {
            return (ushort)((High << 8) | Low);
        }
 

Ostatecznie przyczyną błędu była zbyt duża szybkość transmisji - BaudRate = 230,4k. Zmieniłem to na 115,2k i już wszystko działa,
Dzięki! :)

Jeszcze przy okazji małe pytanie: dlaczego przy zamykaniu portu aplikacja się zawiesza? Z tego co widzę po wywołaniu serialPort.Close() dane nadal nadchodzą, czemu tak się dzieje? Jak temu zapobiec?

0

Super.
Co do tego drugiego problemu- próbowałeś szukać odpowiedzi w Internecie czy tylko czekasz aż ktoś inny rozwiąże Twój problem? http://stackoverflow.com/questions/13876274/serialport-fires-datareceived-event-after-close

1 użytkowników online, w tym zalogowanych: 0, gości: 1