C#, odbiór ramki danych

0

Witam,
mam problem odnośnie odbioru ramki z miernika. Ramka nie jest wysyłana w całości, tylko podzielona jest na kilka części, w jaki sposób odebrać całą ramkę ?
Przykładowa cała ramka: 41550200000408
Na początku i na końcu ramki jest spacja, 4 i 1 na początku się nie zmieniają.

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
                     string dataIN   = serialPort1.ReadExisting();
                   
                     this.Invoke(new EventHandler(ShowData));
        }

Z góry dziękuję za pomoc :)

0

jest znak końca linii (albo jakikolwiek, który nie może wystąpić w środku ramki ale zawsze jest na końcu) na końcu?
ramka ma stałą długość?

0

Tak ramka ma stałą długość, na końcu znajduje się znak \r

2

to robisz tak.
deklarujesz zmienną prywatną ramka oraz bufor typu string i ustawiasz im wartość ""

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
                     string dataIN   = serialPort1.ReadExisting();
                     bufor+= dataIN;
                     int i = bufor.IndexOf("\r");
                     if (i > 0)
                     {
                           ramka = bufor.Substring(0, i);
                           bufor = bufor.Remove(0, i + 1);
                           this.Invoke(new EventHandler(ShowData));
                     }
        }

i teraz w ShowData jak odczytasz zmienną ramka to powinieneś dostać całą ramkę

0

Dzięki wielkie za pomoc abrakadaber, teraz dalsza część apki działa bez zarzutu ;)

0

Mam jeszcze jedno pytanie, w pierwszej wersji aplikacja była robiona w jednym okienku i wszystko działało po zastosowaniu porady abrakadaber. Teraz muszę przerobić ją na dwa okienka, w pierwszym jest wybór COM (cała konfiguracja), gdzie bo wyborze z comBoxa otwiera się drugie. W drugim jest zrobiony odbiór danych i wyświetlenie w odpowiedniej formie. W jaki sposób połączyć te dwa okienka w całość, żeby to wszystko działało ?
Wywołanie okna 2 po warunku odbywa się w ten sposób:

Form2 okno = new Form2();
 okno.ShowDialog();

W pierwszej wersji aplikacji dalej miałem wywołanie odbioru danych w ten sposób:

serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
0

dlaczego serialPort1 nie dasz na drugą formę, tam gdzie rzeczywiście chcesz go używać?

0

Mam go na pierwszej i na drugiej, na pierwszej konfiguruje serialPort1 a na drugiej ma być sam odbiór.

0

to tak nie działa - jak masz dwie osobne kontrolki na formach to one się same z siebie nijak nie komunikują pomiędzy sobą. Może pokaż trochę kodu, np. tam gdzie konfigurujesz port bo nie bardzo wiem jak Ci pomóc bez kodu.

0

Kod w pierszym formie :

 public partial class okno1 : Form
    {
        public okno1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            cBoxCom.Items.AddRange(ports);
        }

        private void cBoxCom_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                serialPort1.PortName = cBoxCom.Text;
                serialPort1.BaudRate = 9600;
                serialPort1.StopBits = System.IO.Ports.StopBits.One;
                serialPort1.Parity = System.IO.Ports.Parity.None;
                serialPort1.DataBits = 8;

                serialPort1.ReadTimeout = 500;
                serialPort1.WriteTimeout = 500;
                serialPort1.Open();

                progressBar1.Value = 100;

              //  serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);

            }
            catch(Exception error)
            {
                MessageBox.Show(error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            if(progressBar1.Value == 100)
            {
                Form2 okno = new Form2();
                okno.ShowDialog();
                
              //  this.Invoke(new EventHandler(serialPort1_DataReceived));
               // serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);

            }
        }
    }
}

drugie okno początek:

 public Form2()
        {
            InitializeComponent();
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            dataIN = serialPort1.ReadExisting();
1

możesz zrobić np. tak

        private SerialPort serialPort = null;

        public SerialPort Port
        {
                get { return serialPort; }
                set 
                {
                        if (serialPort != null)
                                serialPort.DataReceived  -= new SerialDataReceivedEventHandler(serialPort1_DataReceived);
                        serialPort = value;
                        if (serialPort != null)
                                serialPort.DataReceived  += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
                }
        }

        public Form2()
        {
            InitializeComponent();
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            dataIN = serialPort1.ReadExisting();
        }

        protected override void OnClosed(EventArgs e)
       {
                 Port = null;
                 base.OnClosed(e);
       }

a w form1

            if(progressBar1.Value == 100)
            {
                Form2 okno = new Form2();
                okno.Port = serialPort1;
                okno.ShowDialog();
            }
0

Zrobiłem tak jak napisałeś, w ogóle nie wywołuje się serialPort1_DataReceived, sprawdzałem breakpointem.
Za każdym razem warunek nie jest spełniony.

0

Jest ktoś mi w stanie pomóc ? Uczę się dopiero programowania i nie wiem jak sobie z tym problemem poradzić.

0

Analogowo czy cyfrowo wysyłasz tą ramkę?

0

Ramka jest odbierana z elektronicznego miernika siły po przez podłączenie po RS232 do komputera

0

wyślij tą ramkę tak samo jak inne urządzenia na ps/2

Czyli jak jak jest sygnał na zegarze to sprawdzasz na linii przesyłu czy jest 0 czy 1, ale tylko jeśli sygnał na zegarze jest narastający w ten sposób najłatwiej jak się da przesyłasz informacje.

0

Chodzi o to, że program mi działał na jednym oknie, a jak zrobiłem na dwa to nie chce mi się wywołać funkcja serialPort1_DataReceived
Serial Port jest tak samo skonfigurowany jak poprzednio

0

Dej numer miernika jakiś model id czy coś, wrzucę to w google bo nie wiem co tam zastosowali.

0

Tak, dostaję ramki w kilku kawałkach tak jak na początku postu napisałem, potem obsługę odebranych danych mam już zrobioną i wszystko ładnie wyświetla pomiar i jednostkę.
Sęk w tym, że po zrobieniu tego samego na dwa okna nie wiem jak to ze sobą powiązać. To co kolega abrakadaber napisał działa do tego miejsca, że przeskakuje już do form2, tylko, że nie wywołuje funkcji odbioru danych SerialPort1_DataReceived. Wartość SeriPort zawsze jest równa null.

0

Czyli działa odczyt danych?

0

Ogólnie w aplikacji działa, problem jest z tym, żeby dwa Formy ze sobą połączyć

1

w załączniku masz przykładowy projekt z dwiema formami - jedna główna oraz druga z wyborem numeru portu COM.

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