Serial Monitor Freezing at Same spot

Hello,

I am currently building a DAQ with the following components:
1X TCA9548A Multiplexer
2X MPRLS
1X BME280
1X RTC
1X DS18B20
1X Micro SD module
2X RS232 interfaces

I have combined many of the example sketches for each sensor to get this sketch.

The Serial monitor will run only partway and freeze at the same point each time. I have tried removing some of the "Serial.print" commands in case there are just too many for the system to handle but that caused it to just freeze at a different spot.

#include <Wire.h>
#include <SPI.h> 
#include <SD.h> //Used for SD card Read/Write
#include <Adafruit_Sensor.h> 
#include <Adafruit_MPRLS.h> // Used for the 2 PFD pressure sensors
#include <Adafruit_BME280.h> //Temp, Humidity, Pressure Sensor
#include <DS1307RTC.h> //Used for RTC
#include <TimeLib.h> //USed for RTC
extern "C" { 
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
#include <OneWire.h> //Used for the DS18B20 Water Temperature Sensor
#include <SoftwareSerial.h> //RS232 communication 

#define TCAADDR 0x70
#define RESET_PIN -1
#define EOC_PIN -1
#define SEALEVELPRESSURE_HPA 1013.5 

int RX_PIN1 = 17;
int TX_PIN1 = 16;
int RX_PIN2 = 15;
int TX_PIN2 = 14;
int count;
char serialData = "";
String dataString = "";
int data[15];
byte x;
const int chipSelect = 53;

/* Assign a unique ID to this sensor at the same time */
Adafruit_MPRLS mpr1 = Adafruit_MPRLS(RESET_PIN, EOC_PIN);
Adafruit_MPRLS mpr2 = Adafruit_MPRLS(RESET_PIN, EOC_PIN);
Adafruit_BME280 bme;
SoftwareSerial RS232_1 = SoftwareSerial(RX_PIN1, TX_PIN1);
SoftwareSerial RS232_2 = SoftwareSerial(RX_PIN2, TX_PIN2);

OneWire  ds(2);  // on pin 2 (a 4.7K resistor is necessary)

void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}
 
void setup(void) 
{
  while(!Serial);
  Serial.begin(9600);
  delay (1000);

  Wire.begin();

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  
  Serial.println("card initialized.");
  pinMode(RX_PIN1, INPUT);
  pinMode(TX_PIN1, OUTPUT);
  pinMode(RX_PIN2, INPUT);
  pinMode(TX_PIN2, OUTPUT);
  RS232_1.begin(9600);
  RS232_2.begin(9600);
  
  Serial.println("TCA Scanner Ready");
  for (uint8_t t=0; t<8; t++) {
      tcaselect(t);
      Serial.print("TCA Port #"); Serial.println(t);
 
      for (uint8_t addr = 0; addr<=127; addr++) {
        if (addr == TCAADDR) continue;
      
        uint8_t data;
        if (! twi_writeTo(addr, &data, 0, 1, 1)) {
           Serial.print("Found I2C 0x");  Serial.println(addr,HEX);
        }
      }
    }
  Serial.println("MPRLS Manometer Test"); Serial.println("");
  
  /* Initialise the 1st sensor */
  tcaselect(1);
  if(! mpr1.begin())
  {
    Serial.println("Ooops, no MPRLS1 detected ... Check your wiring!");
    while(1);
  }
  
  /* Initialise the 2nd sensor */
  tcaselect(2);
  if(!mpr2.begin())
  {
    Serial.println("Ooops, no MPRLS2 detected ... Check your wiring!");
    while(1);
  }
}
 
void loop(void) 
{
   /* Get a new MPRLS Pressure event */ 
  sensors_event_t event; 
  
  tmElements_t tm;

  tcaselect(0);
  if (RTC.read(tm)) {
    Serial.print("Time ");
    dataString += "Time ";
    print2digits(tm.Hour);
    Serial.write(':');
    dataString += ":";
    print2digits(tm.Minute);
    Serial.write(':');
    dataString += ":";
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    dataString += ", Date (D/M/Y) = ";
    Serial.print(tm.Day);
    Serial.write('/');
    dataString += "/";
    Serial.print(tm.Month);
    Serial.write('/');
    dataString += "/";
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
    dataString += String(tmYearToCalendar(tm.Year));
    dataString += "    ";
  }
  else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  
  tcaselect(1);
  /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
  Serial.print("Sensor #1 - ");
  Serial.print("Pressure (PSI): "); Serial.print(mpr1.readPressure()/68.947572932); Serial.print("  ");
  dataString += "Pressure 1 (PSI):  ";
  dataString += String(mpr1.readPressure()/68.947572932);
  
  tcaselect(2);
  /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
  Serial.print("Sensor #2 - ");
  Serial.print("Pressure (PSI): "); Serial.print(mpr2.readPressure()/68.947572932); Serial.print("  ");
  Serial.println(" ");
  dataString += "   Pressure 2 (PSI):  ";
  dataString += String(mpr2.readPressure()/68.947572932);
  
  tcaselect(7);
  printBMEValues();

  printWaterTemp();
  printRS232();

  
  delay(2000);
  
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port:
    Serial.println(dataString);
  }
  // if the file isn't open, error:
  else {
    Serial.println("error opening datalog.txt");
  }
  Serial.println("done");
}

