Forum: Mikrocontroller und Digitale Elektronik Datenpakete mit ATmega88 verarbeiten


von Patrick R. (pat711)


Lesenswert?

Guten Tag zusammen,

ich bin derzeit damit beschäftigt Datenpakete eines externen Geräts an 
meinem ATmega88 auszulesen.
Diese Datenpakete haben keine einheitliche Länge, Da die Daten 
unterschiedlich lang sind. Daher befinden sich in diesem Datenpaket zwei 
Bytes die die Länge der Daten angeben.
Nun wollte ich fragen ob es irgendwelche Tricks oder so gibt um die 
Pakete möglichst einfach zu bearbeiten und temporär in Variablen zu 
speichern. Eine Möglichkeit wäre nun bis zu den beiden Bytes in ein 
neues Array auszulesen und abzuspeichern. Nach empfangen dieser beiden 
Byte die Länge des Paketes bestimmen und einen Endwert festzulegen. Bei 
erreichen des Endwertes dann in das Nächste Array (beispielsweise eines 
Mehrdimensionalen Arrays wechseln) und in diesem wieder von vorne zu 
beginnen.
Die Datenpakete werden am USART empfangen.

Aufbau der Datenpakete:
Start Delimiter 1 Byte | Packet Type identification 1 Byte | Op code 1 
Byte | Data length 2 Byte | Checksum 1 Byte | Packet Data X Byte | End 
delimiter 1Byte

Beispiel:

Array[0][0] Zeichen vom USART einlesen und speichern
Array[0][1] Zeichen vom USART einlesen und speichern
...
Array[0][5] Zeichen vom USART einlesen und speichern
            Endwert festlegen aus Byte 4 und 5
...
Array[0][Endwert] Zeichen vom USART einlesen und speichern
                  zum nächsten Array wechseln

Array[1][0] Zeichen vom USART einlesen und speichern
Array[1][1] Zeichen vom USART einlesen und speichern
...
Array[1][5] Zeichen vom USART einlesen und speichern
            Endwert festlegen aus Byte 4 und 5
...
Array[1][Endwert] Zeichen vom USART einlesen und speichern
                  zum nächsten Array wechseln

...


MfG Pat711

von Antwort (Gast)


Lesenswert?

Am einfachsten wird es sein die Daten beim Empfang in einen Ringpuffer 
zu speichern. Dabei kümmerst du dich nicht darum was du da eigentlich 
empfangen hast, sondern schreibst es stumpf in den Ringpuffer rein.
Das schreiben in den Ringpuffer läuft im Empfangsinterrupt der UART 
Schnittstele (Interrupt wenn ein Byte empfangen wurde).

Den Ringbuffer machst du dann bsw. 256Byte lang (oder eben so lang das 
du zumindest mal 4-5 deiner Packete abspeichern kanst). So brauchst du 
den Bytepointer einfach nur immer zu inkrementieren und fängst durch den 
überlauf wieder bei 0 an.

Nun hast du das Datenpacket im Ringpuffer stehen (oder auch schon 
mehrere) und über eine extra Funktion suchst du nun von deiner letzten 
Lese-position (zu Beginn wird das 0 sein) den ersten auftauchenden 
"Start Delimiter". Nun schreibst du jedes fogende Byte in einen 
zwischenpuffer bis du zum "End delimiter" gelangst (dabei kontinuierlich 
prüfen ob der Lese pointer nicht über den Schreibe-pointer hinausläuft).

Nun hast du in deinem Zwischenpuffer das Packet ohne Start/End delimiter 
stehen. Du kannst nun je nach Packet identification und Op-code ein 
struct erzeugen in dem du dann die Daten aus dem Zwischenpuffer 
abspeicherst. (neu erzeugen der Checksum und vergleich mit der alten 
natürlich nicht vergessen).

Um das ganze etwas leichter erweiterbar zu machen arbeite ich dabei 
gerne mit Unions. Dazu definiere ich mir für jedes mögliche ankommende 
datenpacket ein eigenes struct. All diese Structs fasse ich in einem 
Union zusammen (bei definition der structs muss ggf. #pragma pack(1) 
verwendet werden). Das erste byte in jedem struct enthält dabei einen 
identificationscode um festzustellen was da eigentlich drinnen steht. 
Bei dir wäre das dann wohl "Packet type identification" oder "Op Code". 
Nun übergibst du an jede Funktion nur noch Pointer auf die Unions, liest 
das erste Byte zur Identifikation aus und kannst anhand dessen 
feststellen was zu amchen ist. So lässt sich der Code sehr leicht für 
weitere mögliche Datenpackete erweitern.

