Hi,
also komme bei der Kommunikation von PC zu Arduino nicht mehr weiter
(Mega2560). Wenns nur darum geht einzelne zahlen zu senden dann
funktioniert das einwandfrei aber bei z.b. "p_brake=0" wirds zwar
korrekt zurückgegeben aber ich kann damit nichts vergleichen (mit
"strcmp(inString, "p_brake=1")") d.h. es passiert nicht. Hab dann
herausgefunden, dass er nicht die gesamten strings oder so einließt und
habe dazu u.a. das hier getestet:
1
#define MAXSTRING 5
2
charinString[MAXSTRING+1];// Space for the string plus Nullbyte
3
byteindex=0;
4
5
6
7
voidsetup(){
8
// initialize both serial ports:
9
Serial.begin(9600);
10
11
pinMode(47,OUTPUT);
12
pinMode(46,OUTPUT);
13
}
14
15
voidloop(){
16
17
if(Serial.available()>0){
18
inString[index]=Serial.read();
19
inString[index+1]='\0';
20
index+=1;
21
}
22
23
if(index==MAXSTRING){
24
if(!strcmp(inString,"start")){
25
digitalWrite(47,HIGH);// set the LED on
26
index=0;
27
}elseif(!strcmp(inString,"stopp")){
28
digitalWrite(47,LOW);// set the LED off
29
index=0;
30
}
31
}
32
33
34
35
}
Leider ist das ja so, dass man 5 Zeichen haben muss um "fortzufahren".
Es ist so, dass von einer Software Daten ausgegeben werden. Den Namen
der Variablen kann ich noch selbst festlegen z.b. p_brake . Ändert sich
dann der Zustand gibt die Software jeweils p_brake=0 oder p_brake=1 aus.
Zudem kann diese auch z.b. n_n=123.345 ausgeben und enstprechend dieser
ausgaben muss das arduino interagieren. Kann mir da mal einer auf die
Sprünge helfen weil in C bin ich noch nicht wirklich bewandert.
Danke
Peter L. schrieb:> A sorry hatte das falsche drin jetzt ist das was ich aus dem netz hab.
Jetzt weißt du auch, warum wir hier immer wieder sagen, dass man die
DINGE auch LERNEN muss. Code aus dem Internet kopieren und zu glauben
das reicht dann schon, ist einfach nicht genug. Um eine Herzoperation zu
machen reicht es einfach nicht sich auf Youtube 2 Videos zum richtigen
Aufkleben von Pflasteren anzusehen.
Stringoperationen sind eines der ersten zentralen Themen, die jeder
Programmierer im Schlaf beherrschen muss.
Und nein, der Ansatz aus dem geposteten Programm ist nicht tauglich. Da
fehlt es an einem ganz wesentlichen Punkt: es gibt kein vernünftiges
Protokoll um erst mal zuverlässig einen String zu haben, den man dann
mittels Stringoperationen zerlegen kann um rauszufinden, was die
Gegenstelle eingentlich mitteilen will.
> Leider ist das ja so, dass man 5 Zeichen haben muss um "fortzufahren".
Das ist aber nur so, weil es dieser Programmierer so gemacht hat. Im
allgemeinen ist das nicht so. Genau das nennt man dann ein Protokoll.
Dein anderes Programm wird ja nicht nur den Text
1
p_brake=0
senden, sondern da kommt üblicherweise noch ein Zeichen danach. Zb. ein
'\n', der anzeigt "Hier ist der Text jetzt zu Ende". Und genau dieses
Zeichen ist es, das dem Empfänger mitteilt: Jetzt ist der Text
vollständig - du kannst mit der Auswertung anfangen.
D.h. dein erstes Ziel ist es nicht, irgendwelche Vergleiche anzustellen,
sondern einfach nur mal den Text komplett und sicher aus dem
Eingabestrom herauszufischen. Dazu brauchst du dieses Terminierzeichen,
wie auch immer das in deinem Protokoll definiert ist.
Aber derartige Textübertragungen, die sich auf einer vorab bekannten
Anzahl von Zeichen stützen, sind Mist. Ein simples Kabel abstecken,
Kabel wieder anstecken bringt das alles durcheinander. Das ist nicht
tauglich. Das ist eben: "Ich kann ein Pflaster aufkleben - Schwester:
Knochensäge und Spreizer." So wird das nichts. Das ist Programmieren,
wie sich die kleine Erna vorstellt, dass Programmieren funktioniert.
Kaj schrieb im Beitrag #3683799:
> Peter L. schrieb:>> if ( !strcmp(inString, "start") )> Weißt du was da steht? Natürlich weißt du es nicht...> Da steht:>
1
>if(strcmp(inString,"start")!=0)
2
>
> Das heißt soviel wie: wenn der empfangene String nicht dem String> "start" entspricht, mach was.
Darüber sollten wir nochmal nachdenken, meinst du nicht, Kai?
Hab ne funktionierende Lösung hingekriegt dank eines netten Helfers
(nein nicht hier aus dem Forum). Dieser hat mir einiges Erklärt im
Gegensatz zu hier wo's einfach heißt "Kauf dir ein Buch..."
Darauf möcht ich auch nicht näher eingehen.
Hab jetzt eine andere Frage:
Wenn ich:
...."wert.substring(9,80);"...
mache dann erhalte ich als wert bei z.b.
tstfunc=1:
garnichts also nur leer. Habe ich aber einen längeren Wert z.b.
tstfunc=123456:
dann kommt als wert auch 12345 raus. Da es ja immer die 9. Stelle sein
wird wo die Zahlenfolge beginnt versteh ich nicht, dass wenn nur 1 steht
der wert "leer" ist und ab 2 Zahlen dann alles passt. Mit Substring sage
ich doch nur, dass ich die "Werte" ab Zeichen 9- xx in die andere
variable "speichern" möchte oder?
Hast du die Beschreibung der Funkion Substring gelesen?
http://arduino.cc/en/Tutorial/StringSubstring
Als Bemerkung steht da: "Caution: make sure your index values are within
the String's length or you'll get unpredictable results."
Und das ist bei dir dann wohl eingetreten
Peter L. schrieb:> Hab ne funktionierende Lösung hingekriegt dank eines netten Helfers> (nein nicht hier aus dem Forum). Dieser hat mir einiges Erklärt im> Gegensatz zu hier wo's einfach heißt "Kauf dir ein Buch...">> Darauf möcht ich auch nicht näher eingehen.
aber ich, in diesem Thread hat dir keiner gesagt "kauf dir ein Buch"
(was ein guter Tipp ist) sondern es gab mehrere Tipps zu deinem
Programm.
Wenn Dich hier die Leute nerven, warum fragst du dann nicht deinen
netten Helfer?
In deinem ersten Codestück gibt es übrigens einen Überlauf wenn weder
Start noch Stopp als String kommen
Ja mit 9 tritt das ein stimmt (Da hab ich die doch glatt überflogen...).
.substring(8);
Hatte das aber zufällig davor mit der 8 getestet weil ich mich vertan
habe, da ist dann wenn hinter dem = ne 1 steht auch beim Wert als
ergebnis die '1'. Habe ich jetzt aber '12345' hinter dem '=' so hab ich
jetzt aber das '=' mit im Ergebnis. Irgendwie hab ich n denkfehler oder
sowas...
Peter L. schrieb:> Hab ne funktionierende Lösung hingekriegt dank eines netten Helfers> (nein nicht hier aus dem Forum). Dieser hat mir einiges Erklärt im> Gegensatz zu hier wo's einfach heißt "Kauf dir ein Buch...">> Darauf möcht ich auch nicht näher eingehen.> Hab jetzt eine andere Frage:>> Wenn ich:>> ...."wert.substring(9,80);"...>> mache ...
Oh! Mein! Gott!
Du hast im Prinzip am Anfang des Threads recht vernünftig mit der
Verwendung von nullterminierten C-Strings angefangen (nur leider ohne
jegliche Ahnung vom Programmieren) und bist jetzt bei lahmen
String-Objekten gelandet.
OK, mann kann auch mit RAM-fressenden, lahmen und zur Standard-Library
inkompatiblen String-Objekten etwas programmieren. Ist allerdings
überhaupt nicht mein Fall, obwohl ich Arduinos programmiere. Denn das
Programmieren mit String-Objekten artet zu einem Alptraum aus, sobald Du
irgendwas machen möchtest, was von der handvoll
Arduino-Komfortfunktionen für String-Objekte nicht unterstützt wird.
Aber das verstehe ich trotzdem nicht:
> "Hab ne funktionierende Lösung hingekriegt"
und
> "wenn nur 1 steht der wert "leer" ist und ab 2 Zahlen dann alles passt"
Passt an der Lösung nun doch nicht alles?
Wenn nein, dann mache ich Dir mal folgendes Angebot:
Du schreibst mal beispielhaft und möglichst genau auf, was Du als
Kommandos wie senden möchtest, und ich mache Dir einen funktionierenden,
beispielhaften Sketch zur Auswertung mit dem Arduino.
Hi,
Nur damit ich auch mal was sage: Ich bin vor einiger Zeit auf das hier
gestoßen: http://playground.arduino.cc/Code/CmdMessenger und konnte die
Library bereits erfolgreich nutzen. Vielleicht kannst du ja auch was
damit anfangen.
Gruß
Also: ganz oben der Code vom Thread war nur aus dem Netz kopiert,
entsprach aber nicht dem was ich brauchte. Hab aber jetzt ne Funktion
gefunden wo mit Puffer,... gearbeitet wird (und auch verstanden) und die
funktioniert soweit top. Die Sache ist jetzt folgende: Es kommen Befehle
im Format p_brake=0:
an. p_brake ist nur beispiel, dieser "text" kann frei definiert werden.
Wenn nur logiken mit 0 und 1 (also hinter dem = ) kommen ist das ja kein
Thema weil da vergleiche ich einfach den Input mit dem was drinstehen
sollte. Kommt jetzt aber ein Wert ..=123.456 dann ist das ja nicht
wirklich umsetzbar. Dazu wollte ich einfach den Substringcode benutzen
um mir immer den hinteren teil auszugeben und zu verarbeiten (vor dem =
sind immer 7 stellen, ansonsten ginge das ja nicht)
Bsp:
p_brake=0: -> Irgendein Output springt auf 0 oder 1 oder sonst was.
tstfunc=127.432: -> z.B. Wert der auf 7-Seg. Angezeigt werden soll.
@Markus:
Werd ich mir mal anschauen. Danke.
Peter L. schrieb:> Bsp:>> p_brake=0: -> Irgendein Output springt auf 0 oder 1 oder sonst was.> tstfunc=127.432: -> z.B. Wert der auf 7-Seg. Angezeigt werden soll.
Codevorschlag für eine einfache Auswertung und zeitgleiches Blinken der
Pin-13 LED:
1
#define BLINKLED 13
2
3
voidcommandExecution()
4
{
5
#define BUFSIZE 21
6
charbuffer[BUFSIZE];// Maximale Stringlänge plus 1
7
if(!Serial.available())return;// kein Zeichen verfügbar, nichts machen
8
delay(100);// abwarten, bis kompletter Befehl empfangen wurde
Danke dir Jürgen wirklich tolle und Ressourcenarme Lösung die wirklich
sehr gut läuft. Das mit dem Auswerten ist jetzt wenn man's verstanden
hat relativ einfach. In C bin ich noch absolut grün, komm aber langsam
mit der syntaxstrucktur zurecht. Hatte vorher nur n bisschen Bascom
rumprogrammiert und sonst nur visualbasic am pc, ist halt eben ein
anderer syntax.
Danke!
Peter L. schrieb:> Das mit dem Auswerten ist jetzt wenn man's verstanden> hat relativ einfach.
Ich sehe übrigens gerade, dass die Empfangsroutine noch nicht ganz
narrensicher ist, änder mal die beiden Vergleichszeilen so ab, dass
verglichen wird, ob der gesuchte String auch wirklich am Anfang der
Zeile gefunden wird:
1
if(strstr(buffer,"p_brake=")==buffer)
2
und
3
elseif(strstr(buffer,"tstfunc=")==buffer)
Sonst wird z.B. ein ungültiger Befehl wie
xytstfunc=127.432:
falsch ausgewertet und nicht als ungültig erkannt.
> In C bin ich noch absolut grün, komm aber langsam> mit der syntaxstrucktur zurecht.
Es geht nicht nur um die Syntax, sondern auch um die Library.
Wenn Du unter Arduino programmierst, mußt Du Dir darüber im klaren
werden, dass Du nicht nur die "Arduino-Komfortbefehle" ("digitalWrite"
oder "Serial.read" etc.) zur Verfügung hast. Von diesen Komfortbefehlen
sind viele sogar so komplett vermurkst, dass man sie besser niemals
verwendet. Zum Beispiel alles, was mit String-Objekten zu tun hat.
Was Du außer den Arduino-Komfortfunktionen als Library zur Verfügung
hast, ist die AVR libc, Librarybeschreibung siehe:
http://www.nongnu.org/avr-libc/user-manual/modules.html
Und neben der C-Syntax ist es insbesondere diese Library, aus der Du ein
paar grundlegende Funktionen kennenlernen müßtest, um Deinen Controller
sinnvoll programmieren zu können.