ich versuche gerade, über die serielle Schnittstelle meines Arduino Nano über Putty Ein- und Ausgaben zu tätigen, hier erstmal mein Sketch (heruntergebrochen auf das nötigste):
#include <EEPROM.h>
int interval = 5000; //Counter refresh and save interval
long counter;
char serialinput;
String valueString;
bool serialBlock = false;
unsigned long time_now = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(Serial.available())
{
Serial.setTimeout(15000);
serialinput = Serial.read();
if (serialinput == 's')
{
Serial.println("Please enter a new counter value to start with: ");
serialBlock = true;
valueString = Serial.readStringUntil('s');
long received = atol(valueString.c_str());
if (received > 0)
{
counter = received;
Serial.println("received and saved: " + counter);
}
else
{
Serial.println("received 0, not saving ");
}
serialBlock = false;
}
}
if (serialBlock == false)
{
if(millis() > time_now + interval)
{
time_now = millis();
Serial.println(counter);
}
}
}
Wenn ich das Ausführe und mit s in den Editir-Modus gehe, einen Wert eingebe, und wieder s drücke um den Editiermodus zu verlassen, erhalte ich oft (nicht immer) ein Zeichenwirrwar auf der Konsole:
0
0
0
0
Please enter a new counter value to start with:
▒Wz▒~▒▒▒u▒▒▒z▒wγ~▒▒▒[▒▒g▒y▒▒v▒▒▒~B▒~▒▒▒▒▒▒▒5▒z▒g|▒▒▒S▒W▒▒▒▒▒7▒_7▒▒▒▒͏a▒▒▒G▒}f}▒Wx▒▒՛▒▒J▒;▒▒kR▒Gx▒▒_▒▒ޟ▒{~▒▒▒_=▒▒▒o▒9▒▒g▒\ݩ▒▒پ{▒▒▒o_▒ Rw▒{▒▒~▒▒▒▒▒▒ݥ▒▒▒O▒▒▒▒▒Gν▒▒;▒▒;▒▒?▒▒▒m▒▒▒Ҙ▒ֽ_▒▒▒W▒o:3
▒▒▒▒▒▒▒▒▒▒_W<?▒u▒▒▒▒-▒▒_▒▒▒߰o▒▒▒▒vv▒▒߿▒▒▒.▒▒8▒~X▒
▒▒▒Čw▒▒▒▒?▒▒▒▒▒j▒k▒▒'▒_▒▒▒▒yQ▒2c=/B▒▒~ԍn?▒▒▒▒Z/▒▒▒;p
▒▒߳▒3▒}▒▒▒L3▒▒.՞r▒V▒PMo▒2▒▒彛▒▒▒L▒▒۷V:▒▒▒D▒▒˛▒▒ԻS.]▒,▒BS6▒▒▒s▒▒▒uO▒▒▒▒▒J;▒▒Jf▒2▒Ϧfi▒▒▒ew??▒▒▒▒}▒▒▒▒v▒▒,ڣ▒▒▒▒▒▒▒▒wwuƌ▒▒wn▒cL▒▒r▒▒▒q▒▒▒O▒d▒▒▒y▒L▒▒▒W▒▒▒$▒Zy7▒}▒{▒▒▒^̙▒s▒z6▒}▒lM▒▒▒N:▒3▒▒▒Y~▒▒▒▒^▒_w▒▒{]▒▒<▒▒a▒-▒▒▒▒▒Վvu▒▒"▒▒n▒▒▒ڭjt2▒W▒▒▒▒^G▒|▒▒▒>▒z)▒▒▒i▒▒▒▒▒▒▒d▒▒㿺▒▒w▒n▒▒▒^▒▒r^▒S▒i▒▒F▒#▒=▒-▒▒[▒▒T▒D|n▒▒Z▒▒?Oܷu▒▒▒▒▒j▒t}▒zBk▒▒gy▒͔r+▒-1▒▒▒▒▒[糮▒▒▒▒}▒0b▒]▒▒▒▒▒▒▒▒
ٞ7▒▒▒▒=▒▒▒▒C▒▒▒ztq▒▒߿▒{▒▒▒▒k▒m▒▒▒O▒▒^▒&8j▒▒▒▒-▒~▒y▒%▒▒▒▒▒▒▒▒▒_▒▒▒ݱ'?▒▒▒▒+▒▒߭▒[▒▒▒ퟻ|}Y▒v▒▒oy▒▒▒▒▒=▒9▒▒▒~▒5▒▒W▒▒cyҝP▒eͿ▒▒▒▒X_▒▒▒▒+7
546456464
Okay, ich habe aufgrund deines Minimalbeispiels noch nicht verstanden wo ich einen Überlauf habe, auch werden mir in der IDE keine Warnings beim Kompilieren angezeigt, muss man die irgendwo aktivieren?
Sinn und zweck des Ganzen ist in der laufenden Loop durch drücken einer Taste (in meinem Beispiel 's') die Verarbeitung anzuhalten, einen Wert einzulesen (long) und eine interne Variable damit zu beschreiben, wobei die EIngabe mit 's' abgeschlossen wird. Man hätte auch \n nehmen können, ich habe aber das Problem dass unter verschiedenen Termionalprogrammen unter Linux und Windows beim Drücken der Eingabetaste verschiedene Carriage Returns gesendet werden, mal \n, mal \r, mal beides, also pragmatischer Ansatz: nimm halt s
Okay, jetzt sehe ich klarer wo das Problem ist. Lösungsansatz:
Serial.println("received and saved: " + (String)counter);
Gab's da nicht auch irgendwas mit Format-Modifieren (in der Art "Der Wert %l wurde gelesen", counter), ich finde da nur die korrekte Syntax gerade nicht
Die String-Klasse soll, so habe ich in diesem Forum gelesen, zu ungenutzten Speicherlücken führen, die wegen das geringen Speichervolumens des ATmega328 zu Laufzeitfehlern führen können. Wenn Du für String-Variablen Speicherplatz vorab reservierst, soll es besser sein.
Aber auch nur "ungefähr"!
In diesem Fall nur fürchterlich "unschön", aber kein Fragmentierungsproblem.
Die Stringinstanz, bzw. beide werden lokal erzeugt und wieder dekonstruiert.
Verschwinden also folgenlos.
Ist nur unsinnig kompliziert! Serial.println("received and saved: " + (String)counter);
Es werden 2 String Instanzen erzeugt.
incl. 3facher Speicherreservierungsorgie
Besser wg. viel sparsamer: Serial.print(F("received and saved: ")); Serial.println(counter);
Oder wie bei mir üblich: cout << F("received and saved: ") << counter << endl;