Hiho,
bin noch ein Frischling was Arduino angeht. Ich würde gerne einen einfachen Taschenrechner über den seriellen Monitor ausgeben lassen. Bzw, es erstmal schaffen Zahlen anständig einlesen zu lassen.
Mit meinem Code dafür kommen die tollsten Sachen bei raus... Wenn ich eine 1 eingebe, liefert er mir eine 49 zurück und ich hab absolut keine Ahnung warum...
Wäre nett wenn jmd Abhilfe leisten könnte.
void setup(){
Serial.begin(9600);
}
void loop(){
int z = Serial.available();
if(Serial.available(){
z = Serial.read();
Serial.println(z);
}
}
Hiho zurück,
und willkommen im Forum.
Erstens:
Bitte fasse deinen Code in die entsprechenden Tags. Dazu gibt über dem Editor oben links das Symbol </> Dadurch werden deine Quelltexte für alle besser lesbar.
Zweitens:
Wenn du über den seriellen Monitor eine "1" sendest, wird lediglich das ASCII-Zeichen gesendet, welches für die Ziffer 1 steht. Dementsprechend kommt gemäß deinem Beispiel natürlich 49 zurück, was wiederum der ASCII-Code für 1 ist.
Und dann:
Ist der reine µC von Hause aus wenig intelligent. Du sagst ihm mit deinem Code lediglich: Nehme die Eingabe und sende sie zurück. Mehr nicht. Damit er anfängt zu rechnen, musst du jede Menge eigener Programmier-Arbeit dazwischen packen...
Nachsatz:
Wenn du statt "int" den Variablentyp "char" nimmst, dann bekommst du deine 1 auch an den Serialmonitor zurück. Nur mit "ASCII 49" wirst du nicht wirklich "rechnen" können. Heißt: Wieder umwandeln usw.
Erstmal vielen Dank für die kleine Einleitung,
nun, vergessen wir den Taschenrechner und konzentrieren uns auf das Einlesen, gibt es denn eine Möglichkeit über den seriellen Monitor eine Zahl 'korrekt' einlesen und ausgeben zu lassen?
Z.B mit parseInt oder so?
Warum den Taschenrechner vergessen? Das ist doch ein guter Aufhänger, denn ich bin gerade dabei so etwas ähnliches zu bauen - jedoch ohne Serialmonitor. Statt dessen mit einer 5x5 Tastenmatrix für die Eingabe und 20x4-Display für die Ausgabe.
Aber im Prinzip ist es vergleichbar: Was "eingelesen" wird - ist immer "irgendwie korrekt", es kommt nur darauf an, wie die Eingaben verarbeitet werden... Und hier habe ich keine Ahnung, wie gut du dich mit der Programmierung auskennst?? Ich bin selbst kein großer C-Experte - aber es gibt hier jede Menge Funktionen, die Eingaben konvertieren können (stoi, stol, stoul... um nur einige wenige zu nennen).
Hallo,
parseint braucht man dafür nicht. Du fragst die serielle ab ob was eingegangen ist. Dann liest du jedes Byte nacheinander in einen Buffer (Array). Und zwar so lange bis ein definiertes Endezeichen erkannt wird. Meistens der Null-Terminator. Oder ein eigens erstelltes eindeutiges Zeichen. Wenn fertig, kannste mit den Bytes in dem Buffer anstellen was immer du möchtest.
Meistens der Null-Terminator.
"Meistens" wird der Null-Terminator nicht mitgesendet ...
Ich sammle die Zeichen gerne in einem Puffer, benutze CR als Trennzeichen, ignoriere LFs und Leerzeichen oder Tabs am Zeilenanfang.
void setup() {
Serial.begin(115200);
Serial.println(F("Echo Zeilen (maximal 40 Zeichen lang)"));
}
void loop() {
serialHandler();
}
void verarbeiteEingabezeile(const char* iLine) {
Serial.print(F("Zeile '"));
Serial.print(iLine);
Serial.print(F("' als long "));
Serial.println(strtol(iLine, NULL, 0));
}
void serialHandler()
{
byte inChar;
bool doCheck = false;
const byte sCBMax = 41;
static char sCBuffer[sCBMax];
static byte buffIndex = 0;
while (Serial.available()) {
inChar = Serial.read();
if (inChar == 10) { // ignoriere LF
continue;
} else if (inChar == 13) {
doCheck = buffIndex;
} else {
if ((buffIndex == 0) && isWhitespace(inChar)) { // ignoriere Leerzeichen am Zeilenanfang.
continue;
}
sCBuffer[buffIndex++] = inChar;
doCheck = (buffIndex == (sCBMax - 1)); // terminiere wenn voll
}
if (doCheck) {
sCBuffer[buffIndex] = 0; // 0 hinter dem Text
verarbeiteEingabezeile(sCBuffer);
buffIndex = 0;
}
}
}
Echo Zeilen (maximal 40 Zeichen lang)
Zeile '1234567' als long 1234567
Zeile '0x123232' als long 1192498
Zeile '123456789' als long 123456789
Zeile '12345678901234567890' als long 2147483647