von Patrick R. (pat711)


Lesenswert?

Danke, deine Antwort ist schonmal sehr hilfreich ich werde mir nun mal 
was du mit den union's und struct's meinst, welche mir unbekannt sind 
;-). (wohl ne Art Maske, schätz ich mal)

Aber das mit dem Ringpuffer ist eine tolle Idee ^^ allerdings könnte ich 
dann Probleme mit meinem Speicher bekommen. Vielleicht muss ich dann den 
EEPROM zu hilfe nehmen.

MfG Pat711

von Sascha W. (sascha_w)


Lesenswert?

Patrick R. schrieb:
> Aber das mit dem Ringpuffer ist eine tolle Idee ^^ allerdings könnte ich
> dann Probleme mit meinem Speicher bekommen.
weil? nicht genug Platz?

> Vielleicht muss ich dann den
> EEPROM zu hilfe nehmen.
keine gute Idee, der lässt sich für den Anwendungsfall nicht oft genug 
überschreiben

mal noch was zur Kärung:
* wie groß können die Packete maximal sein
* wie groß ist die minnimale Pause zwischen zwei Packeten
* ist der 'End delimiter' einmalig, oder kann der Wert dieses Bytes auch 
im Rest des Packets enthalten sein

Sascha

von Antwort (Gast)


Lesenswert?

Das mit structs und unions ist wie folgt gemeint:
1
//Opcode Typedefs
2
#define DEFINE_DATA_1   0
3
#define DEFINE_DATA_2   1
4
5
//Auf ARM 7 macht er aus uint8_t sonst uint16_t weil er da besser/schneller zugreifen kann. Kostet aber mehr Platz. Daher das pragma welches dies verhindert
6
7
#pragma pack(1) 
8
typedef struct{
9
uint8_t u8OpCode; //enthält Zahl zur Identifikation des structs
10
uint8_t u8MyData1;
11
uint8_t u8MyData2;
12
} tdsMY_DATA_1;
13
14
#pragma pack(1)
15
typedef struct{
16
uint8_t u8OpCode; //enthält Zahl zur Identifikation des structs
17
uint16_t u16MyData1;
18
char[5] cMyWord;
19
} tdsMY_DATA_2
20
21
typedef union{
22
tdsMY_DATA_1 tdsMyData1;
23
tdsMY_DATA_2 tdsMyData2;
24
} tduMY_RECEIVE_DATA;

Nach füllen des Zwischenspeichers könnte man nun wie folgt vorgehen:
1
tduMY_RECEIVE_DATA gtduGetReceiveData(){
2
uint8_t u8Buffer[20];
3
tduMY_RECEIVE_DATA tduReceivedData;
4
5
...    //erstmal zwischenspeicher füllen. Alles ausser delimiter enthalten
6
7
switch(u8Buffer[1]){ //Identification anhand OpCode
8
9
case DEFINE_DATA_1:
10
     //union befüllen
11
     (tdsMY_DATA_1)tduReceivedData.u8OpCode = DEFINE_DATA_1;
12
     (tdsMY_DATA_1)tduReceivedData.u8MyData1 = u8Buffer[2];
13
     (tdsMY_DATA_1)tduReceivedData.u8OMyData2 = u8Buffer[3];
14
     break;
15
16
case DEFINE_DATA_2:
17
     //befüllen
18
     break;
19
}
20
21
return tduReceiveData;
22
}


In einer anderen Funktion könnte die Auswertung wie folgt aussehen:
1
void gvMyFunction(tduMY_RECEIVE_DATA* ptduMyReceiveData){
2
3
//OpCode auslesen
4
switch(*ptduMyReceiveData){
5
6
case DEFINE_DATA_1:
7
     //tue etwas
8
     break;
9
10
case DEFINE_DATA_2:
11
     //tue etwas
12
     break;
13
}
14
}

Wichtig ist das die Zahl zur Identifikation des structs immer an erster 
stelle steht.

von Patrick R. (pat711)


Lesenswert?

@Sascha:
Das mit dem Platz sollte schon irgendwie zu machen sein der ATmega88 hat 
ja immerhin 1kByte Speicher.

