Gå til innhold

parse seriell data i C#?


Anbefalte innlegg

Skrevet

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)
        {

        }
    }
}
Videoannonse
Annonse
Skrevet

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.

Skrevet

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?

Skrevet

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.

Skrevet

Hvis du skal enumerere dem:

 

var input = "22 19 5";

var tall = input 
            .Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries)
            .Select(x => int.Parse(x, CultureInfo.InvariantCulture));
  • 2 uker senere...
Skrevet

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:

  • 1 år senere...
Skrevet

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?

Skrevet

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.

Skrevet

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. 

Skrevet

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. 

Skrevet (endret)

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
Skrevet

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.

Skrevet

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.

Skrevet

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);

Skrevet

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:

Skrevet

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.

Skrevet

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?

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...