Serielle Daten Empfangen Netzteil Nice Power

OP #7717880
Lesenswert?

Hallo Ich Brauche mal euere Hilfe. Also Ich sah mich gezwungen für mein Nice Power China Netzteil selber ein Programm zur Fernsteuerung + Datenlogging zu schreiben.(original ist Schrott) Was zuerst nach keinem großen Problem aus sah, wurde dann aber schnell zu einem Riesen-Problem.

Ich bekomme die Daten im sek. Takt vom Netzteil (Seriell) nach dem Senden halbwegs sauber empfangen. OK nur wie kann ich die werte dann ordnen? In C++ kein Problem aber in C# Komme ich mir da verloren vor.

Da bekomme ich z. B. bei Ampere den String <C4000976000> Geliefert das bedeutet:

"<" Anfang (Immer gleich) "C400" Wert Zuordnung in dem Fall für Ampere. (Immer gleich) "0976" Hier den Wert in mA. 0-9999 "000" Ist mir unbekannt und (Immer gleich) ">" Übertragung zu Ende. (Immer gleich)

Oder Für Spannung <120 1227 0000> Was Bedeutet:

"<" Anfang (Immer gleich) "120" Wert Zuordnung in dem Fall Volt. (Immer Gleich) "1227" Hier den Wert für 12,30V. (Ändert sich natürlich die 4 Stellen) "000" Ist mir unbekannt und (Immer gleich) ">" Übertragung zu Ende. (Immer gleich)

So Weit ok. Wie Kann ich aus jeder Übertragung die Zuordnung und den Wert jeweils separieren und in die TextBox Schreiben lassen ?

Wäre Super, wenn mir jemand helfen können.

DANKE

Beispiele: <C4007973000> = 8,00Ampere <C4000976000> = 1Ampere <C4001483000> 1,5Ampere

<120 1227 0000> = 12,30 Volt <120 1108 9000> == 11,11Volt <120 1510 1000> 15,15 Volt

Angehängte Dateien:
#7717944
Lesenswert?

Hallo David B.,

Ich bekomme die Daten im sek. Takt vom Netzteil (Seriell) nach dem Senden halbwegs sauber empfangen. OK nur wie kann ich die werte dann ordnen?

Die Werte sortieren?!

Da bekomme ich z. B. bei Ampere den String <C4000976000> Geliefert das bedeutet:

"<" Anfang (Immer gleich) "C400" Wert Zuordnung in dem Fall für Ampere. (Immer gleich)

Benutze sinnvolle, sprechende Bezeichnungen. Für mich ist das ein Einheitenbezeichner. Denk' Dir was aus!

"0976" Hier den Wert in mA. 0-9999 "000" Ist mir unbekannt und (Immer gleich) ">" Übertragung zu Ende. (Immer gleich)

Oder Für Spannung <120 1227 0000> Was Bedeutet:

"<" Anfang (Immer gleich) "120" Wert Zuordnung in dem Fall Volt. (Immer Gleich) "1227" Hier den Wert für 12,30V. (Ändert sich natürlich die 4 Stellen) "000" Ist mir unbekannt und (Immer gleich) ">" Übertragung zu Ende. (Immer gleich)

So Weit ok. Wie Kann ich aus jeder Übertragung die Zuordnung und den Wert jeweils separieren und in die TextBox Schreiben lassen ?

Du schneidest die für die Anzeige relevanten Stellen mit Hilfe von Textbearbeitungsfunktionen wie "MID" oder so ähnlich aus und bearbeitest die weiter. Den numerischen Wert wandelst Du immer in eine Zahl. Den Einheitenbezeichner schneidest Du einfach aus. Dein Ausgabestring hat die Form "<numerischerWert> <physikalischeEnheit>".

Nach dem "Ausschneiden" folgt eine Fallunterscheidung à la "Select case" für alle Varianten von Einheitenbezeichnern. In Abhängigkeit von dem Einheitenbezeichner legst Du die Einheit für die Ausgabe fest und bearbeitest den numerischen Wert entsprechend und wandelst den neuen Wert in einen String. Wert-String und Einheitenstring ergeben dann zusammen die Ausgabe für das Formular.

Aus Deinen Beispielen kann mein ungeübtes Auge keine Regeln für die numerische Nachbearbeitung ableiten!

(Firma: Privat) #7718177
Lesenswert?

Wenn die Blanks auch mit drin sind, hast du ja gleich 3 Teilstrings. Da greifst du halt den zweiten raus. Schau mal, was deine Sprache her gibt. Da sind bestimmt Stringfunktionen dabei, mit denen du sowas rausgreifen kannst.