Und noch zu deinen Fragen:
* Die Größe der Pakete ist im Datenblatt mit einem Maximum der 
Datenlänge von 333 Byte also 7Byte + 333Datenbyte.
Dies ist allerdings nur voll ausgenutzt wenn der Controller Daten an den 
Chip sendet. Im umgekehrten Fall habe ich bisher Pakete mit einer 
maximalen Länge von 16 Byte empfangen. Viel längere werden nicht 
gesendet werden.


* Diese Pause beträgt laut Logicanalyser 0,1sec also 100ms da der 
Datenfluss sich aber mit RTS und CTS anhalten lassen sollte, sollte dies 
kein Problem darstellen.

* Im Datenteil des Paketes kann der End delimiter auch vorkommen

MfG Pat711

von Sascha W. (sascha_w)


Lesenswert?

Patrick R. schrieb:
> @Sascha:
> Das mit dem Platz sollte schon irgendwie zu machen sein der ATmega88 hat
> ja immerhin 1kByte Speicher.
soviel ist das nicht

> Und noch zu deinen Fragen:
> * Die Größe der Pakete ist im Datenblatt mit einem Maximum der
> Datenlänge von 333 Byte also 7Byte + 333Datenbyte.
dann könnte man mit der Variante von 'Antwort' höchstens 1 Paket puffern

> Dies ist allerdings nur voll ausgenutzt wenn der Controller Daten an den
> Chip sendet. Im umgekehrten Fall habe ich bisher Pakete mit einer
> maximalen Länge von 16 Byte empfangen. Viel längere werden nicht
> gesendet werden.
du empfängst also blos?

>
> * Diese Pause beträgt laut Logicanalyser 0,1sec also 100ms da der
> Datenfluss sich aber mit RTS und CTS anhalten lassen sollte, sollte dies
> kein Problem darstellen.
liest du nur mit?

die 100ms sollten locker ausreichen um das empfange Paket noch im 
Empfangspuffer zu verarbeiten.
mein Vorschlag:
*eingehende Daten Byteweise in einen Puffer ablegen (Array), dabei 
Anzahl der Bytes mitzählen und Obergrenze überwachen (Obergrenze wird 
erst mal auf die Größe des Arrays festgelegt)
*nach Empfang von Byte 5 (2.Byte der Länge) Paketlänge berechnen und 
Obergrenze neu festlegen
*bei Erreichen von Obergrenze Flag setzten, das von Main aus das Paket 
verarbeitet werden kann, wenn dabei Obergrenze=Arraygröße dann ist ein 
Fehler aufgetreten (Daten haben nicht in das Array gepasst)

Sascha

von Patrick R. (pat711)


Lesenswert?

Tag zusammen,

klar so viel ist 1kB nun auch wieder nicht aber es sollte reichen.

Und es wird außerdem auch gesendet, aber das ist ja wieder ein anderer 
Part.
Und das mit den 100ms ist eben nicht so sicher, da der Controller 
nebenher auch noch messwerte aufnehmen muss.

