Ich beschäftige mich seit kurzem mit einem Arduino und möchte einen Potentiometer einlesen diese infos Seriel über eine drahtlose Verbindung zum Empfänger Arduino schicken und dort ein Servo ansteuern.
Die Daten kommen auch beim Empfänger an und ich kann sie dort über die serielle Schnittstelle auslesen nur kommen hier die infos als ASCII-Code an.
Wie kann ich nun diesen ASCII-Code wieder in eine Dezimalzahl umwandeln?
53 -> 5
51 -> 3
50 -> 2
13 -> CR
10 -> LF
Wenn die 13 empfangen wird ist die Übertragung beendet und die davor gesendeten Daten sollen zu einer Dezimalzahl zusammengesetzt weden um sie mittels map() an den Ausgang weiter zu geben.
Einmal in ein Array einlesen und dann per atoi() (ascii to integer) Konvertieren. Oder direkt die Ziffern aufaddieren.
Wenn man nur Zahlen will reicht das zweite, aber Text einlesen braucht man an vielen Stellen. z.B. auswerten von Kommandos oder wenn man Text + Zahlen hat
Doc_Arduino:
wenn es nur um die Zahlen geht, einfach -48 rechnen.
Du meinst sicher "Ziffern im Text"
Liegt daran, dass die Ziffer '0' den Code 48 hat.
48 braucht sich übrigens keiner zu merken, nur dass alle 10 Ziffern-Zeichen direkt hintereinander liegen und '0' die kleinste ist.
'5' - '0' == 5
char c = Serial.read();
if ( c >= '0' && c <= '9') {
int zahl = c - '0'; // oder auch -48;
}
Bei mehreren Ziffern einfach alt * 10 + neu.
unsigned long readDecimalUntilCR() {
unsigned long value = 0;
while Serial.available() {
char c = Serial.read();
delay(1); // damit bei 9600 Bd auch alle Zeichen zusammen ankommen
if ( c >= '0' && c <= '9') {
value = value*10+ c - '0';
}
return value;
}
Das erste Zeichen, das keine Dezimalziffer ist, beendet den Lesevorgang und ist auch weg.
Habe mich heute drüber gemacht und hab an dem Beispiel von michael_x am meisten verstanden.
@ Serenifly: das mit dem atoi() hab ich leider nocht ganz verstanden, steh wohl auf dem Schlauch.
Folgendes ist dabei raus gekommen:
int Regler = 0;
#include <SoftwareSerial.h>
// XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX)
// XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX)
SoftwareSerial XBee(2, 3); // RX, TX
void setup() {
Serial.begin(9600);
XBee.begin(9600);
}
void loop() {
if (XBee.available()) {
char ascii = XBee.read();
delay(5);
if (ascii >= '0' && ascii <= '9') {
Regler = Regler * 10 + ascii - 48;
}
else if (ascii == 13) {
Serial.println(Regler);
Regler = 0;
delay(100);
}
}
}
Anfangs passt noch alles und ich bekomme den ADC Wert sauber ausgegeben nur dann verhaut er sich (siehe Bild).
Strings in C sind Null-terminierte char Arrays (nicht zu verwechseln mit der Arduino String Klasse). atoi() nimmt einen solchen String und liefert einen signed int.
Also entweder man liest erst einen C String ein und macht dann atoi(), oder man addiert die Ziffern auf.
Die readSerial() Funktionen aus dem meinem Link gehen auch mit SoftwareSerial
Was ist mit anderen Zeichen ?
Die lassen Regler unverändert und machen sonst nichts, eigentlich. Aber wenn xbee 2 Zahlen kriegt: "LF 513 irgend was 419 CR " kommt 513419 oder als int16 -10869 raus.
LF sollte auch erwartet sein und nichts machen. Alles andere solltest du mindestens testweise anzeigen.
Regler als unsigned long zu deklarieren, schützt auch vor nicht erwartetem Überlauf.
Sollte xbee immer nur eine Zahl 0 ... 1023 empfangen? Evtl. auch die Anzahl Zeichen seit dem letzten mitzählen ...