Beantwortet Probleme beim Empfang eines Strings über serialPort

  • Freitag, 18. Januar 2013 08:27
     
     

    Hallo,

    ich habe folgendes Problem. Ich sende einen Befehl an einen µC dieser Befehl soll den µC anweisen mir seine Softwareversion zu schicken. Ich weis dass der Port richtig initialisiert und seine Eigenschaften richtig festgelegt sind, deshalb geh ich davon aus dass das Problem irgendwo beim Empfang oder beim Verarbeiten des Empfangenen liegt.

    dieses Codestück wird ausgeführt wenn ein Click auf einen Button erfolgt.

    //senden des Befehls zum senden der Softareversion
                String empfangene_snr = "";
                serialPort1.Open();
                serialPort1.Encoding = Encoding.Default;
                serialPort1.Write("#F0F2$1c?§");


                //Empfang der Strings in der die Softwareversion steht
                //und diesen string in temp.txt schreiben
                empfangene_snr = serialPort1.ReadExisting();
                StreamWriter softw_vers_in_temptxt = new StreamWriter(@"D:\temp.txt");
                softw_vers_in_temptxt.Write(empfangene_snr);
                serialPort1.Close();
                softw_vers_in_temptxt.Close();

    Ich hoffe jemand kann mir helfen weil ich noch weitere Daten vom µC abrufen und verarbeiten will/muss.

                           
    • Bearbeitet Erik_Stief Freitag, 18. Januar 2013 08:28
    •  

Alle Antworten

  • Freitag, 18. Januar 2013 09:47
    Beantworter
     
     Vorgeschlagene Antwort

    Hallo Erik,

    serielle Kommunikation ist relativ langsam... Und ein Ergebnis steht meist nicht unmittelbar zur Verfügung.

    Du solltest das DataReceived-Ereignis abonnieren, das ausgelöst wird, wenn Daten zurückgeliefert wurden.

    Fürs Testen wäre es einfacher die Ausgabe via Console.WriteLine vorzunehmen, das wird im VS-Ausgabefenster angezeigt. Hinweis: Eine Ausgabe in Windows-Steuerelemente ist im DataReceived Ereignis nicht direkt möglich, da das Ereignis nicht auf dem GUI-Thread ausgelöst wird (siehe Dokumentation).

    Gruß Elmar

  • Freitag, 18. Januar 2013 11:41
     
     

    Vielen Dank für deine Antwort Elmar,

    nachdem ich das ganze in einer Consolenaplication versucht habe, habe ich das Gefühl dass mein Eventhandler nicht angesprochen wird.

    Ich hab das Beispiel aus der Dokumentation ein wenig abgeändert weil ich ja erst den Befehl senden muss damit ich eine Antwort vom µC bekomme, aber alles was bei mir in der Konsole steht ist: "Press any key to continue..."

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO.Ports;
    using System.IO;


    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                SerialPort serialPort1 = new SerialPort("COM3");

                serialPort1.BaudRate = 9600;
                serialPort1.Parity = Parity.None;
                serialPort1.StopBits = StopBits.One;
                serialPort1.DataBits = 8;
                serialPort1.Handshake = Handshake.None;

                serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

                serialPort1.Open();
                serialPort1.Encoding = Encoding.Default;
                serialPort1.Write("#F0F2$1C?§");
                serialPort1.Close();


               
                

                Console.WriteLine("Press any key to continue...");
                Console.WriteLine();
                Console.ReadKey();
                
                

            }

            private static void DataReceivedHandler(
                            object sender,
                            SerialDataReceivedEventArgs e)
            {
                SerialPort sp = (SerialPort)sender;
                string indata = sp.ReadExisting();
                Console.WriteLine("Data Received:");
                Console.Write(indata);
                Console.ReadKey();
            }
        }
    }

    Hab ich den Eventhandler an der falschen Stelle? Kann ich den überhaupt an der falschen Stelle haben?

  • Freitag, 18. Januar 2013 12:53
    Beantworter
     
     Beantwortet Enthält Code

    Hallo Erik,

    da Du den Port gleich nach dem Senden schließt, kann da nichts (mehr) kommen.
    Ändere den unteren Abschnitt mal ab in:

                serialPort1.Open();
                serialPort1.Encoding = Encoding.Default;
                serialPort1.Write("#F0F2$1C?§");
                
                Console.WriteLine("Warten auf Antwort...");
                Console.WriteLine();
                Console.ReadKey();
    
                // Erst hier wird geschlossen
                Console.WriteLine("Verbindung getrennt.");
                serialPort1.Close();      
    

    Gruß Elmar

  • Mittwoch, 23. Januar 2013 07:26
     
     

    Hallo Elmar,

    hast natürlich recht.

    Vielen Dank

    Aber jetzt bin ich beim nächsten Problem angekommen.

    Und zwar bekomme ich nur die komplette Antwort angezeigt, wenn ich das Programm  Schritt für Schritt ausführe.

    Die Antwort sollte so aussehen: "#F2F0$E1000050000§"

    die Antworten sehen so aus:

    050000§

    §

    F0$E1000050000§

    Wir sind inzwischen sogar schon zu zweit dran und mein Partner hat eigentlich recht gute c# Kenntnisse aber es reicht trotzdem nicht. Wir haben es mit Filestream und Streamwriter versucht und mit sleep weil wir hofften die ganze Antwort würde empfangen.

    Soll ich deine erste Antwort als Antwort tagen? Die anfängliche Frage ist ja beantwortet ich hab nur nicht gewusst ob noch jemand hier reinschaut wenn ich es als beantwortet markiere.


    • Bearbeitet Erik_Stief Mittwoch, 23. Januar 2013 10:07
    •  
  • Donnerstag, 7. Februar 2013 01:15
     
     

    Hi,

    der Text kommt immer nur was gerade verfügbar ist, d.h. du musst das Ergebnis Puffern und solange warten, bis die Antwort vollständig ist.

    static StringBuilder buffer=new StringBuilder();

    private static void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
    {
       SerialPort sp = (SerialPort)sender;
       string indata = sp.ReadExisting();
      for(;;) // endlosschleife .. ( while(true) geht auch
     {
      int z=indata.IndexOf('§'); // vermute § markiert das ende des wertes

       if(z==-1)
      {
          buffer.Append(indata);
          break; // kein § schleife verlassen und weiter warten
       }else
       {
          buffer.Append(indata,  0, z+1); // bis inkl § anfügen  
          string Reponse=buffer.ToString();
            Console.WriteLine("Data Received: {0}", Reponse); // antwort verarbeiten
          // weiter mit nächster antwort
          buffer.Clear();
          indata=indata.Substring(z+1);  // könnte ja schon wieder ein § enthalten also in der schleife nochmal prüfen
       }
      }

    }

    sorry für die formatiereung ;)
    PS:  Encoding.ASCII  (0x00-0x7F) oder  Encoding.GetEncoding(1252)   (latin 1 zeichensatz, mit umlauten) wäre exakter und unabhängig von der betiebssystemsprache.


  • Donnerstag, 7. Februar 2013 08:48
    Beantworter
     
     

    Hallo Harald,

    bitte verwende für Code die vorgesehene Schaltfläche, dann sieht es auch "hübscher" aus.

    Kleine Anmerkungen zum Code selbst:
    static für die den StringBuilder und Methoden sollte man hier vermeiden.

    Das Encoding kann beim SerialPort angegeben werden und hängt von der Schnittstelle ab - da könnte auch Unicode verwendet werden. Siehe
    http://blogs.msdn.com/b/bclteam/archive/2006/05/26/608377.aspx

    Gruß Elmar