Die Vorgehensweise die du mir da beschreibst ist ja praktisch die aus 
meinem ersten Post ein wenig erweitert, oder?
`
MfG Pat711

von Sascha W. (sascha_w)


Lesenswert?

Patrick R. schrieb:
> Die Vorgehensweise die du mir da beschreibst ist ja praktisch die aus
> meinem ersten Post ein wenig erweitert, oder?
nicht ganz, in deiner Variante sieht es je eher so aus als ob du in dem 
mehrdimensionalen Array alle Datenpakete speichern willst.
Nach meinem Vorschlag wird im Array immer nur ein Paket gespeichert, 
und nach dessen vollständigem Empfang werden nur die Werte die du 
brauchst in separaten Variablen abgelegt.

Sascha

von Patrick R. (pat711)


Lesenswert?

1
#include <avr/io.h>
2
#include <arf32.h>
3
#include <lcd-routines.h>
4
#include <stdlib.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h> 
7
8
#define PAKET   25    // Maximale Paketlänge festlegen
9
#define CTS    PD7    // CTS - Pin des BT - Moduls (in)
10
#define RTS    PD6    // RTS - Pin des BT - Moduls (out)
11
12
uint8_t buffer = 0;    // Puffervariable in der das empfangene Zeichen abgelegt wird
13
uint8_t daten[PAKET];  // Variable, in der die Empfangenen Pakete abgelegt werden
14
uint8_t count0 = 0;    // Zähler zur erstellung der Pakete
15
uint8_t count1 = 0;
16
uint8_t zeile = 1;    // zum festlegend der LCD - Zeile
17
uint8_t paket_ende = 0; // Paketende - Flag um zu signalisieren, dass das Paket vollständig empfangen wurde
18
uint8_t paket_laenge = PAKET;
19
uint8_t lcd_zeichen = 0;
20
uint8_t kont = 0;
21
22
ISR (USART_RX_vect)
23
{
24
  buffer = UDR0;        // Empfangenes Zeichen in Puffer einlesen
25
  daten[count0] = buffer;    // Empfangenes Zeichen dem Paket hinzufügen
26
  count0 ++;
27
  if (count0 == (paket_laenge + 1))
28
  {
29
    paket_ende = 1;      // Paket wurde emfangen
30
    paket_laenge = PAKET;
31
    count0 = 0;
32
  }
33
  if (count0 == 5)        // Wenn beide Datenlänge Bits empfangen wurden
34
  {
35
    paket_laenge = (daten[4] * 256) + daten[3] + 7;
36
    lcd_zeichen = paket_laenge;
37
    
38
    lcd_clear();
39
    char Puffer[20]; // in diesem {} lokal
40
    itoa(daten[paket_laenge], Puffer, 10); 
41
    set_cursor(0,1);
42
    lcd_string(Puffer);
43
    
44
    itoa(daten[3], Puffer, 10); 
45
    set_cursor(5,1);
46
    lcd_string(Puffer);
47
    
48
    itoa(daten[4], Puffer, 10); 
49
    set_cursor(10,1);
50
    lcd_string(Puffer);  
51
  }
52
}
53
54
int main(void)
55
{
56
  _delay_ms(100);
57
  DDRD |= (1<<CTS);  // Pin an CTS-Eingangs des BT-Moduls als Ausgang derfinieren
58
  PORTD |= (1<<RTS);  // Pull-Up Widerstand am Eingang des Pins am RTS-AUsgang des BT-Moduls
59
  PORTD &= ~(1<<CTS); // Mittels CTS empfangsbereitschaft signalisieren
60
  lcd_init();
61
  uart_init();
62
  lcd_clear();
63
  set_cursor(0,1);
64
  lcd_string("Suche BT-Geraete");
65
  while(PIND & (1<<RTS))  // Warten, bis BT - Modul bereit zum Empfangen ist
66
  {}
67
  PORTD |= (1<<CTS);     // Nicht empfangsbereit
68
  BT_environment_inquiry();  // Umgebung nach BT - Geräten absuchen
69
  PORTD &= ~(1<<CTS);      // Empfangsbereit
70
  sei();
71
  lcd_clear();
72
  while (1)
73
  {
74
    if (paket_ende == 1)
75
    {
76
      count1 = 1;
77
      while (count1 > (lcd_zeichen - 1))
78
      {
79
        lcd_clear();
80
        char Puffer[20]; // in diesem {} lokal
81
        itoa(daten[count1], Puffer, 10); 
82
        set_cursor(0,zeile);
83
        lcd_string(Puffer);
84
        count1 ++;
85
        if (count1 == 15)
86
        {
87
          zeile = 2;
88
        }
89
      }
90
    }
91
    if(paket_laenge > PAKET)    // Falls Paketgröße die größe der Paketvariable übersteigt
92
    {
93
      set_cursor(0,2);
94
      lcd_string("Err0:Paketlaenge");
95
      while(1);
96
    }
97
    else if(paket_laenge < 7)    // Fehler beim berechnen der Paketgröße
98
    {
99
      set_cursor(0,2);
100
      lcd_string("Err1:Paketlaenge");
101
      while(1);
102
    }
103
    if ((daten[0] != 0x02) && (count0 > 1))  // Paketanfang ist nicht Start Delimiter!
104
    {
105
      lcd_clear();
106
      set_cursor(0,2);
107
      lcd_string("Err2:Paketanfang");
108
      
109
      char Puffer[20]; // in diesem {} lokal
110
      itoa(daten[0], Puffer, 10); 
111
      set_cursor(14,1);
112
      lcd_string(Puffer);
113
      
114
      while(1);
115
    }
116
  }  
117
}

Ich habe nun mal versucht das ganze umzusetzen allerdings stimmt 
irgendwas bei der Reihenfolge wie die Byte gespeichert werden nicht. Der 
Start Delimiter fehlt des öfteren ( = 0).
Vielleicht sollte ich es doch mal mit dem Rinpuffer versuchen.

Die ANfrage an das Modul (BT_environmen_inqury) wird korrekt gesendet. 
Die Antworten kommen aus am UART -Eingang an. (Logic Analyser)

MfG Pat711

von Sascha W. (sascha_w)


Lesenswert?

schmeiß mal die ganzen LCD Ausgaben aus der ISR raus, das dauert dort 
viel zu lange! Wenn du die Daten unbedingt ausgeben willst, dann setze 
noch ein FLAG und mach die Ausgabe in Main.
UND definiere alle Variablen die in Main und der ISR verändert werden 
als volatile!

Sascha

von Patrick R. (pat711)


Lesenswert?

Guten Tag zusammen,

die LCD ausgaben habe ich erst nachträgich eingefügt, um den Fehler zu 
finden. Nun habe ich sie wieder herausgenommen, aber es funktioniert 
auch so nicht.
Es wird auf dem LCD immer Err2:Paketanfang angezeigt, was bedeutet, dass 
mein Startdelimiter fehlerhaft ist. Die Variable data[0], welche neben 
dem Fehler angezeigt wird hat immer einen der folgenden Werte: 14, 23, 
105 oder 114.
Diese Werte kommen in der Antwort des Moduls gar nicht vor. Diese 
Antwrot sieht folgendermasen aus:
0x02 Start Delimiter
0x69 Packet Type identification
0x01 Op Code
0x09 Data length
0x00 Data length
0x73 Checksum
0x72 Packet Data
0x15 Packet Data
0x07 Packet Data
0x0E Packet Data
0x19 Packet Data
0x00 Packet Data
0x04 Packet Data
0x01 Packet Data
0x3E Packet Data
0x03 End Delimiter
1
#include <avr/io.h>
2
#include <arf32.h>
3
#include <lcd-routines.h>
4
#include <stdlib.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h> 
7
8
#define PAKET   25    // Maximale Paketlänge festlegen
9
#define CTS    PD7    // CTS - Pin des BT - Moduls (in)
10
#define RTS    PD6    // RTS - Pin des BT - Moduls (out)
11
12
uint8_t buffer = 0;    // Puffervariable in der das empfangene Zeichen abgelegt wird
13
uint8_t daten[PAKET];  // Variable, in der die Empfangenen Pakete abgelegt werden
14
uint8_t count0 = 0;    // Zähler zur erstellung der Pakete
15
uint8_t count1 = 0;
16
uint8_t zeile = 1;    // zum festlegend der LCD - Zeile
17
uint8_t paket_ende = 0; // Paketende - Flag um zu signalisieren, dass das Paket vollständig empfangen wurde
18
uint8_t paket_laenge = PAKET;
19
uint8_t lcd_zeichen = 0;
20
uint8_t kont = 0;
21
uint8_t lcd_flag = 0;
22
23
ISR (USART_RX_vect)
24
{
25
  buffer = UDR0;        // Empfangenes Zeichen in Puffer einlesen
26
  daten[count0] = buffer;    // Empfangenes Zeichen dem Paket hinzufügen
27
  count0 ++;
28
  if (count0 == (paket_laenge + 1))
29
  {
30
    paket_ende = 1;      // Paket wurde emfangen
31
    paket_laenge = PAKET;
32
    count0 = 0;
33
  }
34
  if (count0 == 5)        // Wenn beide Datenlänge Bits empfangen wurden
35
  {
36
    paket_laenge = (daten[4] * 256) + daten[3] + 7;
37
    lcd_zeichen = paket_laenge;
38
    
39
    lcd_flag = 1;  
40
  }
41
}
42
43
int main(void)
44
{
45
  _delay_ms(100);
46
  DDRD |= (1<<CTS);  // Pin an CTS-Eingangs des BT-Moduls als Ausgang derfinieren
47
  PORTD |= (1<<RTS);  // Pull-Up Widerstand am Eingang des Pins am RTS-AUsgang des BT-Moduls
48
  PORTD &= ~(1<<CTS); // Mittels CTS empfangsbereitschaft signalisieren
49
  lcd_init();
50
  uart_init();
51
  lcd_clear();
52
  set_cursor(0,1);
53
  lcd_string("Suche BT-Geraete");
54
  while(PIND & (1<<RTS))  // Warten, bis BT - Modul bereit zum Empfangen ist
55
  {}
56
  PORTD |= (1<<CTS);     // Nicht empfangsbereit
57
  BT_environment_inquiry();  // Umgebung nach BT - Geräten absuchen
58
  PORTD &= ~(1<<CTS);    // Empfangsbereit
59
  sei();
60
  lcd_clear();
61
  while (1)
62
  {
63
    if (paket_ende == 1)
64
    {
65
      count1 = 1;
66
      while (count1 > (lcd_zeichen - 1))
67
      {
68
        lcd_clear();
69
        char Puffer[20]; // in diesem {} lokal
70
        itoa(daten[count1], Puffer, 10); 
71
        set_cursor(0,zeile);
72
        lcd_string(Puffer);
73
        count1 ++;
74
        if (count1 == 15)
75
        {
76
          zeile = 2;
77
        }
78
      }
79
    }
80
    if(paket_laenge > PAKET)    // Falls Paketgröße die größe der Paketvariable übersteigt
81
    {
82
      set_cursor(0,2);
83
      lcd_string("Err0:Paketlaenge");
84
      while(1);
85
    }
86
    else if(paket_laenge < 7)    // Fehler beim berechnen der Paketgröße
87
    {
88
      set_cursor(0,2);
89
      lcd_string("Err1:Paketlaenge");
90
      while(1);
91
    }
92
    if ((daten[0] != 0x02) && (count0 > 1))  // Paketanfang ist nicht Start Delimiter!
93
    {
94
      lcd_clear();
95
      set_cursor(0,2);
96
      lcd_string("Err2:Paketanfang");
97
      
98
      char Puffer[20]; // in diesem {} lokal
99
      itoa(daten[0], Puffer, 10); 
100
      set_cursor(13,1);
101
      lcd_string(Puffer);
102
      
103
      while(1);
104
    }
105
    if (lcd_flag == 1)
106
    {
107
      lcd_clear();
108
      char Puffer[20]; // in diesem {} lokal
109
      itoa(daten[paket_laenge], Puffer, 10); 
110
      set_cursor(0,1);
111
      lcd_string(Puffer);
112
      
113
      itoa(daten[3], Puffer, 10); 
114
      set_cursor(5,1);
115
      lcd_string(Puffer);
116
      
117
      itoa(daten[4], Puffer, 10); 
118
      set_cursor(10,1);
119
      lcd_string(Puffer);  
120
    }
121
  }  
122
}

von Patrick R. (pat711)


Lesenswert?

Im letzten Thread hatte ich einen kleinen Fehler, und zwar kommen die 
Werte doch auch alle bis auf einen in der Antwort vor.
114 -> 0x72 Packet Data 1.Stelle
105 -> 0x69 Packet Type identification
23  -> 0x17 kommt nicht vor ???
14  -> 0x0E Packet Data 4.Stelle

heißt wohl dass mein Programm zu lansam arbeitet, oder?

und das mit den volatile habe ich auch noch vergessen die werde ich nun 
verändern.
Edit: Macht keinen Unterschied

MfG Pat711

von Sascha W. (sascha_w)


Lesenswert?

Patrick R. schrieb:
> heißt wohl dass mein Programm zu lansam arbeitet, oder?
das würde erst mal heißen das das 1.Byte verschluckt wird, was schon 
dadurch passieren kann wenn die Schnittstelle erst nach dem Einschalten 
verbunden wird und dadurch eine Flanke am Eingang auftritt.
Das Problem was ich momentan noch sehe ist die fehlende Syncronisation 
am Anfang. Wenn irgendwas aus dem Tritt kommt wird count0 ja erst wieder 
auf null gesetzt wenn der Puffer voll ist, und auch dann werden 
anschließend die Daten wieder falsch eingelesen. Wenn das Startbyte auch 
innerhalb der Daten vorkommt bleibt zur Syncronisation nur ein Timeout, 
also ein Reset des count0 wenn für z.B. 100ms keine Daten kommen, oder 
wenn die Daten nur auf Anforderung gesendet werden dann am besten vor 
dem senden den count0=0 setzen.

Sascha

von Patrick R. (pat711)


Lesenswert?

Das mit dem Timer ist eine gute Idee. Aber ich vermute, dass ich mit 
einem Ringpuffer besser arbeiten kann. Ich werde dies jetzt einmal 
ausprobieren da ich vermite, dabei mehr chancen zu haben keine Bytes zu 
verlieren.
Der Ringpuffer muss ja auch nicht 256 Byte lang sein.

MfG Pat711

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.