Gå til innhold

parse seriell data i C#?


Anbefalte innlegg

Mottar sensordata fra Arduino UNO (temperatur, fuktighet og jordfuktighet) via serieporten i C# og vil presentere dette i tre tekstbokser, men sliter med å få det til.

Hvordan splitter man en strøm av seriell data slik at jeg kan presentere tallene i tre ulike tekstbokser?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace Recieve_Show_Save_data_from_Arduino
{
    public partial class Form1 : Form
    {
        private SerialPort myport;
        private DateTime datetime;
        private string in_data;
        
        public Form1()
        {
            InitializeComponent();
        }

        private void start_btn_Click(object sender, EventArgs e)
        {
            myport = new SerialPort();
            myport.BaudRate = 9600;
            myport.PortName = port_name_tb.Text;
            myport.Parity = Parity.None;
            myport.DataBits = 8;
            myport.StopBits = StopBits.One;
            myport.DataReceived += Myport_DataReceived1;
            try
            {
                myport.Open();
                time_text_box.Text = "";
                
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message, "Error");
            }

        }

        void Myport_DataReceived1(object sender, SerialDataReceivedEventArgs e)
        {

            in_data = myport.ReadLine();
            
            this.Invoke(new EventHandler(displaydata_event));
            /*String dataFromArduino = myport.ReadLine();
            String[] dataTempHumidMoisture = dataFromArduino.Split();
            int Temperature = (int)(Math.Round(Convert.ToDecimal(dataTempHumidMoisture[0]), 0));
            int Humidity = (int)(Math.Round(Convert.ToDecimal(dataTempHumidMoisture[1]), 0));
            int SoilMoisture= (int)(Math.Round(Convert.ToDecimal(dataTempHumidMoisture[2]), 0));
            temp__text_Box.Text = Temperature.ToString() + "C";
            humidity_text_Box.Text = Humidity.ToString() + "%";
            soil_moisture_textbox.Text = SoilMoisture.ToString() + "%";*/
            
            



        }

        private void displaydata_event(object sender, EventArgs e)
        {
            datetime = DateTime.Now;
            string time = datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second;
            time_text_box.Text = time;
          
          

        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void port_name_tb_TextChanged(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }
    }
}
Lenke til kommentar
Videoannonse
Annonse

Det er flere måter man kan splitte en String. Det kommer an på hvordan strengen er generert i Arduino.

En måte er å ha en delimiter (f.eks space, komma, semikolon) mellom feltene. En annen måte er å ha fast lengde på feltene.

Jeg får tre sensorverdier som tre rene tall slik: 22 19 5

Jeg får lest de av i et tekstfelt, men skjønner ikke hvordan jeg skal splitte dette? Hvordan mener du man splitter det med (komma, semikolon etc)  ??

kan du gi meg en kodesnutt?

Lenke til kommentar

Her er noe tilfeldig kode jeg fant i et prosjekt jeg har liggende:

string[] parts = inpLine.Split(new char[] {' ', ','});                              // Tokenize string, 
List<string> tokens = new List<string>();
foreach (string s in parts)
{
	if (s.Length != 0)
	{
		tokens.Add(s);
	}
}
double Xp = int.Parse(tokens[0]) * sosiEnhet;
double Yp = int.Parse(tokens[1]) * sosiEnhet; 

Split funksjonen her ser etter to mulige delimiters, space og komma.

Lenke til kommentar
  • 2 uker senere...

Her er noe tilfeldig kode jeg fant i et prosjekt jeg har liggende:

string[] parts = inpLine.Split(new char[] {' ', ','});                              // Tokenize string, 
List<string> tokens = new List<string>();
foreach (string s in parts)
{
	if (s.Length != 0)
	{
		tokens.Add(s);
	}
}
double Xp = int.Parse(tokens[0]) * sosiEnhet;
double Yp = int.Parse(tokens[1]) * sosiEnhet; 

Split funksjonen her ser etter to mulige delimiters, space og komma.

Takk Hårek, denne funka etter litt redigering  :w00t:

Lenke til kommentar
  • 1 år senere...

Her er noe tilfeldig kode jeg fant i et prosjekt jeg har liggende:

string[] parts = inpLine.Split(new char[] {' ', ','});                              // Tokenize string, 
List<string> tokens = new List<string>();
foreach (string s in parts)
{
	if (s.Length != 0)
	{
		tokens.Add(s);
	}
}
double Xp = int.Parse(tokens[0]) * sosiEnhet;
double Yp = int.Parse(tokens[1]) * sosiEnhet; 

