Arduino loosing sketch after power recycle

I have a fully working sketch involving a raspberry pi and an Arduino UNO.

The Raspberry pi feeds data from a html user interface down a USB serial cable to the Arduino, which drives some relays.

However, when I power the Arduino down, I have to reload the sketch before I can get it working again.

So far, I have tried …

A different sketch (blink) which works and is stored perfectly. This would suggest that the issue is related to my sketch or the serial connection

I have tried powering things up and down in different orders, so see if that made a difference
I have also tried Powering the Arduino from separate power, as well as via the USB cable

The code in question is as follows

// NOTE that the data must have start/stop characters < >

String DATA ="";
boolean newData = false;
String before = "";
String after = "";
String relay = "";

void setup() {
    Serial.begin(9600);
    /*Serial.println("<Arduino is ready>");*/

    pinMode(6,OUTPUT);
    pinMode(7,OUTPUT);
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);
    pinMode(13,OUTPUT);
    
    digitalWrite(6,HIGH);
    digitalWrite(7,HIGH);
    digitalWrite(8,HIGH);
    digitalWrite(9,HIGH);
    digitalWrite(10,HIGH);
    digitalWrite(11,HIGH);
    digitalWrite(12,HIGH);
    digitalWrite(13,HIGH);
}



void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    char startMarker = '<';
    char endMarker = '>';
    char received_character;
 
    while (Serial.available() > 0 && newData == false) {
        received_character = Serial.read();

        if (recvInProgress == true) {
                 
            if (received_character != endMarker) {
                DATA = DATA + received_character;
                
            }
            else {
                recvInProgress = false;
                newData = true;
            }                 
        } 

        else if (received_character == startMarker) {
            recvInProgress = true;
        }                                                  
    }  
} 

void driveRelays() {
  
    if (newData == true) {
        
     int pin = 13; 
      if(DATA[0] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

      pin = 12; 
      if(DATA[1] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

       pin = 11; 
      if(DATA[2] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

      pin = 10; 
      if(DATA[3] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

       pin = 9; 
      if(DATA[4] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

      pin = 8; 
      if(DATA[5] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

     pin = 7; 
      if(DATA[6] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}

      pin = 6 ; 
      if(DATA[7] == '1') 
          { digitalWrite(pin,LOW); }        
      else
          { digitalWrite(pin,HIGH);}
             
        DATA = "";
        newData = false;
    }
}

void loop() {
    recvWithStartEndMarkers();  
    driveRelays();
 delay(100);   
}

Running out of ideas, all suggestions welcome
My code is also a but crude as I am a bit off-side. Any suggestions on how to improve it, also appreciated

Your assumption is likely wrong, your arduino does not loose its program.

are you sure your arduino shows up under the same Serial Connection when it reboots? do you have other stuff connected? how do you upload, versus connect to your RPi ? is your RPi closing the Serial connection when the Arduino disappear and does not open it again? → explore there

note that you can put the PIN number directly in the code, no need to change pin all along and you can simplify your code with a for loop:

  if (newData) {
    for (int index = 0; index < 8; index++) {
      if (DATA[index] == '1') digitalWrite(13 - index, LOW);
      else digitalWrite(13 - index, HIGH);
    }
    DATA = "";
    newData = false;
  }

also seems you’ve taken the Serial Input Basics idea for start and end marker, but you still went for a String class to store your buffer, that’s not a great idea… just stick to the cString char buffer, you’ll gain in memory and efficiency.

also given you seem to handle less than 8 digits, rather than sending the data in ASCII, just send a byte with bits at 0 or 1 matching the pins number you want to handle. that will make the Serial communication 10x faster (if that’s needed)

Try running the sketch on the Arduino while it is connected to the computer you used to program it.

Use the serial monitor to manually send your commands. You should be able to prove quickly that the sketch survives a restart of the Arduino.

Thanks for your input guys,

In answer to your questions ....

Provided that I don't have anything else in the PI USB sockets, the arduino always connects to the same port.
I have been ensuring that nothing else is connected during testing.
I have been uploading the sketch from the PI (with keyboard/mouse connected)
The Pi script is triggered via an HTML user interface but with same result if triggered from the command line.

Sending commands from the serial monitor does not work after the arduino reboot but is a useful testing tool, thanks for the tip.

Good advice re the code, I'll implement that and see if it changes anything because I'm not really any closer to finding the true cause of the problem.

One point. After the reboot, there is clearly some data on the move because the 'receive' LED flashes, together with pin 13LED. However, the relays are not controlled. I think this would indicate a fault with my code, even though it does work when first uploaded. You are probably correct when you say that the serial link is working, but not the code after reboot. I'll soldier on. Thanks again

When I encounter an issue like this, I ask myself why are the laws of physics not working on my project when they work for everyone else?

I used the serial port from Pi to Uno via a logic level shifter, worked great.

When the Uno is connected and doing its thing, unplug the USB and plug it back in, does the Uno resync with the Pi? You see if the Pi is powered and the Uno is powered unplugging the Uno to Pi connection will cause a loss of communications but each unit will remain powered, the Uno, at this point does not erase its programming. But if they do not sync back up then the issue is the code and not the laws of physics being different on your workbench then for the rest of humanity on Earth.

When I send data, serially, I think of each data packet as a sentence. To mark the beginning of the sentence I use a “<” and to mark the end of the sentence, I use a “>.” If the Uno starts receiving data in the middle of the sentence, like after a communication disruption, the Uno should have markers to that indicate that what’s being received at the serial port is the beginning, middle, or end of the sentence.

So a sentence might look like this

<!, 422,965,peanuts are ok,3,79> or <#,422,965,peanuts are ok,3,79>

I use the ! or # or @ or $ and so on and so forth to describe to the receiving device what the info is and what needs to be done with the data. The “,” are word separators and the “< >” are sentence markers.

if the arduino disappears, what happens to the status of the Serial object you have in you RPi program? don't you need to restart it?

re-opening the Serial line from the RPi side will reboot your arduino (if you have a UNO or Mega etc)

UPDATE
It looks as if you are right in that the sketch is still in the Arduino, but for some reason, does not work after a reboot. However, when I open the serial monitor, it starts to work. Can anyone suggest why that might be, and what might be done to to emulate that effect in the sketch?

how are things wired? how can you open the Serial Monitor if your arduino is connected to the RPi as well?

again, I would suggest you look at what happens on the RPi side when the Serial link goes away. do you test that, do you re-open when it comes back ?

The Raspberry Pi is running everything, including the Arduino compiler and serial monitor, so I can open it during the action.

Apart from checking which port has been assigned by the Pi, using "ls /dev/tty*", how can I check whether the serial connection is open and active on the pi? I can send you the pi code if that is relevant.

Forgive my ignorance, I'm new to all this and whilst my code is a bit crude, I'm surprised that I have got as far as I have.

On the RPi a loop back test would let you know that the Pi is doing the serial thing. Try the Raspberry Pi website for more information.

robbiethepoet:
The Raspberry Pi is running everything, including the Arduino compiler and serial monitor, so I can open it during the action.

You can have only one process attached to the serial link, it’s either your program or the Arduino IDE console

robbiethepoet:
when I open the serial monitor, it starts to work. Can anyone suggest why that might be

When you open the Serial Monitor, the Uno resets. Does pressing the reset button on the Uno have the same effect as opening Serial Monitor?