Serielle Verbindung bricht ab

Gast #3937936
Lesenswert?

Hallo,

mein Arduino empfängt alle 500ms ein Datenpaket mit einer Zahl darin, 
dieses wird in ein char Array gespeichert und zu einem MD5 hash gehasht. 
Danach wird an den Hash noch 456 (ID) dran gehängt.
Funktioniert alles problemlos, jedenfalls 1-2 Minuten. Danach stoppt die 
Serielle Kommunikation des Arduinos einfach. Die LED-leuchtet nicht 
mehr, durch die Arduino IDE kommt nichts mehr an und auch nicht in 
Putty.  Komisch ist wenn ich das serielle Fenster in der Arduino IDE 
beende und danach wieder öffne klappt die Ausgabe wieder für 1-2 
Minuten. Bin echt ratlos..

Baudrate wurde mit 9600 und 115200 versucht.



1
#include <MD5.h>
2
#include <SPI.h>
3
#include <Ethernet.h>
4
#include <EthernetUdp.h>
5

6

7

8

9
int udppacket=0;
10
int arraygroesse= 0;
11
int clientarraygroesse=0;
12
byte sendestatus=0;
13
byte hashzaehler = 0;
14
unsigned long clientzeit=0;
15

16

17

18
char recieveddata[100];
19
char hasharray[100]; //Ein MD5 Hash hat 32 Zeichen, hier von 0-31, die Zeichen 32-34 dient zur Zuordnung des Hashes, die restlichen fuer die Clientzeit
20
char clientzeitbuffer[100];
21

22

23
//Lokale Adresse:
24

25
byte clientmac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEB };
26
IPAddress clientip(192, 168, 3, 2);
27
IPAddress clientsubnet(255, 255, 255, 0);
28
IPAddress gateway(192, 168, 3, 1);
29
int clientport = 8002; //Lokaler Port
30

31
//Serveradresse:
32

33
IPAddress serverip(192, 168, 3, 1); //Address to send UDP packe to
34
IPAddress servergateway(292, 168, 3, 1);
35
int serverport = 8001;
36

37

38
char packetbuffer[UDP_TX_PACKET_MAX_SIZE]; //Bufferspeicher um Empfangene Pakete bis zur Bearbeitung zu speichern.
39
EthernetUDP Udp; //Beginnt eine UDP-Instanz
40

41

42
//########################################################################################################################################################################
43

44

45
void setup() {
46

47
  Ethernet.begin(clientmac, clientip, clientsubnet, gateway);
48
  Udp.begin(clientport);
49
  Serial.begin(115200);
50

51
}
52

53
//########################################################################################################################################################################
54

55

56

57
void loop() {
58

59

60
  char udppacket = Udp.parsePacket();
61
  if (udppacket) {
62
    Serial.println(udppacket);
63

64

65
    Udp.read(packetbuffer, udppacket);
66
    Serial.println(packetbuffer);
67

68

69
    //Speichert die Empfangenen Daten in ein char Array
70
    for (int i = 0; i < udppacket; i++) {
71
      recieveddata[i] = packetbuffer[i];
72
      Serial.print("Empfangene Zeit:");
73
      Serial.println(recieveddata[i]);
74

75
    }
76

77
    //Ermittelt die tatsächliche größe des Arrays
78
    arraygroesse = (unsigned)strlen(recieveddata);
79
    Serial.print("Arraygroesse ");
80
    Serial.print(arraygroesse);
81
    Serial.print("\n");
82

83
  }
84

85

86
   //########################################################################################################################################################################
87

88

89
  //if (arraygroesse!=0 && arraygroesse<31 && sendestatus==0) { //Die erste Zeit wird empfangen und gehasht.
90
if(arraygroesse >0){
91

92
    
93
    Serial.println("Der Mikrocontroller ist am HASH-Erstellen");
94
    unsigned char* hash = MD5::make_hash(recieveddata);
95
    char *md5str = MD5::make_digest(hash, 16);
96
    free(hash);
97
    //Serial.println(md5str);
98

99

100
    //Gibt den Hash in der seriellen Konsole & speichert ihn in ein neues Array.
101
    //Serial.println (hasharray[32]);
102
    for (int i = 0; i < 32; i++) {
103
      hasharray[i] = md5str[i];
104
     // Serial.print(hasharray[i]);
105
    }
106

107
    //Hängt an den Hash eine ID-an um dem Server Polls von Befehlen zu unterscheiden.
108
    hasharray[32] = '4';
109
    hasharray[33] = '5';
110
    hasharray[34] = '6';
111

112

113

114
    Serial.println("Hash mit 1"); //Ausgabe des Arrays in die Serielle Konsole
115
    for (int i = 0; i < 35; i++) {
116
      Serial.print(hasharray[i]);
117
    }
118
}
119
 
120
  udppacket=0;
121
  arraygroesse=0;
122
  }


