Hi,
hab hier einen von jurs umgebauten Sketch, der mir nicht das zurückgibt, was ich gerne hätte.
Wenn ich dem Sketch z.B. seriell den String "d000056" sende, bekomme ich nicht die Zahl 56 zurück.
Das Ziel ist es nämlich lediglich das 'd' und sämtliche Nuller vor der eigentlich zu extrahierenden folgenden Zahl abzuschneiden.
Leider komme ich nicht darauf, was das Problem sein könnte.
Zudem gefällt mir folgende Zeile nicht:
if (i == 9) i = 0;
Da gibt es was mit "sizeof (commandbuffer)", ich komme aber nicht mehr drauf wie es geht.
Gruß Chris
void setup()
{
Serial.begin(9600);
}
void loop()
{
lesevorgang();
}
void lesevorgang()
{
static char commandbuffer[10];
static char c;
static int i = 0;
if (Serial.available())
{
c = Serial.read();
commandbuffer[i] = c;
i++;
if (i == 9) i = 0;
if (c == 10) // Linefeed
{
Serial.println(getIntFromString (commandbuffer, 1)); // Ausgabe der ermittelten Zahl
i = 0;
memset(commandbuffer, 0, sizeof(commandbuffer)); // Puffer mit Nullbytes fuellen und dadurch loeschen
}
}
}
int getIntFromString (char *stringWithInt, byte num)
{
char *tail; // Zeiger
while (num > 0)
{
num--; // Nicht-Zahlen überspringen
while ((!isdigit (*stringWithInt)) && (*stringWithInt != 0)) stringWithInt++;
tail = stringWithInt; // Zahlen finden
while ((isdigit(*tail)) && (*tail != 0)) tail++;
if (num > 0) stringWithInt = tail;
}
return (strtol(stringWithInt, &tail, 0));
}
void setup() {
Serial.begin(9600);
}
void loop() {
lesevorgang();
}
void lesevorgang() {
static char commandbuffer[10];
static int i = 0;
char c;
if (Serial.available()) {
c = Serial.read();
commandbuffer[i] = c;
if (c == 10) {
commandbuffer[i] = 0;
Serial.println(atoi(commandbuffer + 1));
i = 0;
} else if (c == 13) { // cr ignorieren
} else if (++i == sizeof(commandbuffer) - 1) {
i = 0;
}
}
}
Danke, doch das scheint das Problem nicht zu lösen.
Seriell senden tu ich übrigens immer mit abschließendem CR und LF.
Gruß Chris
Hast du es schonmal mit Serial.parseInt() probiert?
Das scheint mir einfacher zu sein.
void lesevorgang() {
if (Serial.available()) {
int val = Serial.parseInt();
Serial.println(val);
}
}
Ich fand einen Fehler im Lesevorgang und habe ihn behoben.
Komischerweise bekomme ich, wenn ich z.B. "d07" schicke eine 7 zurück.
Schicke ich jedoch "d08" bekomme ich eine 0 als Ergebnis.
Das verstehe ich nicht.
Gruß Chris
Hier der aktualisierte Code:
void setup()
{
Serial.begin(9600);
}
void loop()
{
lesevorgang();
}
void lesevorgang()
{
static char commandbuffer[10];
static char c;
static int i = 0;
if (Serial.available())
{
c = Serial.read();
commandbuffer[i] = c;
i++;
if (i == sizeof(commandbuffer)) i = 0;
if (c == 10) // Linefeed
{
Serial.println(getIntFromString (commandbuffer, 1)); // Ausgabe der ermittelten Zahl
i = 0;
memset(commandbuffer, 0, sizeof(commandbuffer)); // Puffer mit Nullbytes fuellen und dadurch loeschen
}
}
}
int getIntFromString (char *stringWithInt, byte num)
{
char *tail; // Zeiger
while (num > 0)
{
num--; // Nicht-Zahlen überspringen
while ((!isdigit (*stringWithInt)) && (*stringWithInt != 0)) stringWithInt++;
tail = stringWithInt; // Zahlen finden
while ((isdigit(*tail)) && (*tail != 0)) tail++;
if (num > 0) stringWithInt = tail;
}
return (strtol(stringWithInt, &tail, 0));
}
combie
February 17, 2017, 12:34pm
6
Das verstehe ich nicht.
Dann mache dich bitte mit dem Oktalsystem vertraut.
Chris72622:
Danke, doch das scheint das Problem nicht zu lösen.
Seriell senden tu ich übrigens immer mit abschließendem CR und LF.
Das ist natürlich quatsch, weil ich Kode teste, ehe ich ihn poste.
Deine Fehler liegen in dem Kode, der atoi() versucht nachzustellen.
Nimm
return strtol(stringWithInt, NULL, 10);
Hi,
anbei die Lösung für die Nachwelt. Danke nochmals allen geduldigen Mitlesern.
Sollte es bzgl. der Codegröße noch Einsparpotenzial geben, bitte!
Gruß Chris
void setup()
{
Serial.begin(9600);
}
void loop()
{
lesevorgang();
}
void lesevorgang()
{
static char commandbuffer[10];
static char c;
static int i = 0;
if (Serial.available())
{
c = Serial.read();
if (c != '\r')
{
commandbuffer[i] = c;
i++;
if (i == sizeof(commandbuffer)) i = 0;
}
if (c == 10) // Linefeed
{
// Serial.print(commandbuffer);
Serial.println(getIntFromString (commandbuffer, 1)); // Ausgabe der ermittelten Zahl
i = 0;
memset(commandbuffer, 0, sizeof(commandbuffer)); // Puffer mit Nullbytes fuellen und dadurch loeschen
}
}
}
unsigned long getIntFromString (char *stringWithInt, byte num)
{
char *tail; // Zeiger
while (num > 0)
{
num--; // Nicht-Zahlen überspringen
while ((!isdigit (*stringWithInt)) && (*stringWithInt != 0)) stringWithInt++;
tail = stringWithInt; // Zahlen finden
while ((isdigit(*tail)) && (*tail != 0)) tail++;
if (num > 0) stringWithInt = tail;
}
return strtoul(stringWithInt, NULL, 10);
}
Also bei mir funktioniert das nicht.
(Mega2560; IDE 1.8.1; Serieller Monitor)
Wogegen das hier funktioniert:
void loop() {
if (Serial.available()) {
int val = Serial.parseInt();
Serial.println(val);
}
}
agmue
February 18, 2017, 10:01am
12
Nur so Ideen:
In getIntFromString lese ich "Nicht-Zahlen überspringen". Das könntest Du auch in lesevorgang machen (ungetestet):
void lesevorgang()
{
static char commandbuffer[10];
static char c;
static int i = 0;
if (Serial.available())
{
c = Serial.read();
switch (c)
{
case '0' ... '9':
commandbuffer[i] = c;
i++;
if (i == sizeof(commandbuffer)) i = 0;
break;
case '\n':
// Serial.print(commandbuffer);
Serial.println(getIntFromString (commandbuffer, 1)); // Ausgabe der ermittelten Zahl
i = 0;
memset(commandbuffer, 0, sizeof(commandbuffer)); // Puffer mit Nullbytes fuellen und dadurch loeschen
break;
}
}
}
Durch die positive Abfrage kommt '\n' nicht in den Puffer.
Chris72622:
Sollte es bzgl. der Codegröße noch Einsparpotenzial geben, bitte!
Dein Kode
Der Sketch verwendet 2.770 Bytes (1%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 201 Bytes (2%) des dynamischen Speichers, 7.991 Bytes für lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.
mein Kode
Der Sketch verwendet 2.170 Bytes (0%) des Programmspeicherplatzes. Das Maximum sind 253.952 Bytes.
Globale Variablen verwenden 198 Bytes (2%) des dynamischen Speichers, 7.994 Bytes für lokale Variablen verbleiben. Das Maximum sind 8.192 Bytes.
Meinst Du mit "mein Kode" das hier?
void lesevorgang()
{
static char commandbuffer[10];
static int i = 0;
char c;
if (Serial.available()) {
c = Serial.read();
commandbuffer[i] = c;
if (c == 10) {
commandbuffer[i] = 0;
Serial.println(getIntFromString (atoi(commandbuffer + 1), 1));
i = 0;
} else if (c == 13) { // cr ignorieren
} else if (++i == sizeof(commandbuffer) - 1) {
i = 0;
}
}
}
Falls ja funktioniert das bei mir so nicht.
Gruß Chris
Bei mir schon.
P.S.
Chris72622:
Falls ja funktioniert das bei mir so nicht.
[SARCASM]
Tolle und unglaublich detailierte Fehlerbeschreibung.
[/SARCASM]
Die serielle Eingabe meinerseits führt bei dem von mir angegebenen Code nicht zur gewünschten Ausgabe.
Gruß Chris
Chris72622:
Die serielle Eingabe meinerseits führt bei dem von mir angegebenen Code nicht zur gewünschten Ausgabe.
Das ist genauso nichtssagend.
Wenn ich die Eingabe d000056 (Zeilenende: Sowohl NL als auch CR, 9600 Baud) mit dem Knopf Senden sende,
gibt das Programm wunschgemäß 56 aus.
void setup() {
Serial.begin(9600);
}
void loop() {
lesevorgang();
}
void lesevorgang() {
static char commandbuffer[10];
static int i = 0;
char c;
if (Serial.available()) {
c = Serial.read();
commandbuffer[i] = c;
if (c == 10) {
commandbuffer[i] = 0;
Serial.println(atoi(commandbuffer + 1));
i = 0;
} else if (c == 13) { // cr ignorieren
} else if (++i == sizeof(commandbuffer) - 1) {
i = 0;
}
}
}
56
Ich glaube, ich hab das Problem gefunden. Atoi funktioniert nur mit Integer, oder?
Ich benötige in diesem Fall die Rückgabe (noch) größerer Zahlen.
Gruß Chris
combie
February 19, 2017, 2:10pm
19
Atoi funktioniert nur mit Integer, oder?
Es kann doch nicht sein, dass du nach weit über 1000 Postings immer noch nicht in die Doku schaust...
Wie kann ich dir dabei helfen, dir solche Fragen selber zu beantworten?
Ich benötige in diesem Fall die Rückgabe (noch) größerer Zahlen
Es kann doch nicht sein, dass du nach weit über 1000 Postings immer noch nicht in die Doku schaust...
Wie kann ich dir dabei helfen, dir solche Fragen selber zu beantworten?
Immer noch keine konkrete Angabe.
So sollte es auch mit großen Zahlen (bis ca 2100000000) gehen.
void setup() {
Serial.begin(9600);
}
void loop() {
lesevorgang();
}
void lesevorgang() {
static char commandbuffer[20];
static int i = 0;
char c;
if (Serial.available()) {
c = Serial.read();
commandbuffer[i] = c;
if (c == 10) {
commandbuffer[i] = 0;
Serial.println(strtol(commandbuffer + 1, NULL, 10));
i = 0;
} else if (c == 13) { // cr ignorieren
} else if (++i == sizeof(commandbuffer) - 1) {
i = 0;
}
}
}
Eingabe von d0001234567899 ergibt
1234567899