Arduino Nano Freezes after some data is transfered through the serial port

#include <LiquidCrystal_I2C.h>
#include <Wire.h> 
//Define lcd monitor
LiquidCrystal_I2C lcd(0x27,20,4);
//          Variables
int Li          = 20;
int Lii         = 0; 

String readSong = "";
String oldSong = "wesrctfvygbhunjimkl";
String oldTime = "wesrctfvygbhunjimkl";
String data;
String delimiter = "sgxdfgchjkl";
String spotify_closed_key = "kyawesgtlu";

int wherePrint;
int time_x = 15;
int time_y = 3;

bool scrolling = false;
bool connected = false;
//Setup lcd display and serial port
void setup() {
  // initializing the LCD.
  lcd.init();  
  // initializing the serial monitor.
  Serial.begin(9600);
}
//Split two different data types
String* ProcessData(String sentData){
  if (sentData.startsWith(delimiter)){
    String time = sentData.substring(11, 16);
    String song = sentData.substring(16, sentData.length());
    //Can anyone explain me why use String* and not String?
    String* songandtime = new String[2];
    songandtime[0] = song;
    songandtime[1] = time;
    return songandtime;
  }else{
    String* songandtime = new String[2];
    songandtime[0] = sentData;
    songandtime[1] = "";
    return songandtime;    
  }
}
//Scrolls the text if > 20 characteres
String Scroll_LCD_Left(String StrDisplay){
  lcd.setCursor(0, 1);
  String result;
  String StrProcess = StrDisplay + "      " + StrDisplay;
  result = StrProcess.substring(Li,Lii);
  Li++;
  Lii++;
  //Only God knows what's happening here
  if (Li>(StrProcess.length() - (StrDisplay.length() - 20))){
    Li=20;
    Lii=0;
  }
  return result;
}
//Main void loop
void loop() {
  //Get data from python server
  readSong = Serial.readString();
  if (readSong != ""){ 
    //Enabling backlight
    lcd.backlight();
    String* processedData = ProcessData(readSong);
    //Check If time changed
    if (processedData[1] != ""){
      if (processedData[1] != oldTime){
        oldTime = processedData[1];

        //lcd.clear();
        lcd.setCursor(0, time_y);
        lcd.print("                    ");

        lcd.setCursor(time_x, time_y);
        lcd.print(processedData[1]);
      }
    }
    //Test if song changed
    if (processedData[0] != ""){
      if (processedData[0] != oldSong){
        oldSong = processedData[0];
        if (processedData[0] == "ServerExitedByUser"){
          lcd.noBacklight();
        }        
        if (processedData[0] == spotify_closed_key){
          time_x = 7;
          time_y = 1;

          lcd.clear();
          lcd.setCursor(time_x, time_y);
          lcd.print(oldTime);
        }else{
          time_x = 15;
          time_y = 3;

          //lcd.clear();
          lcd.setCursor(0, 1);
          lcd.print("                    ");
          //Print the results
          if (processedData[0].length() < 20){
            wherePrint = (20 - (processedData[0].length())) / 2;
            lcd.setCursor(wherePrint, 1);
            lcd.print(processedData[0]);
            //Disable text scrolling
            scrolling = false;
          }else{
            data = processedData[0];
            Li = 20;
            Lii = 0;
            //Enable text scrolling
            scrolling = true;          
          }        
        }
      } 
    }
  }
  //Text scrolling switch
  if (scrolling){
    lcd.print(Scroll_LCD_Left(data));
  }
}

I'm new in coding with arduino so i need some help here. This is an arduino program i made to display the currently playing song on a lcd display. Unfortunately, after transfering some ammount of data, the arduino freezes and it needs to be unplugged from the pc and plugged in again. After restarting it works fine. It seems like memory gets full or something, can somebody actually help me figure this out.

There is no delete matching your new, so your 2k RAM is lost fast.

If you run out of memory, Strings won't work anymore, new returns NULL,
which points directly to the processor's registers and IO ports.

I would not use String on a Nano anyway.
Fixed buffers would work better than the allocations, too.

can you either explain in more detail a solution or send a link with the documentation?

Learn C++, there are plenty of tutorials and books.

very helpful

Sorry, I can not spoon feed basic knowledge,
the Nuremberg Funnel was a hoax.

1 Like

thanks for your time

String* ProcessData(String sentData){

  static String songandtime[2];

  String time;
  String song;
  if (sentData.startsWith(delimiter)){
    time = sentData.substring(11, 16);
    song = sentData.substring(16, sentData.length());
    songandtime[0] = song;
    songandtime[1] = time;
  }else{
    songandtime[0] = sentData;
    songandtime[1] = "";
  }

  return songandtime;
}

I followed your advice and did some search. Still, I'm a beginner in C++ so it would be very helpuful if you weren't so strict(sr bad english). Anyways, I removed the new [] from the ProcessData() and I'm running the program for over 15min while contstantly sending a lot of data through the com port. I know the code is crap but is working. I just wanted to ask you if this was the problem you told me to fix or i have to do more work. I'll do my best and my goal is to learn C++ better in the following months, but this is my first project overall. So, it better?

If your program runs to your satisfaction, it is ok.

Instead of static you could have made the String array global,
which is just the same from a memory perspective,
so there would be no need to return it.

I would not use String on small memory machines,
the risk of memory (heap) fragmentation is too high for me.

Thank you for your support!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.