Re-uploading sketch EVERY time after restart??

Hello All,
my Arduino Nano interacts with a PC (listens to the PC via serial and performs some jobs). Works fine. However, after every shutdown (not graceful, because I have to stop execution by switching off the power) Arduino stops performing SOME jobs (some, because it does the thirst thing, but doesn't the rest). Looks like the flash memory gets corrupted somehow. If I re-upload the sketch (using IDE or directly by avrdude from the command prompt) everything starts working normally again. Did anyone experience similar behavior? Any advices?
I can think only of re-uploading the hex file from the PC program using system(), but this is not nice.
Thanks for any tips.

Cheers,
Yuri

Hi Yuri

Please post your Arduino code. Use code tags (the </> button on the toolbar above the reply window).

Arduino stops performing SOME jobs (some, because it does the thirst thing, but doesn't the rest)

Can you give more details of what the Nano does and does not do?

Is the Nano powered from the PC? So, when the PC powers down, the Nano is turned off also?

Regards

Ray

Hello Ray,
yes, Nano is powered from the PC, so when the power is switched off, Nano dies ungracefully too. I forgot to add that if the PC is shutdown gracefully, Nano still requires re-upload, so the problem does not seem to be in ungracefulness...
The code is too large to be included as a whole, but the essence is:
....
if(Serial.available()) {
delay(100);
while(Serial.available()>0) {
inByte - Serial.read();
if(inByte==LogoSign) {
<>
} else if(inByte==SpectrumSign) {
<< read next N characters, interpret them as integers and display certain graph>>
} else if(inByte==TextSign) {
<< read next N characters, interpret them as text and display on LCD as text>>
}
.....
}
}
....

Nano does not send anything back to PC.

Cheers,
Yuri

The code is too large to be included as a whole, but the essence is:

Use Reply, not Quick Reply. Below the text entry area, there is a link, Additional Options. Under that, there is a way to attach your code. I doubt that you really have this in your code:

inByte - Serial.read();

If you do, that is useless.

Sorry - I'm new to this forum.
Of course there is a "=", not "-"...
I have attached the whole code here.
As I said, it works fine AFTER re-upload.

Cheers,
Yuri

LogoTextSpectrumTempUROSS2.ino (12.1 KB)

    while(Serial.available()>0) {
        // display each character to the LCD
        inByte = Serial.read();

        if(inByte==LogoSign) { // '!'
            tft.setRotation(3);
            bmpDraw("CCOM.bmp", 0, 0);
        } else if(inByte==LogoReadySign) { // '%'
            tft.setRotation(3);
            bmpDraw("READY.bmp", 0, 0);
        } else if(inByte==SpectrumSign) {  // '#'
            // Next 150 characters contain scaled spectrum data
            for(int i = 0; i<150; i++) {
                v[i] = Serial.read();
            }

Garbage! If there is at least one byte of serial data, it is NOT okay to read 150 bytes.

"Garbage! If there is at least one byte of serial data, it is NOT okay to read 150 bytes."

Why? The PC sends 151 chars ('#' and 150 bytes of data), so when '#' arrives to Nano, it KNOWS exactly how many bytes follow.
Besides, if there would be anything wrong with it, it wouldn't work WITH re-upload as well as without.

Yuri

Why? The PC sends 151 chars ('#' and 150 bytes of data), so when '#' arrives to Nano, it KNOWS exactly how many bytes follow.

It knows how many bytes ARE TO FOLLOW. The number returned by Serial.available() is how many bytes HAVE ARRIVED. The number of bytes that have arrived and the number that are to arrive are NOT the same. They can't possibly be, since the serial data buffer can only hold 64 bytes.

Besides, if there would be anything wrong with it, it wouldn't work WITH re-upload as well as without.

Obviously this statement is not true.

Sorry, the logic still evades me. Once something is available and it happens to be '#', Nano doesn't check for availability any more, it just reads next 150 bytes. Is it wrong to assume that there are 150 following bytes? Only after the consumption of this data block the control is returned to while(), to check whether anything is still available.
How else this processing can be achieved?

Yuri

Is it wrong to assume that there are 150 following bytes?

Yes, it is. If Serial.available() tells you that there are 22 bytes to be read, does reading 150 bytes make any sense? The last 128 will be -1. Then, you'll have to wait for the remaining bytes to arrive and be discarded.

You need to read and store the bytes AS THEY ARRIVE, until you have read and stored all 150 bytes. You can NOT assume that slowly arriving serial data will arrive while you are reading the data that has already arrived.

Ok, thank you, I got it now. Will try to change the code so that it stores incoming bytes.
Wonder if this will affect the necessity to re-upload the sketch though...

Yuri

Wonder if this will affect the necessity to re-upload the sketch though...

To be honest, I do to. However, your problem is a bit like doing to the doctor after nearly cutting your leg off with a chainsaw, and complaining about a splinter. You need to fix the big problems, first.

PaulS:
...your problem is a bit like doing to the doctor after nearly cutting your leg off with a chainsaw, and complaining about a splinter

I see it other way round. Misinterpretation (or missing) of sent bytes is not a big deal - they are used only for a display purpose (feedback to the user). Necessity to re-upload is a killer, because the device is going to be switched on underwater, meaning headless and without any normal input devices like keyboard or mouse.
Anyway, I've cleaned the code and used Serial.readStringUntil() (see attached). PC sends 152 bytes, starting with '#' and ending with '\0' with guaranteed absence of 0's in the array. So I just read until 0 is encountered. Seems to do fine.
Re-upload is still required, alas...

Cheers,
Yuri

LogoTextSpectrumTempUROSS3.ino (12 KB)

PC sends 152 bytes, starting with '#' and ending with '\0'

Unless you are doing something special on the PC, the NULL is NOT actually sent.

I guess the reason that I harp on the proper reading of data is that the data seems to be x coordinates. What happens if the coordinates are negative (-1 is what you get when you read data that isn't there)? What happens if two consecutive values are the same? Does a delta of 0 cause a division by 0, with disastrous results?

If you comment of the mode, do you still need to reload the sketch every time?

PC opens serial communication to Nano with Windows' function
HANDLE h = CreateFile("//./COMsomething",...)
and sends bytes with
WriteFile(h, ...)
so there is nothing fancy, and I believe that NULL is being sent, as it is just a byte which is equal to 0.
The data is a simplified representation of a spectrum, so they are properly scaled Y-coordinates with equidistant X's. No division or subtraction, positive non-zero values are just drawn on a connected LCD.

Doesn't matter if I call spectrum-drawing function or not, or if I do ANYTHING at all, powering off corrupts the program stored on a flash.

Yuri

YuriRzhanov:
Doesn't matter if I call spectrum-drawing function or not, or if I do ANYTHING at all, powering off corrupts the program stored on a flash.

If powering off your Nano really does corrupt the flash memory, you have faulty hardware and should get a new one.

I suspect the problem is actually somewhere in your code, perhaps in the way it's receiving serial data.

christop:
If powering off your Nano really does corrupt the flash memory, you have faulty hardware and should get a new one.

I suspect the problem is actually somewhere in your code, perhaps in the way it's receiving serial data.

May well be - I'm puzzled, that's why I've turned to the community.

  • Simple test programs (like "blink") do not get corrupted, that makes me think (hope) that Nano is ok.
  • I don't think (hope) that serial comms do not corrupt flash, because otherwise a single cycle of comms would cause the corruption and the program would stop working correctly.
  • Sketch uses 26884 bytes (87%) of storage, so there still some storage left.
  • Global vars use 1392 bytes (67%) of dynamic memory, so again I have 656 bytes for local vars. The only significant array is 150 ints, but they are global.

What kind of tests could I use to pinpoint the issue? I'd hate to dismantle the whole device (Nano is in the middle and has lots of wires soldered). Hope that the problem is in the code, but can't think of any particular part of code.

Cheers,
Yuri

What kind of tests could I use to pinpoint the issue?

Load the blink sketch. Does the LED blink? Power off the Arduino. Power it back on. Does the LED resume blinking? If so, there is nothing wrong with the Arduino, and it is your sketch that is the problem.

If not, the the Arduino is defective.

PaulS:
Load the blink sketch. Does the LED blink? Power off the Arduino. Power it back on. Does the LED resume blinking? If so, there is nothing wrong with the Arduino, and it is your sketch that is the problem.

If not, the the Arduino is defective.

I've mentioned before that Blink has no problems - it keeps blinking after powering off and then on again.
So it must be the code, but I don't see any place which might be dodgy...

but I don't see any place which might be dodgy

That makes one of us, unless you have fixed the reading of 150 bytes when there is at least one available.