Forum: PC-Programmierung C# Serialport-Falsche Werte


von arash j. (arashjavan)


Lesenswert?

Guten Abend,

ich hab folgendes Problem, mit einem AVR-Controller schicke ich alle 
paar sekunden 127 Bytes an PC COM-Port, die Daten habe ich schon öfter 
kontrolliert, die werden richtig von AVR verschickt, auf der Pc-Seite 
speichere ich die Daten in einem Array. Leider werden die Daten aber 
flasch angezeigt. unten ist der code den ich zum lesen des seriellen 
Ports geschrieben hab.
1
    .
2
    .
3
    .
4
this.serialPort = new SerialPort(this.comStruct.PortName,     this.comStruct.BaudRate, this.comStruct.Parity, this.comStruct.DataBits, this.comStruct.StopBits);
5
6
this.serialPort.Encoding = Encoding.UTF8;
7
8
this.serialPort.Handshake = this.comStruct.Handshake;
9
10
this.serialPort.DataReceived += this.readDataFromSerialPort;
11
12
this.serialPort.Open();
13
14
 private void readDataFromSerialPort(object sender, SerialDataReceivedEventArgs e)
15
        {
16
            try
17
            {
18
                while (serialPort.BytesToRead > 0)
19
                {
20
                    this.arra.Add((byte)serialPort.ReadByte());
21
                }
22
                if ((MsgTyp_t)this.arra[4] == MsgTyp_t.BATCHG)
23
                {
24
                    MessageBox.Show("Akku wird geladen");
25
                }
26
                serialPort.DiscardInBuffer();
27
            }
28
            catch (Exception ex)
29
            {
30
                MessageBox.Show(ex.Message + ex.StackTrace, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
31
            }
32
        }
die WErte werden zum Teil falsch angezeigt, Baudrate ist beidseitig auf 
115200 eingestellt. liegt es eventuell an der Encoding-Funktion!! kann 
ich den ENcoding komplett ausschalten, denn ich brauc die Rohwerte des 
UCs. die werde ich dann später weiter filtern usw.

vielen Dank vorasu!

Gruss
Ps.: für alle die erst mit google-suchen-rat anfangen wollen hab genug 
gelesen und ausprobiert keinen erfolg!!!!!

von Peter II (Gast)


Lesenswert?

marti harti schrieb:
> kann
> ich den ENcoding komplett ausschalten, denn ich brauc die Rohwerte des
> UCs. die werde ich dann später weiter filtern usw.

wenn du readbyte verwendest, dann wird kein coding angewendet.

> (byte)serialPort.ReadByte()
was soll hier der cast? willst du von byte auf byte?

welchen datentype hat arra?

Hast du schon mal ein anders Programm als Refenzen verwendet, um zu 
testen ob es überhaupt ein softwarefehler bei dir ist?

von arash j. (arashjavan)


Lesenswert?

Peter II schrieb:
> marti harti schrieb:
>> kann
>> ich den ENcoding komplett ausschalten, denn ich brauc die Rohwerte des
>> UCs. die werde ich dann später weiter filtern usw.
>
> wenn du readbyte verwendest, dann wird kein coding angewendet.
>
>> (byte)serialPort.ReadByte()
> was soll hier der cast? willst du von byte auf byte?
>
> welchen datentype hat arra?
>
> Hast du schon mal ein anders Programm als Refenzen verwendet, um zu
> testen ob es überhaupt ein softwarefehler bei dir ist?

@Peter danke erst mal für die ANtwort,
1
 private List<byte> arra = new List<byte>();
ohne cast mekert der compiler:
1
Fehler  2  Die beste Übereinstimmung für die überladene System.Collections.Generic.List<byte>.Add(byte)-Methode hat einige ungültige Argumente.

ich habe es mit tera term ausprobiert der kann aber kein roh-byte werte 
anzeigen nur ascii!!

von Karl H. (kbuchegg)


Lesenswert?

marti harti schrieb:

> ich habe es mit tera term ausprobiert der kann aber kein roh-byte werte
> anzeigen nur ascii!!


Dann nimm HTerm

von Karl H. (kbuchegg)


Lesenswert?

1
  ....
2
                while (serialPort.BytesToRead > 0)
3
                {
4
                    this.arra.Add((byte)serialPort.ReadByte());
5
                }
6
                if ((MsgTyp_t)this.arra[4] == MsgTyp_t.BATCHG)
7
 ....

Muss schon sagen ... du traust dich was.
Wer oder was garantiert dir, dass du in der while Schleife auch 
tatsächlich alle 127 Bytes bekommst? Übertragung auf der Seriellen 
dauert viel länger als dein PC rechnen kann. D.h. dein serialPort wird 
relativ schnell mitteilen, dass keine Bytes mehr vorliegen. Aber nicht, 
weil bereits alle 127 Bytes bereits abgeholt wurden sondern weil sie 
noch gar nicht übertragen wurden!

1
  ....
2
        serialPort.DiscardInBuffer();
3
  ....
und spätestens danach hast du ein gewaltiges Problem. Du weißt nicht 
wieviele Zeichen du hier verwirfst. D.h. ab hier hast du keinen blassen 
Schimmer mehr, was das nächste eintreffende Byte aussagt. Ist das ein 
Byte, welche noch zu den Daten gehört? Ist es der Beginn der nächsten 
127 Byte Nachricht?


Protokolle, die einzig und alleine auf dem Wissen aufbauen, dass eine 
Nachricht aus genau so und so vielen Bytes besteht und ansonsten 
keinerlei Rahmenbedingungen definieren (wie zb das erste Byte ist 
eindeutig immer 0xFE weil 0xFE in den Daten nicht vorkommen kann) haben 
ein enormes Problem: Wenn die Synchronisierung erst mal verloren 
gegangen ist, dann ist es praktisch unmöglich sie wieder herzustellen. 
Mit dem DiscardInBuffer wirfst du die Synchronisierung aber mutwillig 
weg.

von Udo S. (urschmitt)


Lesenswert?

Der cast wird benötigt da readByte einen int zurückliefert. Warum ist 
mir nicht ganz klar, denn anders als im klassischen C hibt es meines 
Wissens keine -1 als Fehlerrückgabe. Bei fehlern wird eine Exception 
geworfen.

Wie wird der AVR betrieben? mit dem internen Oszillator, mit einem 
Quarz?

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Protokolle, die einzig und alleine auf dem Wissen aufbauen, dass eine
> Nachricht aus genau so und so vielen Bytes besteht und ansonsten
> keinerlei Rahmenbedingungen definieren (wie zb das erste Byte ist
> eindeutig immer 0xFE weil 0xFE in den Daten nicht vorkommen kann) haben
> ein enormes Problem: Wenn die Synchronisierung erst mal verloren
> gegangen ist, dann ist es praktisch unmöglich sie wieder herzustellen.
> Mit dem DiscardInBuffer wirfst du die Synchronisierung aber mutwillig
> weg.

Soweit war ich noch nicht. Das Zusammenspiel aus
while (serialPort.BytesToRead > 0)
und
serialPort.DiscardInBuffer();
dürften des Rätsels Lösung sein.
Die Schleife kann ein paar Bytes lesen bis sie schneller ist als die 
UART Übertragung, die werden ausgewertet und dann kommt ein 
discardBuffer, dann werden wieder mal ein paar Bytes mitten aus dem 
Datenblock ausgewertet, ...
Kann niemals funktionieren.
Sychronisieren wie Karl Heinz gesagt hat über ein Start Byte oder eine 
Folge von Bytes die so nie vorkommen kann, oder wenn das nicht geht über 
einen Timeout-read der die Lücke zwischen 2 Datenpaketen erkennen kann. 
Das ist aber nicht schön.
Wenn genügend Zeit vorhanden ist könnte man auch die Binärdaten in Hex 
wandeln und übertragen. Dann kann man ein Sonderzeichen als Start/Stopp 
etc nehmen und es hat den Charme daß es direkt lesbar ist.

Nachtrag: Ein Protokoll, das am Anfang die Länge das Datenpakets und am 
Ende noch eine Prüfsumme sendet würde das Leben dqann nochmal einfacher 
und sicherer machen.

von Peter II (Gast)


Lesenswert?

oder einfach erstmal über ReadsByte ohne event funktion arbeiten und die 
Daten einlesen.

while( true ) {
  this.arra.Add((byte)serialPort.ReadByte());

  //auswerten und break wenn das richtig oder genug in arra drin steht
}

von arash j. (arashjavan)


Lesenswert?

Udo Schmitt schrieb:
> Der cast wird benötigt da readByte einen int zurückliefert. Warum ist
> mir nicht ganz klar, denn anders als im klassischen C hibt es meines
> Wissens keine -1 als Fehlerrückgabe. Bei fehlern wird eine Exception
> geworfen.
>
> Wie wird der AVR betrieben? mit dem internen Oszillator, mit einem
> Quarz?

ja, mit interen RC-Osci. an uc liegt es nicht ich kann die Daten durch 
printf und tera term ausgeben und die stimmen auch alle. es muss irgend 
etwas mit meinem c# programm zu tun haben.

ich habe es mit serial port monitor ausprobiert, der zeigt auch genau 
die selben werte wie mein eigenes programm ??????

sobald ich die Daten durch pintf bzw. acii codes ausgebe stimmen die!!!

von Karl H. (kbuchegg)


Lesenswert?

Udo Schmitt schrieb:

> Die Schleife kann ein paar Bytes lesen bis sie schneller ist als die
> UART Übertragung,

Ich würd sogar sagen:
Da das ganze auf einen Event triggert, wird genau 1 einziges Byte von 
der UART geholt ehe die while Schleife abbricht.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> Der cast wird benötigt da readByte einen int zurückliefert.
> Warum ist mir nicht ganz klar
Warum steht doch in der API:
1
Rückgabewert
2
Typ: System.Int32
3
Das Byte, das in Int32 umgewandelt wurde, oder -1, 
4
wenn das Ende des Streams gelesen wurde.

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> Warum steht doch in der API:Rückgabewert
> Typ: System.Int32
> Das Byte, das in Int32 umgewandelt wurde, oder -1,
> wenn das Ende des Streams gelesen wurde.

Superklasse. Ich hatte gegoogelt und den ersten Treffer in der MSDN 
gefunden:
http://msdn.microsoft.com/de-de/library/system.io.ports.serialport.readbyte%28v=vs.80%29.aspx
Da steht:
"Rückgabewert
Das Byte, das gelesen wurde.  "
und sonst NIX!
Scheiß Doku! Früher war MSDN mal klasse.

von Udo S. (urschmitt)


Lesenswert?

marti harti schrieb:
> ja, mit interen RC-Osci.

Sehr suboptimal, das kann funktionieren, und wenn es 4 Grad wärmer ist 
dann nicht mehr. Der interne Oszillator ist nicht exakt genug, da kann 
es sein daß der Zeitfehler über die 10 Bit zu groß wird.

von arash j. (arashjavan)


Lesenswert?

Danke erstmal an alle!

Udo Schmitt schrieb:
> marti harti schrieb:
>> ja, mit interen RC-Osci.
>
> Sehr suboptimal, das kann funktionieren, und wenn es 4 Grad wärmer ist
> dann nicht mehr. Der interne Oszillator ist nicht exakt genug, da kann
> es sein daß der Zeitfehler über die 10 Bit zu groß wird.
auf der Platine hab ich einen externen oszi, werde ich den Takt-Quelle 
umändern.

jetzt abgesehen von den ganzen oben geschriebenen code mit 
while-schleife,
welche möglichkeiten gibts in c# einen Roh-Byte aus Seriellen Ports zu 
lesen.
denn der arra-array wird wirklich tatsächlich beim ersten empfang mi 127 
byte gefüllt. aber nur DIE WERTE stimmen nicht.

ich werd es morgen nochmal mit paar anderen methoden probieren.
und schreib es noch mal hier.

von Peter II (Gast)


Lesenswert?

mach mal dein array als unsigned byte. Ich habe jetzt nicht nachgelesen 
aber eventuell ist ja bei c# ein byte signed.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> Ich hatte gegoogelt und den ersten Treffer in der
> MSDN gefunden:
C# SerialPort hat mir das geliefert.

http://msdn.microsoft.com/de-de/library/system.io.ports.serialport.readbyte.aspx

ansonsten ist das Verhalten in Java ebenso, irgendwie muss man ja das 
Dateiende feststellen auch wenn es sicher anders ginge als über den 
Rückgabewert. Hat aber den Vorteil, dass z.B. beim lesen über 
Buffer/Arrays die selbe Semantik gilt.

Hatten wir nicht letztens schonmal so einen Fall mit EventLesen + 
Wegwerfen von Bytes gehabt??

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> ansonsten ist das Verhalten in Java ebenso,
Deshalb hab ichs ja geschrieben, weil mich das etwas verwundert hat. 
Auch in K&R C wurde die -1 schon als EOF genommen.

von Udo S. (urschmitt)


Lesenswert?

marti harti schrieb:
> jetzt abgesehen von den ganzen oben geschriebenen code mit
> while-schleife,
> welche möglichkeiten gibts in c# einen Roh-Byte aus Seriellen Ports zu
> lesen.

Die Methode readByte() stimmt schon.
Du solltest aber wie von Karl Heinz und mir beschrieben auf jeden Fall 
ein sauberes Protokoll aufbauen, sonst weisst du nie ob du sauber 
synchron bist.

von arash j. (arashjavan)


Lesenswert?

Udo Schmitt schrieb:
> marti harti schrieb:
>> jetzt abgesehen von den ganzen oben geschriebenen code mit
>> while-schleife,
>> welche möglichkeiten gibts in c# einen Roh-Byte aus Seriellen Ports zu
>> lesen.
>
> Die Methode readByte() stimmt schon.
> Du solltest aber wie von Karl Heinz und mir beschrieben auf jeden Fall
> ein sauberes Protokoll aufbauen, sonst weisst du nie ob du sauber
> synchron bist.

den Protkoll werde ich noch mal überarbeiten.

irgendwie hab ich das gefühl das konnte tatsächlich etwas mit vorzeichen 
zu tun haben, leider bin ich jetzt nicht mehr am System, aber ich werd 
es bis morgen noch mal ausprobieren und posten. den uc werde ich auch 
noch mal genauer unter die luppe nehemn was er liefert.

von Karl H. (kbuchegg)


Lesenswert?

marti harti schrieb:

> denn der arra-array wird wirklich tatsächlich beim ersten empfang mi 127
> byte gefüllt.

Mit Verlaub: Aber das glaube ich dir nicht!

Mach da mal einen Zähler rein
1
private void readDataFromSerialPort(object sender, SerialDataReceivedEventArgs e)
2
        {
3
            try
4
            {
5
                byteCount = 0;
6
                while (serialPort.BytesToRead > 0)
7
                {
8
                    this.arra.Add((byte)serialPort.ReadByte());
9
                    byteCount++;
10
                }
und wenn der hinten nach 127 ist, dann fress ich einen Besen.

Wichtig: Nicht im Debugger. IM Debugger gibst du beim Einzelschritt 
genügend Zeit, dass die 127 Bytes über die Serielle flutschen. Aber wenn 
dein Programm eigenständig full speed läuft nicht mehr. Da wirst du 
sehen, dass der Zähler auf 1 oder 2 steht. Wie willst du daher
1
          if ((MsgTyp_t)this.arra[4] == MsgTyp_t.BATCHG)
hier das 5. Byte auswerten, wenn du es noch gar nicht hast?

von arash j. (arashjavan)


Lesenswert?

Karl Heinz Buchegger schrieb:
> marti harti schrieb:
>
>> denn der arra-array wird wirklich tatsächlich beim ersten empfang mi 127
>> byte gefüllt.
>
> Mit Verlaub: Aber das glaube ich dir nicht!
>
> Mach da mal einen Zähler rein
>
>
1
> private void readDataFromSerialPort(object sender,
2
> SerialDataReceivedEventArgs e)
3
>         {
4
>             try
5
>             {
6
>                 byteCount = 0;
7
>                 while (serialPort.BytesToRead > 0)
8
>                 {
9
>                     this.arra.Add((byte)serialPort.ReadByte());
10
>                     byteCount++;
11
>                 }
12
> 
13
>
> und wenn der hinten nach 127 ist, dann fress ich einen Besen.
>
dann werd ich mal erst mal einen halben Besen für dich suchen ;)
das mit dme zählen hab ich probiert beim ersten durchgang bekomme ich 
immer 127 Bytes dann natürlich geht mit synch alles verloren.
aber mir geht es erst mal darum richtige werte zu empfangen.

byte ist im c# vorzeichnlos
http://msdn.microsoft.com/de-de/library/5bdb6693%28v=vs.80%29.aspx

deswegen wird wohl nicht an byte legen.
werd es heute abend noch mal probieren und posten.

von arash j. (arashjavan)


Lesenswert?

Hallo,

also leute ich hab mein Fehler gefunden, es lag an der höhen Baudrate, 
anscheinend war der interne RC-osci. ungenau für höhe Baudraten. jetzt 
bekomme ich Daten mit richtigen Werten. zu dem habe ich auch den Externe 
Osci aktivert.

Danke nochmal für die Anregungen und Tipps.

von Udo S. (urschmitt)


Lesenswert?

marti harti schrieb:
> also leute ich hab mein Fehler gefunden, es lag an der höhen Baudrate,
> anscheinend war der interne RC-osci. ungenau für höhe Baudraten.

Und was hatte ich gestern schon gefragt?
Aber du hast behauptet:

marti harti schrieb:
> ja, mit interen RC-Osci. an uc liegt es nicht ich kann die Daten durch
> printf und tera term ausgeben und die stimmen auch alle. es muss irgend
> etwas mit meinem c# programm zu tun haben.
>
> ich habe es mit serial port monitor ausprobiert, der zeigt auch genau
> die selben werte wie mein eigenes programm ??????
>
> sobald ich die Daten durch pintf bzw. acii codes ausgebe stimmen die!!!


Klar daran lag es nicht.
Genauso wie es jetzt keine Probleme mit dem Empfang von 127 Bytes mit 
deiner Routine gibt.
Bastel mal schön so weiter dann wird dir nicht langweilig. Nächste Woche 
hast du dann selbst 'entdeckt' dass deine Empfangsfunktion so nicht 
funktioniert.

von arash j. (arashjavan)


Lesenswert?

Udo Schmitt schrieb:
> Klar daran lag es nicht.
> Genauso wie es jetzt keine Probleme mit dem Empfang von 127 Bytes mit
> deiner Routine gibt.
> Bastel mal schön so weiter dann wird dir nicht langweilig. Nächste Woche
> hast du dann selbst 'entdeckt' dass deine Empfangsfunktion so nicht
> funktioniert.

Ja, mit dme Empfang hat es nicht so geklappt, wie ich es mir vorstellte. 
ich habe es mit Readexisting probiert, bringt aber leider auch nicht 
viel, da Daten nur im Ascii-Stringform kodiert vorliegn.

ich habe folgendes vor, aber sagt mir falls ich mich irre,
die Daten des Seriellenports werd ich event-gestuert in einem Array 
mittels Readbyte() speichern und wenn die Daten in dem Array eine 
gewisse Anzahl erreicht haben, kompletten Array nach besonderen 
Merkmalen für Anfang eines neuen Datenpakets suchen, und dann 
dementsprechend die benötigte anzahl der Daten aus dem Array entfernen 
und weiterbearbeiten.

ich bin gerade dabei dies umzusetzten, aber falls ihr einen besseren 
vorschlag habt oder meint es gibt eine Methode die mir das ganze 
ersparrt, dann bin ich ganz ohr, herdamit.

von Udo S. (urschmitt)


Lesenswert?

Wie oben schon gesagt, überlege dir ein Protokoll, das das leistet.
Sind die Daten binär, können alle Werte vorkommen?
Dann ändere sie so um daß du bestimmte Zeichen als Steuerzeihen zur 
verfügung hast.
Oder am einfachsten aber verschwenderischsten. Codiere jedes Byte als 2 
Zeichen Hex Wert. dann hast du alle Zeichen ausser 0-9 und a-f als 
Kontrollzeichen, und das Ganze ist lesbar in einem Terminal (immer gut 
fürs debugging).
Man kann z.B. auch für Zeichen 00 -0f einühren, daß sie eine Meta 
Zeichen als Prefix erhalten z.b. 0f. dann wäre 00 -> 0f00 01 -> 0f01, 
... 0f -> 0f0f
Damit hättest du die Zeichen 00 -0e als Steuerzeichen frei.
Einfaches nicht besonders schönes Beispiel.
etc. pp.
Dann noch so Dinge wie eine Längenangabe zu Beginn jedes Datenblocks, 
eine Prüfsumme (CRC oder einfach Quersumme) am Ende ....
so wird ein richtiges fehlertolerantes Protokoll draus

von arash j. (arashjavan)


Lesenswert?

Udo Schmitt schrieb:
> Dann noch so Dinge wie eine Längenangabe zu Beginn jedes Datenblocks,
> eine Prüfsumme (CRC oder einfach Quersumme) am Ende ....
> so wird ein richtiges fehlertolerantes Protokoll draus

ja genau das hab ich auch vor. mein protokoll hat folgender aufbau:
1
-----------------------------------------------------
2
paket- | Network- | Massege |adressenfelder | Daten |
3
länge  | id       | id      |  & seuquenznr |       |
dabei sind network-id, massege-id. und host-adresse immer konstant.
werde es mal nach networkid suchen dann die anderen beiden wenn alle 
drei bedingungen erfüllt sind dann soviel wie paketlänge vom array 
entfernen und bearbeiten.

von Kan a. (Firma: Basta) (kanasta)


Lesenswert?

marti harti schrieb:
> CRC oder einfach Quersumme

naja da gibts schon Unterschiede, ich sage nur: 
Aliasing-Wahrscheinlichkeit.
Irgendwie erkenne ich die Prüfsumme in marihari's Paketstruktur nicht.

von Peter II (Gast)


Lesenswert?

Wenn wirklich alle werte vorkommen, dann gibt es immer noch die 
Möglichkeit einen Wert zu "Quoten". Wenn du z.b. die 0x00 als start 
haben willst, und in den daten aber eine 0x00 vorkommen dann muss im µC 
bei senden einer 0 eine 2.0 vorrangestellt werden. Beim empfänger gilt 
dann eine einzelnen 0 als start und eine eine doppelete 0 als daten.

Das wird bei hdlc auch so gemacht, ist also gar nicht so unüblich.

von Udo S. (urschmitt)


Lesenswert?

Kan asta schrieb:
> naja da gibts schon Unterschiede, ich sage nur:
> Aliasing-Wahrscheinlichkeit.

Klar.
Wenn du sicher gehen willst packst du einen MD5 hash dahinter :-)

mata hari, was dir fehlt ist die eindeutige Startsequenz, damit du 
weisst wann genau ein Datenblock beginnt.

von arash j. (arashjavan)


Lesenswert?

sorry hab ich vergessen natürlich kommt am ende des Paketts noch ein 
16-CRC.

von Kan a. (Firma: Basta) (kanasta)


Lesenswert?

marti harti schrieb:
> am ende des Paketts

sorry, habe nicht den ganzen Thread mitgelesen, aber am Anfang beim Rest 
des Headers würds ja auch nicht schlecht positioniert sein, oder? Warum 
als einzigstes Meta-Feld am Ende?

von arash j. (arashjavan)


Lesenswert?

Kan asta schrieb:
> marti harti schrieb:
>> am ende des Paketts
>
> sorry, habe nicht den ganzen Thread mitgelesen, aber am Anfang beim Rest
> des Headers würds ja auch nicht schlecht positioniert sein, oder? Warum
> als einzigstes Meta-Feld am Ende?

nein, position ist bliebig, aber ich habes halt so aufgebaut. eskonnte 
genau sogut nach vorne geschoben werden.

von arash j. (arashjavan)


Lesenswert?

ok leute, ich habe mit nach drei bit muster suchen auspobiert es funkt, 
aber es ist mir sehr unsicher, dann die wahrscheinlichkeit, dass auch im 
Daten Bereich auch diese Drei Byte-Muster vorkommen ist sehr gross.

>@Peter II
>Wenn wirklich alle werte vorkommen, dann gibt es immer noch die
>Möglichkeit einen Wert zu "Quoten". Wenn du z.b. die 0x00 als start
>haben willst, und in den daten aber eine 0x00 vorkommen dann muss im µC
>bei senden einer 0 eine 2.0 vorrangestellt werden. Beim empfänger gilt
>dann eine einzelnen 0 als start und eine eine doppelete 0 als daten.

hdlc  gefällt mir ganz gut werde versuchen etwas ähnliches umzusetzten.

von bluppdidupp (Gast)


Lesenswert?

Naja, selbst wenn das Synchronisations-Muster mal im Paket vorkommt muss 
dann ja auch noch zufällig der CRC stimmen

von arash j. (arashjavan)


Lesenswert?

bluppdidupp schrieb:
> Naja, selbst wenn das Synchronisations-Muster mal im Paket vorkommt muss
> dann ja auch noch zufällig der CRC stimmen

man konnte natürlich das ganze noch mit einem FEC erweitern um auf die 
nummer sicher zu gehen aber für meine Anwendung reicht erstmal CRC und 
noch ein Synchron.-Verfahren.

von arash j. (arashjavan)


Angehängte Dateien:

Lesenswert?

Peter II schrieb:
> Wenn wirklich alle werte vorkommen, dann gibt es immer noch die
> Möglichkeit einen Wert zu "Quoten". Wenn du z.b. die 0x00 als start
> haben willst, und in den daten aber eine 0x00 vorkommen dann muss im µC
> bei senden einer 0 eine 2.0 vorrangestellt werden. Beim empfänger gilt
> dann eine einzelnen 0 als start und eine eine doppelete 0 als daten.
>
> Das wird bei hdlc auch so gemacht, ist also gar nicht so unüblich.

Danke erst mal an alle Beteiligen.

hier noch mal darstellung der aktuellen Situation:

- es werden Sensor Daten vom uC zum Pc übertragen und visualisiert.
- es können alle Werte vorkommen.
- Die übertragung sollte schnll gehen--> also wenn möglich mit wenig 
overhead und extra Bytes.

- Die Daten sin im uC in einem uint8-Bereiten Buffer gespeichert und 
werden genau so durch URAT übertragen --> 8N1 .

- auf dr Pc-Seite werden die Daten wieder in einem 8 bit Array 
gespeichert und weiter bearbeitet.

Lösungswege:

1) jedes Byte in 2 Teilen splitten --> zu viel extraBytes.
2) als HEX übertragen auch ziemlich lang.
3) Bitsopfen, gefällt mir am besten da ich kein etra bytes übertragen 
muss.
aber nehmen wir mal an mein Flag würde 01111110 lauten und ich die Daten 
des Array die Reihe nach übertragen will.

