hallo,
ich habe folgenden Code:
********************************************
void loop() {
int farbe;
if(Serial.available()>0){
farbe=Serial.read();
Serial.println(farbe,DEC);
}
if(farbe==49){
digitalWrite(2,HIGH);
}
********************************************
Wenn ich nun z.b. die 1 eingebe, kommt wird beim seriellen Monitor die
49 angezeigt, wegen Ascii.
Wie mache ich es nun aber, dass er mir auch wirklich eine 1 anzeigt?
Integer ist doch eigentlich der richtige Datentyp.
easy-breazy schrieb:> Wenn ich nun z.b. die 1 eingebe
Du gibst aber nicht 1 ein. Du drückst die Taste, auf der '1' steht. Das
ist eine Taste, wie jede andere auch, wie zb die Taste, auf der 'A'
steht.
Nur weil dein Gehirn bei den Tasten mit den Ziffern automatisch eine
Zahl daraus macht, heisst das nicht, dass das eine wäre! Eine '1' ist
genauso ein "Buchstabe", wie es auch ein 'B' oder ein '#' ist. Jeder
"Buchstabe" hat einen Code (den ASCII Code) und der wird versendet, wenn
die Taste gedrückt wird.
> kommt wird beim seriellen Monitor die> 49 angezeigt, wegen Ascii.
ganz genau.
> Wie mache ich es nun aber, dass er mir auch wirklich eine 1 anzeigt?> Integer ist doch eigentlich der richtige Datentyp.
Das hilft dir nut nicht viel. Denn wenn du auf die Taste 'A' drückst,
dann wird der Code 97 versendet. Und das ist ja wohl auch ein Integer.
(Langer Rede kurzer Sinn: in einem Computer ist alles eine Zahl. Ein
Computer kann nur mit Zahlen operieren und mit sonst nichts anderem.
Aber man kann natürlich für bestimmte Zahlen eine Bedeutung vereinbaren.
Wie zb beim ASCII Code, der für Zahlenwert "Buchstaben" definiert, für
die diese Zahlen jeweils stehen sollen).
Aber: Da dein Computer ja mit Zahlen umgehen kann, kann er natürlich
damit rechnen oder aber auch Vergleiche damit anstellen
PS: wenn du in deinem Programm '0' schreibst, dann ist das auch nichts
anderes als eine Zahlenangabe. Der Compiler ersetzt '0' durch die
entsprechende Code Zahl aus dem ASCII Code.
Ob du
1
charc;
2
3
c='0';
4
c=48;
5
c=0x30;
schreibst, kommt alles aufs selbe raus. In die Variable c (die 1 Byte
gross ist), wird das Bitmuster 0011 0000 gespeichert. Alle Anweisungen
sind in diesem Sinne gleichwertig. Es sind nur unterschiedliche
Schreibweisen für immer dasselbe Bitmuster. Und je nach Zusammenhang
benutzt man dann die Schreibweise, die das gewollte am klarsten
ausdrückt. Da ich hier
1
farbe=nextCharacter-'0';
aus dem 'Buchstaben' (zb) '5' die Zahl 5 machen will, muss ich den ASCII
Code für '0' abziehen. Der ASCII Code für '5' wäre 53, der ASCII Code
für '0' wäre 48 und 53 - 48 ergibt die gewollten 5 (als Zahlenwert). Da
mich aber der ASCII Code für '0' überhaupt nicht interessiert und ich
mir den auch nicht merken will, schreibe ich nicht
1
farbe=nextCharacter-48;
sondern statt dessen eben
1
farbe=nextCharacter-'0';
und der Compiler setzt den korrekten ASCII Code für mich ein. Zudem ist
durch diese Schreibweise auch klarer, worum es hier geht. Bei den 48
würde ich mich sofort fragen: Warum 48? Wo kommen die her?
So aber, durch die Verwendung von '0' ist sofort klar, was hier das Ziel
der Übung ist.
@KarlHeinz, dass mit der Ascii-Tabelle und dass jede Taste einen
bestimmten Wert hat, habe ich eigentlich verstanden.
Allerdings bin ich es gewohnt in der Konsole zu programmieren und habe
deshalb gerade das ganze nochmal in Visual Studio ausprobiert.
+++++++++++++++++++++++++++++++++++++++
int farbe=0;
scanf("%d", &farbe);
printf("farbe:%d\n", farbe);
+++++++++++++++++++++++++++++++++++++++
dieser Code ist ja vergleichbar zu dem von meinem arduino, allerdings
gibt mir die Konsole nun auch eine 3 aus, wenn ich eine 3 eingebe.
Die Konsole würde mir bei einer 1 ja nur eine 49 geben, wenn ich als
Datentyp char ausgewählt hätte.
easy-breazy schrieb:> dieser Code ist ja vergleichbar
Irrtum.
Nein er ist nicht vergleichbar.
scanf macht schon die ganze Wandlung, die du am Arduino selbst machen
musst. Oder warum denkst du, musst du scanf das %d in der
Formatieranweisung angeben?
Wenn überhaupt, dann wäre das hier vergleichbar
1
intfarbe=0;
2
scanf("%c",&farbe);
3
printf("farbe:%d\n",farbe);
das entspricht noch am ehesten einem Serial.read
Aber eigentlich ist die noch bessere Übereinstimmung nicht der scanf,
sondern der getc()
easy-breazy schrieb:> Wenn ich nun z.b. die 1 eingebe, kommt wird beim seriellen Monitor die> 49 angezeigt, wegen Ascii.
Und genau das ist dann auch, was tatsächlich gesendet wird.
> Wie mache ich es nun aber, dass er mir auch wirklich eine 1 anzeigt?
Du bist ein Idiot, weil du nichtmal erkennst, was du eigentlich willst.
Du willst nicht, daß dir der "Monitor" (was auch immer das sein mag,
vermutlich irgendein Terminalprogramm) eine "1" (ASCII) anzeigt, du
willst vielmehr, daß es eine binäre 1 sendet. Was auch immer es für für
dieses sog. "nichtdruckbare" Zeichen (bzw. Steuerzeichen) auch anzeigen
mag...
Ja, fuck, das hängt einfach vom verwendeten Terminalprogramm ab und ggf.
der von diesem Programm aktuell verwendeten "Terminalemulation".
D.h.: Bevor du uns nicht mitteilst, wie dein Teminalprogramm heißt und
welche Terminalemulation du verwendest, kann dir niemand wirklich
weiter helfen...
Stimmt hast Recht. Kann man also sagen Serial.read liest immer ein char
ein?
Noch ein weiteres Problem:
++++++++++++++++++++++++++++++
switch(farbe){
case 49: digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
break;
case 50: digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,LOW);
break;
case 51: digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,HIGH);
break;
default: digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
}
++++++++++++++++++++++++++++++
Wenn man keine der 3 möglichen Zahlen eingibt, sollen alle Leds
ausgehen.
Allerdings macht mir hier das default Probleme(ohne dies funktionierts).
Wenn ich jetzt z.B. eine 1 eingebe, dass leuchtet led1 nur kurz auf und
geht direkt wieder aus.
Gibt es bei switch case beziehungsweise bei default einen Unterschied
zur Konsole? Sobald ich in cas 49 reingehe, sollte es ja garnicht mehr
in default reingehen.
@c-hater
Es gibt auch Leute, die einfach eine "schöne Ausgabe" haben wollen und
da nicht irgendwelche hohen Zahlen haben will, mit denen nicht jeder was
anfangen kann. Außerdem ist es eine Übung und da versucht man halt ein
bisschen zu probieren.
easy-breazy schrieb:> Stimmt hast Recht. Kann man also sagen Serial.read liest immer ein char> ein?
Weisst du, was mich an den Arduino Programmierern am meisten nervt?
Dass sie nicht in der Lage sind, ganz einfach mal die Doku zu lesen.
http://arduino.cc/en/Serial/read> Allerdings macht mir hier das default Probleme(ohne dies funktionierts).> Wenn ich jetzt z.B. eine 1 eingebe, dass leuchtet led1 nur kurz auf und> geht direkt wieder aus.
Ganzes Programm.
> Gibt es bei switch case beziehungsweise bei default einen Unterschied> zur Konsole?
Nein
Whrscheinlich hast du nur übersehen, dass du farbe nur dann ändern
darfst, wenn auch wirklich ein Byte über die Schnittstelle reingekommen
ist.
> Sobald ich in cas 49 reingehe, sollte es ja garnicht mehr> in default reingehen.
Tja.
Was tippst du denn sonst noch so für Tasten auf deiner Tastatur. Merke:
Auch ein 'Return' ist einfach nur eine Taste mit einem Code, der
versendet wird, wenn du die Taste drückst. Wenn du nicht haben willst,
dass dein Programm darauf reagiert, dann musst du das entsprechend
programmieren!
Und noch ein Tip:
Gerade am Anfang ist es oft eine gute Idee, wenn du dein Programm so
schreibst, dass es dir mitteilt was es getan hat oder was es von der
Schnittstelle bekommen hat.
1
...
2
if(Serial.available()>0){
3
charnextCharacter=Serial.read();
4
5
Serial.print("Nächstes Zeichen: (0x");
6
Serial.print((int)nextChar,HEX);
7
Serial.print(")"
8
Serial.println(nextChar);
9
10
if(nextCharacter>='0'&&nextCharacter<='9'){
11
farbe=nextCharacter-'0';
12
Serial.println(farbe,DEC);
13
}
14
}
Du hast ein Terminal zur Verfügung um dort Ausgaben machen zu können.
Benutze es!
Danke für eure Hilfe.
Wenn ich dies nun aber nicht mit Zahlen lösen möchte sondern mit "text",
wie funktioniert dies? Wenn ich red eingebe soll die rote led leuchten.
Ich weiß aber nicht, wie ich z.B. red einlesen lassen kann.
easy-breazy schrieb:> Danke für eure Hilfe.>> Wenn ich dies nun aber nicht mit Zahlen lösen möchte sondern mit "text",> wie funktioniert dies? Wenn ich red eingebe soll die rote led leuchten.>> Ich weiß aber nicht, wie ich z.B. red einlesen lassen kann.
1
'r' 'e' 'd' '\n'
2
^
3
|
4
Return deswegen, damit dein Programm erkennen kann
5
wann deine Eingabe fertig ist. Du könntest ja auch
6
das Wort redundant tippen.
4 Tastendrücke. 4 character die aus der Seriellen SChnittstelle
rauskommen.
In einem String (zb in einem char-Array) sammeln und wenn der \n
angekommen ist, weisst du, dass der String vollständig ist. und dann
ganz normale Stringauswertung. So wie du das auf deinem Desktopsystem
auch machen würdest. strcmp lässt grüßen.
Du denkst ein bischen zu viel Desktop!
Hier ist alles viel simpler. 1 Tastendruck ergibt ein Zeichen, dass auf
Arduino Seite aus der Seriellen rauspurzelt. Darauf aufbauend musst du
den Rest selber machen. Wie zb. solange Zeichen sammeln, bis du weisst,
dass eine Zeile fertig übertragen wurde, und dann mit dem gesammelten
etwas machen. Das was der scanf erledigt, musst du hier selber machen.