Hallo ich habe folgendes Problem:
Ich habe das Problem das immer wenn ich einen String sende der nicht
verglichen wird, das sich das Programm aufhängt.
Es würde mich freuen wenn Ihr mir helfen könntet da ich noch nicht so
ganz der super Programmierer binn.
1
charinData[20];// Allocate some space for the string
2
charinChar=-1;// Where to store the character read
3
byteindex=0;// Index into array; where to store the character
4
intleda=12;
5
intledb=11;
6
7
8
9
voidsetup(){
10
pinMode(leda,OUTPUT);
11
pinMode(ledb,OUTPUT);
12
Serial.begin(9600);
13
}
14
15
16
17
18
19
charComp(char*This){
20
21
while(Serial.available()>0)// Don't read unless
22
// there you know there is data
23
{
24
if(index<19)// One less than the size of the array
Hallo Jonas,
Jonas Röver schrieb:> if(Comp("*grün an#")==0)
Es ist grundsätzlich, immer und überall, auch in einem String (gerade
wenn es ums vergleichen geht) eine sehr schlechte idee, zeichen zu
benutzen, die nicht dem englischen Alphabet angehören (bzw. nicht
standard 7-bit ASCII zeichen)!
Guter Tipp zum Programmieren: Besorg dir eine Tastatur mit
englischem/u.s. layout! Dann kommst du beim Programmieren gar nicht in
die Situation "ausversehen" zeichen zu benutzen, die irgendwie,
irgendwann, irgendwo mal probleme machen können. Alle zeichen die in
dieser Tabelle stehen: http://de.wikipedia.org/wiki/ASCII#ASCII-Tabelle
, also mit 0 bis 127 Codiert sind, können ohne Probleme genutzt werden.
Alles was danach kommt... naja, kann dich im schlimmsten fall schon mal
wochen oder monate an zeit kosten, um einen fehler zu finden.
Jonas Röver schrieb:> das sich das Programm aufhängt
Ich glaube nicht, das sich das Programm aufhängt. Ich denke folgendes
passiert:
Du hast 2 Strings, die du vergleichst. Der vergleich schlägt fehl, und
deine Funktion Comp liefert eine 1 zurück... und was machst du mit der
eins? richtig: nichts. also passiert auch nichts, und du siehst auch
nichts, weil du die 1 nicht auswertest.
Es könnte auch noch sein, dass das Programm vielleicht doch in der
> while(Serial.available() > 0)
-Schleife hängen bleibt, warum auch immer.
Wie sendest du den String vom PC zum Arduino? Terminal-Programm?
Welches?
Hast du die Kommunikation überhaupt schon mal getestet? Sende erstmal
ein Zeichen vom PC zum Arduino, und sende das Zeichen einfach direkt
wieder zurück, dann weißt du immerhin schonmal das die Kommunikation
PC<-->Arduino funktioniert.
#############################################################
Nachtrag: (Ich lass den Text da oben jetzt stehen, einfach um meine
Gedankengänge zu zeigen, auch wenn es schon wieder hinfällig ist)
Du hast einen Denkfehler...
In deiner Funktion Comp wartest du darauf, einen String zu empfangen...
Das bedeutet für dein Programm folgendes:
Bei jedem aufruf von Comp, wartet dein Programm auf Input von der
Seriellenschnittstelle!
Das heißt, immer wenn du Comp aufrufst, musst du auch was an den
Arduino senden, weil er da sonst natürlich hängen bleibt.
Ich geb dir eine kleine Denkhilfe (Pseudo-Code), wie man es machen
könnte :
1
voidloop()
2
{
3
// Daten von der Seriellenschnittstelle abholen
4
while(datenanseriellerschnitstelle)
5
{
6
dataIn[i]=serial.read()
7
i++
8
}
9
10
// Strings direkt vergleichen also ohne deine Comp-Funktion
11
if(strcmp(...)==0)
12
{
13
// mach was
14
}
15
else
16
{
17
// vergleich ist fehlgeschlagen, Irgendwie sichtbar machen z.b. eine
18
// LED aufleuchten lassen
19
}
20
// dataIn zurück setzen
21
}
Natürlich kann man das alles schöner, besser und schneller machen, aber
es soll ja auch nur ein anstoß sein.
Nochmal zusammengefasst:
- (empfohlen) keine "Sonderzeichen/Umlaute" wie ä,ü,ß,€,µ, usw.
Zeichen wie "%&*# etc, sind aber zulässig (siehe ASCII-Tabelle)
ggf. muss auf ESC-Sequenzen geachtet werden, bin grade nicht sicher.
- Daten nur einmal abholen, dann alle vergleiche machen, und erst dann
wieder Daten abholen
Das ist, das, was mir so auf die schnelle auffällt. Viel glück
Grüße
Kaj schrieb:> Du hast einen Denkfehler...> In deiner Funktion Comp wartest du darauf, einen String zu empfangen...> Das bedeutet für dein Programm folgendes:> Bei jedem aufruf von Comp, wartet dein Programm auf Input von der> Seriellenschnittstelle!> Das heißt, immer wenn du Comp aufrufst, musst du auch was an den> Arduino senden, weil er da sonst natürlich hängen bleibt.
Das ist natürlich völliger blödsinn von mir :-(
Die schleife wartet ja gar nicht auf daten, mein fehler. Aber wenn keine
Daten empfangen werden, vergleichst du einen String, den du in die
Funktion Comp reingibst, mit einem Array das voll mit 0 ist, der
vergleich schlägt fehl und wir sind bei:
Kaj schrieb:> Du hast 2 Strings, die du vergleichst. Der vergleich schlägt fehl, und> deine Funktion Comp liefert eine 1 zurück... und was machst du mit der> eins? richtig: nichts. also passiert auch nichts, und du siehst auch> nichts, weil du die 1 nicht auswertest.
Grüße
(*noch immer kein Anspruch auf richtigkeit meiner auskunft :-/ )
Der ganze Ansatz ist unsinnig.
Und das beginnt bereits damit, das der Empfänger nicht entscheiden kann,
wann denn der Sender nichts mehr senden wird.
Genau dazu gibt es die Return Taste. Damit man in einem Text zb
markieren kann: So jetzt ist der Text fertig.
Diejenigen, die noch mit einer Commandline und nicht mit klickibunti
gelernt haben, kennen das noch. An einer Command-Line gibt man die
Zeichen ein. Man kann ändern, mit dem Cursor hin und her fahren, Zeichen
einfügen, zeichen löschen, was auch immer. Erst wenn man auf Return
drückt, signalisiert man der Command Line: Soooo, fertig, meine
Text-Eingabe steht, jetzt kannst du anfangen sie auszuwerten.
Und genauso auch hier:
Der Sender muss dem Empfänger irgendwie mitteilen: Fettich, jetzt kommt
nichts mehr, das was du bisher gekriegt hast, das ist mein Text.
Und da sich die return Taste dafür bewährt hat, würde ich vorschlagen du
benutzt das auch. Drückst du auf Return, dann wird das Zeichen '\n'
übertragen. Das ist für den Arduino das Signal "Das wars, jetzt ist der
String fertig, ich kann anfangen ihn auszuwerften"
Die Strategie ist
2 wesentliche Dinge:
Wir warten nicht darauf, das der String komplett übertragen wurde!
Wenn ein Zeichen eingetroffen ist, dann holen wir es und hängen es an
den bisherigen Text hinten drann. Mehr nicht! Sobald das Zeichen hinten
an den text angehängt wurde, macht das Programmm mit seiner restlichen
Arbeit weiter.
Erst wenn ein '\n' eintrifft wissen wir: jetzt ist der vollständige Text
da. Erst jetzt kann die Auswertung beginnen.
macht man auch anders. Denn der nächste schreibt 'an' mit einem 'A', der
übernächste schreibt überhaupt alles in Grossbuchstaben, und und und. Da
wird man nicht fertig, wenn man alle Kombinationen in jeweils eigenen
Abfragen auswertet.
Was man statt dessen macht ist, dass man den empfangenen String komplett
in Grossbuchstaben umwandelt, ehe dann die Vergleicherei (natürlich mit
den Kommandos in Grossbuchstaben) los geht. Dann spielt die genaue
Gross-/Kleinschreibung des Benutzers keine Rolle mehr, selbst ein
getipptes "*LiChT aN#" wird dann korrekt vom Programm als "*LICHT AN#"
erkannt.