void printBMEValues ()
{
    
    Serial.print("Air Temperature:   ");
    dataString += "Air Temperature:   ";
    Serial.print(bme.readTemperature());
    dataString += String(bme.readTemperature());
    Serial.println(" *C");
    dataString += " *C";
    Serial.print("   Air Pressure:   ");
    dataString += "   Air Pressure:   ";
    Serial.print(bme.readPressure() / 100.0F);
    dataString += String(bme.readPressure() / 100.0F);
    Serial.println(" hPa");
    dataString += " hPa";
    Serial.print("   Humidity:   ");
    dataString += "   Humdity:   ";
    Serial.print(bme.readHumidity());
    dataString += String(bme.readHumidity());
    Serial.println(" %");
    dataString += " %";
    Serial.println();
    dataString += "   ";
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
    dataString += "0";
  }
  Serial.print(number);
  dataString += String(number);
}

void printWaterTemp (){
  
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);
  
  delay(1000);     
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad
  
  for ( i = 0; i < 9; i++) {
    data[i] = ds.read();
  }

  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; 
    if (data[7] == 0x10) {
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;  
    else if (cfg == 0x20) raw = raw & ~3; 
    else if (cfg == 0x40) raw = raw & ~1; 
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("Water Temperature:   ");
  dataString += "Water Temperature:   "; 
  Serial.print(celsius);
  dataString += String(celsius);
  Serial.print(" *C");
  dataString += " *C";
  ds.reset_search();
}
/* Function to read incoming data from the RS232 connected to the Load cell */
void printRS232 ()
{
  count = 0;
  if (RS232_1.available()) {

    dataString += "Load Cell 1:   ";
    Serial.print("Load Cell 1:   ");
    while (count < 15){
      x = RS232_1.read();
      Serial.write(x); 
      dataString += String(x);
      Serial.print(" , ");
      data[count] = x;
      delay;
      count++;
    }
    Serial.println();
    for(count = 0;count<15;count++){
      Serial.print(data[count]);
      Serial.print(",");
      }
  }
  count = 0;
  dataString += "   Load Cell 2:   ";
  Serial.print("   Load Cell 2:   ");
  if (RS232_2.available()) {
    while (count < 15)
      {
       x = RS232_2.read();
      Serial.write(x); 
      dataString += String(x);
      Serial.print(" , ");
      data[count] = x;
      delay;
      count++;
      }
    Serial.println();
    for(count = 0;count<15;count++)
    {
      Serial.print(data[count]);
      Serial.print(",");
    }
  }
}

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

My guess is that that is the cause of your problem.

I suspect it is not necessary to write the data to the file in one piece

dataFile.println(dataString);

I think you could write it as a series of separate datafile.print() statements which would avoid the need for creating the String (or even a cstring)

...R

Which Arduino board are you using? How much remaining SRAM (global variables) are reported after compiling?

You have 2 variables named data. A global int array and a local byte array. That may cause troubles even if not the cause of the problem.

@Robin2 thank you! So by that do you mean in place of Strings(), use cstrings()?

@GroundFungus - I'm using a Mega, after it compiles it says 2048 (25%) of dynamic memory is used and 6144 is remaining.

OK, not a memory usage problem. Then I am with Robin2. Replace the use of Strings with cstrings. The Evils of Strings explains why to avoid Strings and how to use cstrings and cstring functions in their place.

One other thing that can cause that type of behaviour is writing past the end of an array. Make sure that your arrays are all large enough to handle the number of elements that you write to them. Don't forget to leave space for the null at the end of cstrings.

Add

dataString = "";

at the begining of loop()

Mark

Thanks a lot for everyone's suggestions.

I went with replacing the dataString occurrences with the dataFile.print() command and it has worked.