Jemand eine Idee?
Gast #3937947
Lesenswert?

Ich hab das Gefuehl, die serielle Schnittstelle ist blockierend. Dann 
wird sie mit viel zuviel Zeug zugemuellt.

Zu Beginn wuerd ich nur das UDP Packet byte fuer byte auf die Serielle 
kopieren, ohne zusaetzliches Zeug.
Gast #3937952
Lesenswert?

> könntest du das genauer erklären?

Der Funktionsaufruf in besagter Zeile allokiert Ressourcen (hier: 
Speicher), die Du nie wieder freigibst (hier: das zugehörige 
free(md5str) fehlt) -> nach ein paar Runden ist die Ressource 
aufgebraucht (hier: kein freier Speicher mehr verfügbar) und es 
passieren lustige Sachen.
Gast #3937956
Lesenswert?

Paul schrieb:
> Danke für diese Antwort aber damit kann ich eigentlich gar nichts
> anfangen.

Zu jedem malloc gehört ein passendes free (siehe Grundlagen dynamischer 
Speicherverwaltung im Buch Deiner Wahl). Also in den Quelltext von 
MD5::make_hash und MD5::make_digest sehen, ob dort ein malloc passiert.

Der Autor der MD5-Lib hätte auch die C++-Möglichkeiten nutzen können 
(RAII), statt eine Klasse als überflüssigen Behälter für simple C-artige 
Funktionen zu verwenden.
Gast #3937958
Lesenswert?

Ah, vielen Dank!
Habe es nun geändert.
1
   Serial.println("Der Mikrocontroller ist am HASH-Erstellen");
2
    unsigned char* hash = MD5::make_hash(recieveddata);
3
    char *md5str = MD5::make_digest(hash, 16);
4
    free(md5str);

Jedoch besteht das selbe Problem weiterhin.
Weitere Ideen?
Gast #3938371
Lesenswert?

Hallo,

nun habe ich ein weiteres Problem, der Hash wird erstellt jedoch stimmt 
dieser nur teilweise überein.. wäre toll wenn mir wieder jemand einen 
Tipp geben könnte. Das Array welches an die Hashfunktion gegeben wird 
enthält den  richtigen Inhalt, auch der generierte Hash stimmt, jedoch 
fehlen unterscheiden sich die Hashes:

z.B.

Klartext: 7377913

Arduino-Hash

1a6363927d7bfc6ff1cbd7048760d57378914

Normal generierter Hash

691a6363927d7bfc6ff1cbd7048760d5


Jemand eine Ahnung?
1
#include <MD5.h>
2
#include <SPI.h>
3
#include <Ethernet.h>
4
#include <EthernetUdp.h>
5

6

7
int udppacket = 0;
8
int arraygroesse = 0;
9
int clientarraygroesse = 0;
10
byte sendestatus = 0;
11
byte hashzaehler = 0;
12
unsigned long clientzeit = 0;
13

14

15

