hi,
a very mysterious effect makes me troubles.
For debugging I inserted an sprintf() statement in my sketch, reusing a string which is available for that purpose. The relevant parts of my sketch:
----> Daten an Server
wmean=2708 wmin=0 wmax=21024 vardir=0 wdir=9OK/Programm: VoiceSMSClientDisplay.ino
From the output the part "K/" I dont know the origin.
But the part "Programm: VoiceSMSClientDisplay.ino" is an output from the setup() function of the sketch, i.e. a reset has occurred.
After commenting the two lines with the sprintf() statement the program continues as it should do.
The length of the string within msgtxt[] is much less than the maximum possible 160 characters.
The whole sketch is quite large. It is a GSM application checking phone calls and SMS, reading wind data from a wind sensor via HW Serial (RFrec) and sending some data to a server.
Here is the final part of loop():
#define SMS_LEN 160
word wmean, wmin, wmax;
byte wdir;
byte pos_sms_rx;
...
char msgtxt[SMS_LEN];
...
setup() {
...
}
loop() {
// the first part of loop() contains checking if a phone call came in and if an SMS was received.
...
// check if Winddata are available:
wanz=0;
while (RFrec.available()) { // Daten sind angekommen, evtl. bereits mehrere
// WxxxRxx<CR> oder TxxxxHxx<CR>
newdat=true;
c=RFrec.read(); Serial.print(c);
msgtxt[wanz++]=c;
while (c > 31) { // immer (nur) einen ganzen Datensatz einlesen
if (RFrec.available()) {
c=RFrec.read();
msgtxt[wanz++]=c;
// Serial.print(c);
}
}
msgtxt[wanz]=0; // String abschliessen
// Message interpretieren:
if (msgtxt[0] == 'W') { // Winddaten in Ringpuffer legen
wmean=atoi(&(msgtxt[1]));
wdir=atoi(&(msgtxt[5]));
storeWDat(wmean, wdir); // store data in a ring buffer, schaltet rbuf_idx weiter
dispWindData(); // display data on epd-display
}
else {
if (msgtxt[0] == 'T') { // Temperaturdaten abspeichern
temp_act=atoi(&(msgtxt[1]));
rh_act=atoi(&(msgtxt[6]));
}
else Serial.println(F("unbekannte Daten vom Funkempfaenger!!"));
}
wanz=0;
} // while (RFrec.available())
if (newdat) epd_update();
newdat=false;
// check if data shall be sent to server:
if ((millis()-t_gprs) > 300000) { // alle 5 Minuten
// Serial.print(millis());
if (SerMonitor)
Serial.println(F("----> Daten an Server"));Serial.flush();
t_gprs=millis();
// 5 Minuten enstspr. ca. 19 Messdaten
wdir = getServerData(19, 19, &wmean, &wmin, &wmax, &pos_sms_rx); // die letzten 19
sprintf(msgtxt,"wmean=%d wmin=%d wmax=%d vardir=%d wdir=%d", // here is the problem ..
wmean, wmin, wmax, pos_sms_rx, wdir); //.. causing the reset!!!
// deactivating/commenting the sprintf() statement results in perfect operation
Serial.print(msgtxt);Serial.flush();
stat = inet.setupGPRSConnection();
if (stat < AT_RESP_OK) { // -1, 0, 1, noch ein Versuch
inet.closeBearer();
delay(100);
gsm.InitParam(PARAM_SET_0);
delay(100);
gsm.CheckRegistration(); // hier wird auch PARAM_SET_1 aktiviert
delay(100);
stat = inet.setupGPRSConnection();
}
if (stat == AT_RESP_OK) {
delay(100);
if (inet.sendHTTPdata(wmean, wmin, wmax, wdir, temp_act, rh_act) == 1) {
delay(100);
rsp=inet.closeBearer();
if (SerMonitor) {
Serial.print(F("link closed with "));
Serial.println(rsp);
}
msg_cnt++;
}
else {
if (SerMonitor) Serial.println(F("sendHTTPdata() failed"));
fail_cnt++;
}
}
else {
if (SerMonitor) Serial.println(F("setupGPRSConnection() failed"));
fail_cnt++;
}
Serial.print(F("OK/fail: "));Serial.print(msg_cnt);
Serial.print("/");Serial.println(fail_cnt);
}
} // loop
The code is large for posting. But the code runs on an Arduino Mega2560 which has sufficient flash and RAM:
Sketch uses 26,700 bytes (10%) of program storage space. Maximum is 253,952 bytes.
Global variables use 4,387 bytes (53%) of dynamic memory, leaving 3,805 bytes for local variables.
I just made a further test, replacing the sprintf() by Serial.print()'s:
I replaced
You're more than likely having memory issues. Any variable that is not declared globally will add to memory usage at occasion, nested function calls will add, recursive functions are a nearly certain death unless you know what your doing and so on.
SupArdu:
well, lack of RAM is what I suspected too. On the other hand a lot of RAM is available.
Are you taking about flash memory or SRAM. I usually run out of SRAM long before I run out of flash memory. I've had situations where the compiler tells me I've only used 70% of SRAM and only 50% of flash, but the program crashed. The reason is because SRAM stores all of the data. Your F macro prevents duplicating strings and can help, but may not save the day. Don't forget that the figures given after a compile are static numbers. When the program runs, data are pushed and popped as functions come and go...the stack ebbs and flows. I ebbed and flowed right out of a Nano and into a Mega 2560.
Something in your code is stomping over memory that doesn't belong to it.
The part of the sketch that you have shown us seems to be working perfectly fine. You build and print "wmean=2708 wmin=0 wmax=21024 vardir=0 wdir=9O" and it gets printed just great.
Obviously, something is printing "K/Program" (etc). What might that be? How could I possibly know? I'd have to pepper your code with log statements to work out what is going in. (TIP: check out the C++ FILE and LINE preprocessor macro.)
If the problem is as you describe it, then you are looking at many, many long and fruitless hours chasing down the errant line of code that writes one byte past the end.
If you are using many, many libraries that you found lying unmaintained in github repos, then you may never find the errant line of code.
It could be something obvious with one line of code.
It could be something that you are doing everywhere, and you need to rework all your code.
Or maybe the reason it blows up after that particular printf is that you lean over to your monitor to read it, and your chair leg is on top of the power supply cable to the aduino.