Hallo zusammen,
ich habe folgendes Problem und weiß leider nicht mehr weiter:
Ich habe einen Code für ein Meldersystem geschreiben, welches serielle
Daten im Format ID;Typ;Text~ bekommt also z.B. 1;A;Text!~
Wenn ich diesen Befehl an den Arduino schicke, startet dieser jedoch
beim Befehl atoi() neu.
Hier der Code:
1
//Libraries
2
#include<RFM12B.h>
3
4
//-----------------------
5
6
//Variables
7
uint8_tkey[]="1234567890123456";
8
intserialSpeed=19200;
9
intownId=1;
10
intgroup=86;
11
chardestination[3];
12
chartype[1];
13
chartext[128];
14
charsendText[128];
15
intackTime=25;
16
boolrequestAck=true;
17
intdest=0;
18
//-------------------------------
19
20
//Instances
21
RFM12Bradio;
22
23
//------------------------------
24
25
26
voidsetup()
27
{
28
Serial.begin(serialSpeed);
29
Serial.println("0x00");
30
radio.Initialize(ownId,RF12_433MHZ,group);
31
radio.Encrypt(key);
32
}
33
34
voidincoming()
35
{
36
if(Serial.available())
37
{
38
delay(10);
39
Serial.readBytesUntil(';',destination,3);
40
Serial.println((String)destination);
41
Serial.readBytesUntil(';',type,1);
42
Serial.println((String)type);
43
Serial.readBytesUntil('~',text,128);
44
Serial.println((String)text);
45
dest=atoi(destination);//Hier steigt der Arduino aus
Serial.println("Nachricht erfolgreich an Melder: "+(String)dest+" gesendet!");
54
}
55
}
56
}
57
58
staticbooleanwaitForAck(intdest)
59
{
60
longnow=millis();
61
while(millis()<(now+ackTime))
62
{
63
if(radio.ACKReceived(dest))
64
returntrue;
65
}
66
returnfalse;
67
}
68
69
voidloop()
70
{
71
incoming();
72
}
Es wäre super, wenn jemand einen Tipp hätte warum das nicht
funktoniert...
Die Serielle ausgabe des Arduino sieht wie folgt aus:
0x00
1
A
;Te0x00
Ich freue mich auf ein paar Tipps.
Nette Grüße
Jan-Niklas
Hi,
nur eine Vermutung evtl. stört die unter Umständen fehlende
Nullterminierung von destination. Alternativ sieh dir die Funktion
strtol mal an, hier gibt es bei Fehlern bessere Möglichkeiten der
Diagnose.
Als erster Test könntest du
char destination[4];
wählen und in der loop() alle Einträge von destination auf '\0' setzen.
DirkZ schrieb:> Die Arrays werden eigentlich alle mit \0 initialisiert. Wenn man sich> nicht darauf verlassen will, schreibt man:char destination[4] = { 0> };> char type[2] = { 0 };> char text[129] = { 0 };> char sendText[129] = { 0 };
Damit setzt du aber nur das erste Array-Element auf 0!?
Kirkenes schrieb:> DirkZ schrieb:>> Die Arrays werden eigentlich alle mit \0 initialisiert. Wenn man sich>> nicht darauf verlassen will, schreibt man:char destination[4] = { 0>> };>> char type[2] = { 0 };>> char text[129] = { 0 };>> char sendText[129] = { 0 };>> Damit setzt du aber nur das erste Array-Element auf 0!?
Ja, das stimmt. Und nach C89 (3.5.7) oder C99 (6.7.8/21) auch den Rest
des Arrays.
legt die Variable text mit 128 Feldern an, die - in C nullindiziert -
von 0 bis 127 angesprochen werden. Oder hast Du vergessen, die Variablen
text und sentText auf 129 zu erweitern?
Denn die Zuweisung
1
text[128]='\0';
schreibt irgendwo im Speicher rum. Mit bekanntem Resultat.
Gut aufgepasst, aber das ist gewollt ;)
Das Funkmodul kann nur einen Datensatz von 128 Byte pro Sendung
übertragen, desswegen lasse ich es dabei, somal der Text von meiner
ansteuerungssoftware eh auf 100 Zeichen begrenzt wird.
Jan-Niklas B. schrieb:> Gut aufgepasst, aber das ist gewollt ;)
Das das Programm abstürzt? Tut es doch!
Jan-Niklas B. schrieb:> Das Funkmodul kann nur einen Datensatz von 128 Byte pro Sendung
Und? Die Variable könnte auch 1000 Byte groß sein. Solange Du beim
Senden nicht mehr als 128 Byte angibts, ist alles gut.
Entweder definierst Du
Exakt was DirkZ gesagt hat.
Und gleiches für folgendes:
1
destination[4]='\0';
2
type[2]='\0'
Du vereinbarst mit
1
chartype[2]={0};
eine Array aus 2 Chars.
Auf das erste Element greifst du mit dem Index 0 zu auf das zweite mit 1
Der Ausdruck
1
type[2]='\0'
würde auf ein drittes Element zugreifen. Das gibt es aber nicht... Der
Speicher an dieser Stelle gehört nunmal zu jemand anderem. Dem Compiler
ist das aber egal ... der meint du weißt was du tust, und lässt dich das
da hinschreiben ... Resultat? undefiniertes Verhalten ...
Ich unterstell dir jetzt einfach mal, dass das nen Flüchtigkeitsfehler
war. Ansonsten kann ich dir nur noch mal Grundlagenliteratur zum Thema
Arrays empfehlen.
Okay,dass war wohl wirklich eigene Dummheit -.-
Das Arrays 0 indexiert sind ist mir eigentlich bekannt, aber irgendwie
hab ich da nicht dran gedacht...ich baus mal ein und mal schauen ob es
dann läuft...
Danke für die HInweise
Kann man irgendwie alle Speicher des Arduino einmal löschen?
Er hat mir grade auf den Befehl hin einen Buchstabensalat mit Fragmenten
von alten Codes rausgegeben...
Du schreibst irgendwo über die Grenzen eines Arrays hinaus, jede Wette.
Bzw. Du liest etwas was nicht (richtig) nullterminiert ist. Irgendwo im
Speicher kommt mal wieder eine Null, und bis dahin kommt halt Grütze bei
raus. ;-)
Das mag sein, ich weiß nur leider nicht wo...ich hab inzwischen überall
die null-terminierung eingebaut, und komischer weise stürzt er immer
während des sendens eines Strings via Serial.println("xyz") ab... ein
gedanke den ich momentan habe ist das ich entweder das RAM aufgebraucht
habe oder ein Memmory-leak / segfault hab ...
Jan-Niklas B. schrieb:> Kann man irgendwie alle Speicher des Arduino einmal löschen?> Er hat mir grade auf den Befehl hin einen Buchstabensalat mit Fragmenten> von alten Codes rausgegeben...
schick mal den aktuellen Programmcode
Hallo Jan-Nicklas,
ich hatte auf meinem Arduino UNO unlängst möglicherweise das gleiche
Problem. Mein Programm wurde (bei knappem SRAM Speicherplatz) durch
Serial-Print()Befehle in einen unbeabsichtigten Reset-Zustand gebracht.
Nach längerem Studium der Beschreibungen im Internet kam ich zur
Konklusion, dass diese Verhalten mit der Größe des Puffers im ARDUINO
RAM zusammenhängt. Offensichtlich ist hier die Länge auf etwa 32 Zeichen
limitiert.
Abhilfe brachte bei mir nur das "Verkürzen" der Ausgaben bzw. die
Auslagerung einiger Texte in den Programm-Speicher.
Ich hoffe, dass dir dieser Hinweis bei Lösung deines Problems hilft.
STS schrieb:> Hallo Jan-Nicklas,>> ich hatte auf meinem Arduino UNO unlängst möglicherweise das gleiche> Problem. Mein Programm wurde (bei knappem SRAM Speicherplatz) durch> Serial-Print()Befehle in einen unbeabsichtigten Reset-Zustand gebracht.>> Nach längerem Studium der Beschreibungen im Internet kam ich zur> Konklusion, dass diese Verhalten mit der Größe des Puffers im ARDUINO> RAM zusammenhängt. Offensichtlich ist hier die Länge auf etwa 32 Zeichen> limitiert.>> Abhilfe brachte bei mir nur das "Verkürzen" der Ausgaben bzw. die> Auslagerung einiger Texte in den Programm-Speicher.>> Ich hoffe, dass dir dieser Hinweis bei Lösung deines Problems hilft.
Hallo,
kann ich so bestätigen, wie geschrieben. Grudsätzlich sollten Text mit
dem
F(...) eingebunden werden damit sie ins Flash kommen.
Aus
Serial.println("Nachricht erfolgreich an Melder: "+(String)destination+"
gesendet!");
wird
Serial.println(F("Nachricht erfolgreich an Melder:
")+(String)destination+ F("gesendet!"));