Ansonsten, wenn zusammenhängend, würde ich den einen Buchstaben und die spitzen Klammern zuerst rauslöschen. Zur Fallunterscheidung hast du dann "400" für Ampere oder "120" für Volt und die nächsten 4 Ziffern sind dann deine Werte. Die ersten zwei Ziffern sind die vor dem Komma und die letzten beiden die aufgerundeten nach dem Komma. Sollten sich die Werte aus 4 Ziffern mal auf 3 oder 5 ändern, muß man halt die letzten 3 "000" abschneiden.

Auch die regulären Ausdrücke würden sich da anbieten. Um jetzt eine genaue Vorgehensweise zu erhalten, müßte man den originalen Stream sehen. Sind da jetzt Leerstellen drin oder nicht ? Wenn C400 bzw. 120 und die letzten 000 immer gleich sind, geht das auch über ein einfaches Left() und MID(String, Startpos, Endpos)

OP #7718203
Lesenswert?

Ok Danke euch gucke ich mir heute Nachmittag noch mal genauer an. Zur Zeichen folge ich weis wann ich welchen wert erwarten kann.

Ablauf ich sende: <04003300000> dann bekomme ich paar ms später dem wert für Strom. Und danach sende ich noch <02003300000> und bekomme den wert für Spannung zurück.

#7732030
Lesenswert?

Am liebsten würde ich dir ja jetzt vorschlagen, noch eine Sprache zu lernen : Reguläre Ausdrücke

Damit kann man beschreiben, welche Muster man in einem Wust von Zeichen sucht.

Und ja, C# beherrscht solche regulären Ausdrücke. Ein

1
using System.Text.RegularExpressions;

am Anfang der Quelldatei und du kannst einfacher Objekte vom Typ Regex anlegen. z.B. so :

1
private Regex rxsalat = new Regex("<(?<salat>[0-9 \t]+)>", RegexOptions.Compiled | RegexOptions.ExplicitCapture);

Damit lassen sich aus dem, was das Netzteil so ausgibt, die einzelnen Datenpakete rausfischen.

#7732054
Lesenswert?

1
using System.Collections.Concurrent;
2
using System.Text.RegularExpressions;
3

4
namespace ChinasKraftQuelle
5
{
6
    public partial class Form1 : Form
7
    {
8
        private StringBuilder answer = new StringBuilder();
9
        private Regex rxsalat = new Regex("<(?<salat>[0-9 \t]+)>", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
10
        private ConcurrentQueue<string> packets = new ConcurrentQueue<string>();
11
        
12
        private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
13
        {
14
            if (serialPort1.IsOpen)
15
            {
16
                try
17
                {
18
                    answer.Append(serialPort1.ReadExisting());
19
                }
20
                catch
21
                {
22
                    answer.Clear();
23
                }
24
                MatchCollection mm = rxinfo.Matches(answer.ToString());
25
                if (mm.Count > 0)
26
                {
27
                    foreach (Match mi in mm)
28
                    {
29
                        string inhalt = mi.Groups["salat"].Value;
30
                        if (!String.IsNullOrWhiteSpace(inhalt))
31
                        {
32
                            inhalt = inhalt.Replace('\t',' ').Replace(" ","");
33
                            packets.Enqueue(inhalt);
34
                        }
35
                    }
36
                    Match m = mm[mm.Count - 1];
37
                    answer.Remove(0, m.Index + m.Length);
38
                }
39
            }
40
            else
41
            {
42
                answer.Clear();
43
            }
44
        }
45

46
        private void SerialPort1_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
47
        {
48
            answer.Clear();
49
        }
50
    }
51
}
(Firma: Privat) #7732068
Lesenswert?

Flunder schrieb:

Am liebsten würde ich dir ja jetzt vorschlagen, noch eine Sprache zu lernen : Reguläre Ausdrücke

Jetzt mache dem TO doch keine Angst. Reguläre Ausdrücke sind nützliche Werkzeuge, die viele Sprachen als zusätzliche Lib bereitstellen. Hier kann man sich mal einlesen, bzw. sogar online ausprobieren : https://www.regexe.de/hilfe.jsp

Sogar FindStr unter cmd (DOS-Konsole) beherrscht sowas.

(Firma: Privat) #7732269
Lesenswert?


<C4000976000> <12012270000> ---------------------

Ich habe mir das nochmals angesehen. Wenn das so ankommt, wie oben, hat man auch mit den regulären Ausdrücken kaum Vorteile. Das einzige, was man sagen kann : die C400 und die 120 stehen jeweils für Ampere und Volt und die letzten 3 Nullen sind uninteressant. Ich denke, das bekommt man auch mit normalen Stringoperationen hin.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren