Forum: Mikrocontroller und Digitale Elektronik Arduino - Serielle Daten Speicher?


von Georg M. (georg_m)


Lesenswert?

Hi allesammt und ein frohes Neues.
Ein neues Jahr ein neues Problem :)

Ich empfange über die serielle Schnittstelle meines Arduino Mega2560 das 
Funkprotokoll eines TCM320 Funktransceiver von EnOcean. Die Baudrate 
muss dabei 57600 sein und es werden immer 38 Bytes empfangen.
Die empfangenen Daten lasse ich mir über die Konsole in Hexadezimal 
ausgeben.
Hier mein Code, ich hab mal alles bis auf die wesentlichen Funktionen 
rausgenommen.

void setup()
{
  Serial.begin(115200);
  Serial2.begin(57600);
}

void loop()
{
  Serial.print("Messwert ");
  Serial.println(Serial2.read(),HEX);   // Write to PC serial
}

Das Funktioniert auch soweit super.
Jetzt würde ich die Werte gerne Puffern um sie anschließend auf einer SD 
Karte zu speichern (direkt speichern dauert zu lange und es kommt 
Datenschrott raus).
Dies klappt aber nur bedingt.
Versuche ich die Daten in einem Array zu speichern und gebe sie mir 
anschließend zur Kontrolle aus, bekomme ich teils Datenmüll.

char data[]={};    //Char-Array zum speichern der Daten
int B=1;           //Zähler, nur nötig damit er mir im loop nur einmal
                   //eine Ausgabe gibt

void loop()
{
  while(Serial2.available()!=0)  //Warten auf Daten
  {
    Serial2.readBytes(data,1000); //Speichern der Daten im Array
    B=0;
  }

  if(B==0)
  {
    B=1;
    for(int i=0;i<100;i++)
     {
       Serial.print(data[i],HEX); //Ausgabe über die Konsole in HEX
     }
  }
}

Und das kommt dabei raus.

5507183FFFFFFE0FFFFFFF63001F5B1B305FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C013 
2D02C3042D30122D30152D30182D30FFFFFFC75507183FFFFFFE0FFFFFFF6001F5B1B205 
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C013FFFFFFD802C2042D20142C3230343244323 
031343243333233303334333234343332333033313334333234

Aus irgendeinem Grund schreibt er mir einfach 0xFF bzw 255 oder 11111111 
mittenrein. Was es natürlich später unmöglich macht präzise bestimme 
Bytes wieder auszulesen. Da sie statt an Stelle x nun auf Position xy 
stehen. :(
Was interessant ist, ist das er FF immer an die selben Stellen schreibt.

Solange ich mir die Daten einfach nur direkt ausgeben lasse (mit 
115200Baud) Funktioniert es super und ich bekomme nur die eigentlichen 
Telegrammdaten.

Hat jemand eine Idee woran das liegen kann?
Sind das vll. Pausen zwischen einzelnen Daten die er irgendwie versucht 
zu füllen?

von Karl H. (kbuchegg)


Lesenswert?

> char data[]={};    //Char-Array zum speichern der Daten

C Buch (oder C++ Buch).

Auch wenn dir der Compiler durch das eigenständige Abzählen der 
Initialisierungen die Angabe einer Array Größe erspart, kommst du nicht 
umhin das Array zu dimensionieren.
In C (und C++) gibt es kein Array, welches selbttätig seine Größe 
ändert, je nachdem wieviele Daten du da reinstopfen willst.
Du selbst bist dafür zuständig, das Array in der entsprechenden Größe zu 
dimensionieren.

>     Serial2.readBytes(data,1000); //Speichern der Daten im Array
wenn du da 1000 Bytes reinlegen willst, dann musst du auch das Array 
entsprechend groß dimensionieren

char data[1000];

und das mit den 1000 würde ich mir nochmal überlegen.

von Georg M. (georg_m)


Lesenswert?

Ja das hatte ich mir auch schon gedacht.
Leider ist es im vollkommen egal wie groß ich das Array dimensioniere.
Auch wenn ich die größe des Arrays genau an die Telegrammgröße anpasse 
schreibt er mir alles mit FF voll.
Erst wenn ich mit der Arraygröße und die Telegrammgröße gehe fängt er an 
vollkommen zu spinnen.
Die 1000 standen noch vom wilden rumspielen mit der Arraygröße drinn. 
Hätte ich erwähnen sollen.

von Karl H. (kbuchegg)


Lesenswert?

Du hast dich nicht um das Timeout gekümmert und denn sinn dahinter 
solange die nächsten Bytes jeweils wieder ab Beginn des Arrays zu 
schreiben, ist mir auch noch nicht klar.

Wie wärs denn mal, nach den Arduino Regeln zu spielen?
1
char data[10];
2
int  dataLen = 0;
3
4
void loop()
5
{
6
  if (Serial2.available())  // Ist was da?
7
  {
8
    data[dataLen] = Serial2.Read();
9
    dataLen++;
10
  }
11
12
  if (dataLen == 10)
13
  {
14
    for(int i=0; i<dataLen; i++)
15
    {
16
      Serial.print(data[i],HEX); //Ausgabe über die Konsole in HEX
17
    }
18
    dataLen = 0;
19
  }
20
}

von Georg M. (georg_m)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Du hast dich nicht um das Timeout gekümmert und denn sinn dahinter
> solange die nächsten Bytes jeweils wieder ab Beginn des Arrays zu
> schreiben, ist mir auch noch nicht klar.
>
> Wie wärs denn mal, nach den Arduino Regeln zu spielen?

Hach, jetzt wird es interessant :)
Erst einmal danke Karl Heinz, der Datenmüll am Ende ist jetzt weg.
Aber ansonsten sieht es immer noch aus wie bei mir.
Mir ist jetzt etwas aufgefallen nachdem ich die Ausgabe mal mit 
Serial.println gemacht habe und beide verglichen hab.

Ausgabe nach          direkte Ausgabe
Speicherung

55                      55            Sync.-Byte
0                        0            Datenlänge
7                        7            Datenlänge also 7Byte
18                      18            Länge Optionaler Daten
3                        3            Paket-Typ
FFFFFFE0                E0            CRC-8 Datenbyte; Checksumme
FFFFFFF6                F6            Telegrammtyp
10                      10            Nutzdaten
0                        0            Sender ID
1F                      1F            Sender ID
5B                      5B            Sender ID
1B                      1B            Sender ID
30                      30            Status-Byte
5                        5            Subtelegrammzahl
FFFFFFFF                FF            Ziel ID
FFFFFFFF                FF            Ziel ID
FFFFFFFF                FF            Ziel ID
FFFFFFFF                FF            Ziel ID
2D                      2D            RSSI-Wert in dBm
0                        0            Security Level
10                      10            Zeitstempel
76                      76            Zeitstempel
.                        .
.                        .
.                        .
Warum hängt er nur bei manchen Daten noch 3mal FF davor?
Interessanterweiße mach er es auch immer nur bei den gleichen Daten.

von Georg M. (georg_m)


Lesenswert?

Ok, Problem ist optisch gelöst^^
Damit die FF Werte verschwinden stelle ich vor dem Speichern einen 
Vergleich an. UInt32 habe ich in einem extra h-File definiert.
Vielen dank an alle für die Hilfe


UInt32 temp  = 0x00000000;
UInt32 temp1 = 0x000000FF;
UInt32 data[10]={0,0,0,0,0,0,0,0,0,0};

void loop()
{
  if (Serial2.available())
  {
    temp=Serial2.read();
    data[dataLen] = temp&temp1;
    dataLen++;
  }

  if (dataLen == 10)
  {
    for(int i=0; i<dataLen; i++)
    {
      Serial.println(data[i],HEX);
    }

    dataLen = 0;
  }
}

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.