Split funksjonen her ser etter to mulige delimiters, space og komma.

Tar opp en gamme tråd her. Jeg brukte din kodesnippet, men det som er problemet er at seriell data ikke alltid  kommer i teksboksen. Noen ganger funker det , andre ganger får jeg en feilmelding som sier følgende:

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.<br />
Parameter name: index'

Har du peiling på hvorfor dette skjer?

Lenke til kommentar

Visual Studio meny, velg Project. Velg Application, set Output Type til Console Application.

Så setter du inn f.eks Console.WriteLine(inpline); for å få utskrift.

 

Når prosjektet er ferdig setter du Output Type tilbake til Windows Application, så forsvinner konsollvinduet.

Lenke til kommentar

Visual Studio meny, velg Project. Velg Application, set Output Type til Console Application.

Så setter du inn f.eks Console.WriteLine(inpline); for å få utskrift.

 

Når prosjektet er ferdig setter du Output Type tilbake til Windows Application, så forsvinner konsollvinduet.

Har gjort det , men hva er inpline egentlig? Er det en komando? 

Hvor i programet legger jed dette? Console vidnuet popper opp, men jeg får den samme feilmeldinga også lukkes Console vidnuet seg. 

Lenke til kommentar

inpLine er input String, første linjen i koden du siterte.

Når du får en exception (feilmelding) så er vel konsollvinduet fremdeles åpent? Men det blir jo pushet i bakgrunnen, så du må hente det fram igjen. Se på Windows oppgavelinje.

Eller du kan sette breakpoint før du kommer til linjen der du får feilmeldingen. 

Lenke til kommentar

inpLine er input String, første linjen i koden du siterte.

Når du får en exception (feilmelding) så er vel konsollvinduet fremdeles åpent? Men det blir jo pushet i bakgrunnen, så du må hente det fram igjen. Se på Windows oppgavelinje.

Eller du kan sette breakpoint før du kommer til linjen der du får feilmeldingen. 

Hei, igjen, kjørte programmet nå og det funker.Greia er at det alltid funker første gangen jeg kjører programmet , men når jeg stopper det og prøver igjen får jeg denne feilmeldinga.

 

Uansett,når programmet funker så skriver Console vidnuet ut følgende ettersom verdiene kommer fra arduino via  fra serieporten inn i tekstboksene .Denne skriften kommer hvert sekund.

System.Collections.Generic.List'1[System.String]
System.Collections.Generic.List'1[System.String]
System.Collections.Generic.List'1[System.String]
System.Collections.Generic.List'1[System.String]

Noen peiling på hva og hvor feilen kan ligge? Jeg mistenker feilen kommer pga. at String array har en endelig størrelse og at det kanskje blir fylt opp? Nå skyter jeg veldig fra hofta, og evet egnetlig ikke hva jeg snakker om, det er bare en mistanke.

Endret av Tesla1856
Lenke til kommentar

Du skriver ut et objekt, ikke innholdet i objektet. 

Er det tokens du prøver å skrive ut? Du kan f.eks skrive Console.WriteLine(tokens.Count) for å få antall elementer.

Ok, da funket det plutselig igjen. Når jeg skriver ut tokens.Count i Consolvidnmuet så får jeg en liste av:

3 3 3 3 3 3 3 3 .....for hvert sekund.

Lenke til kommentar

Det kan vel stemme da, det er 3 tall du får hvert sekund.

Da kan du f.eks se på første tall:

int tmp1 = int.Parse(tokens[0]);  Console.Writeline(tmp1);

Jepp, et funket det. Den skriver ut tallet 23 23 23....., som jo er temperaturen DHT11 måler og sneder via serieporten. 

Dog , jeg har ikke løst problemet mitt. Hvorfor funker det en noen ganger , mens det andre ganger gir denne Index out of range feilmeldinga  :confused:

Lenke til kommentar

Det kan f.eks komme av at en av verdiene mangler, så tokens.Count er bare 2. 

Hvis du bruker faste index som f.eks tokens[0], tokens[1], tokens[2], så vil det feile. Man må passe på å ikke prøve å lese ut en verdi som ikke finnes. Sjekk tokens.Count først.

Nå funker det ikke jo, så jeg vet ikke hvordan jeg skal sjekke tokens Count nå? Console skjermen er bare svart de gangene programmet ikke funker?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...