16
char recieveddata[100];
17
char hasharray[100]; //Ein MD5 Hash hat 32 Zeichen, hier von 0-31, die Zeichen 32-34 dient zur Zuordnung des Hashes, die restlichen fuer die Clientzeit
18
char clientzeitbuffer[100];
19

20

21
//Lokale Adresse:
22

23
byte clientmac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEB };
24
IPAddress clientip(192, 168, 3, 2);
25
IPAddress clientsubnet(255, 255, 255, 0);
26
IPAddress gateway(192, 168, 3, 1);
27
int clientport = 8002; //Lokaler Port
28

29
//Serveradresse:
30

31
IPAddress serverip(192, 168, 3, 1); //Address to send UDP packe to
32
IPAddress servergateway(292, 168, 3, 1);
33
int serverport = 8001;
34

35

36
char packetbuffer[UDP_TX_PACKET_MAX_SIZE]; //Bufferspeicher um Empfangene Pakete bis zur Bearbeitung zu speichern.
37
EthernetUDP Udp; //Beginnt eine UDP-Instanz
38

39

40
//########################################################################################################################################################################
41

42

43
void setup() {
44

45
  Ethernet.begin(clientmac, clientip, clientsubnet, gateway);
46
  Udp.begin(clientport);
47
  Serial.begin(9600);
48

49
}
50

51
//########################################################################################################################################################################
52

53

54

55
void loop() {
56

57

58
  udppacket = Udp.parsePacket();
59
  if (udppacket) {
60

61
    Udp.read(packetbuffer, udppacket);
62
    Serial.println(packetbuffer);
63

64

65
    //Speichert die Empfangenen Daten in ein char Array
66
    for (int i = 0; i < udppacket; i++) {
67
      recieveddata[i] = packetbuffer[i];
68
      Serial.println("Empfangene Zeit:");
69
      Serial.println(recieveddata[i]);
70
      Serial.println(packetbuffer[i]);
71

72

73
    }
74

75
    //Ermittelt die tatsächliche größe des Arrays
76
    arraygroesse = (unsigned)strlen(recieveddata);
77
    Serial.print("Arraygroesse ");
78
    Serial.print(arraygroesse);
79
    Serial.print("\n");
80

81
  }
82

83

84
  //########################################################################################################################################################################
85

86

87
  //if (arraygroesse!=0 && arraygroesse<31 && sendestatus==0) { //Die erste Zeit wird empfangen und gehasht.
88
  if (arraygroesse > 0) {
89

90

91
    Serial.println("HASH-Erstellen");
92
    unsigned char* hash = MD5::make_hash(recieveddata);
93
    char *md5str = MD5::make_digest(hash, 16);
94
    free(hash);
95
    free(md5str);
96

97

98

99
    for (int i = 0; i < 32; i++) {
100
      Serial.print(md5str[i]);
101
    }
102
    arraygroesse = 0;    
103
    memset(recieveddata, 0, sizeof(recieveddata));
104

105

106
  }
107
}
Gast #3938387
Lesenswert?

Paul schrieb:
> free(md5str);
>
>     for (int i = 0; i < 32; i++) {
>       Serial.print(md5str[i]);

du darfst nicht den Speicher freigeben und dann später wieder darauf 
zugreifen.

Ich würde das Programm so umschreiben, das man überhaupt keine 
dynamischen Speicher braucht, lege doch das hash objekt global an. Das 
kann auch mehrfacher verwendet werden.

Keine Ahnung wie Arduino reagiert, wenn kein Speicher mehr frei ist bzw. 
wenn er zu stark fragmentiert ist.
Gast #3938437
Lesenswert?

Paul schrieb:
> Ja ich habe jetzt md5str vor der Speicherfreigabe in ein neues char
> Array geschrieben und jetzt klappt es... :)

und warum? hast du zu viel ram oder cpu zeit das du sinnlos zeug 
rumkopieren musst?

Kannst du es nicht gleich in eine Variabel schreiben lassen?

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