in Array werd ich erstmal nach allen vorkommenden 5er 1-Folgen suchen 
und dann ein 0 dazwischen stopfen.
1
       ----------
2
 Flag | 01111110 |
3
 Daten| 00111111 |   nach BitStuffing     00111110  (1) 
4
      |   .      |  -------------------> 
5
          . 
6
          .
ich hoffe ich konnte es oben einigermassen klar beschreiben.
wenn ich die bitfolge 00111110 senden will, wird durch die bitstuffing
nach der fünften 1 ein 0 hinzugefügt. Somit geht ja die letzte 1 
verloren, oder? Denn 9 bits sende ich ja nicht.

von Peter II (Gast)


Lesenswert?

marti harti schrieb:
> . Somit geht ja die letzte 1
> verloren, oder? Denn 9 bits sende ich ja nicht.

aus den grund solltest du das ja auch nichts mit bits machen sonder mit 
bytes. HDLC ist eine "bit" übertragung. Bei dir würde sich alles bits 
und damit die zusammenstellung der bytes verschieben. Was für die µC 
viel zu aufwendig ist.

Wähle einfach ein byte-wert aus der sehr selten übertragen wird, diesen 
wählst du als SYN wert aus. Wenn er jetzt in den Daten vorkommen dann 
sendest du ihn 2 mal.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.