loop stops responding using ethernet library

hi all!

i have an issue that i am currently trying to debug where after running (so far between 3 - 10 hours before problems happen) it just stops communicating with the server and no longer prints messages to Serial. i am not sure which line the arduino gets stuck on and im not sure how i should handle it so ive included my sketch for anyone's review.

#include <SPI.h>
#include <Ethernet.h>
String uptime;
char data[256];
int motion;
int motion_sensor_pin = 22;
String myID = "C6";
byte myIP[4] = {192,168,230,82};
byte SM[4] = {255,255,0,0};
//byte DNS[4] = {192,168,192,216};
//byte GW[4] = {192,168,192,20};
byte mac[] = { 0xAA, 0xAD, 0xBA, 0xEF, 0xFB, 0xEB };
char server[] = "192.168.230.1";

IPAddress IP(myIP);

// fill in your Domain Name Server address here:
//IPAddress myDns(DNS);

// initialize the library instance:
EthernetClient client;

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 1*1000;  // delay between updates, in milliseconds

void setup() {
  // start serial port:
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial1.setTimeout(250);
  // give the ethernet module time to boot up:
  delay(1000);
  // start the Ethernet connection using a fixed IP address and DNS server:
  Ethernet.begin(mac, myIP);
  // print the Ethernet board/shield's IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  
  pinMode(motion_sensor_pin, INPUT);

}

void loop() {
  
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    httpRequest();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

void readCh1() {
  while (Serial1.read() != -1) {}
  delay(10);
  Serial1.print("?");
  char CRC[16];
  for (int x = 0; x <= 255; x++) {
     data[x] = 0; 
  }
  Serial1.readBytesUntil('@',CRC,15);
  Serial1.readBytesUntil('\r',data,255);
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    digitalWrite(motion_sensor_pin, LOW);
    motion = digitalRead(motion_sensor_pin);
    readCh1();
    Serial.println(motion);
    uptime = String(millis()/1000);
    //String data = "C:28917{\"TYP\":\"DriAir\",\"IDS\":\"D19285\",\"STE\":\"RUN\",\"TMP\":4055,\"DEW\":-49,\"BRD\": 88.26,\"RUN\":1}";
    String Output = "GET /mon?ID=" +myID+ "&TIME=" + uptime +"&MOTI=" + motion + "&DATA=\"" + data + "\"";

    Serial.println("connecting...");
    Serial.println(Output+ " HTTP/1.1");
    // send the HTTP PUT request:
    client.println(Output);
    client.println("Host: www.arduino.cc");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();

    // note the time that the connection was made:
    lastConnectionTime = millis();
  }
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println("disconnecting.");
    client.stop();
  }
}

if anyone could help shed a little light on this i would be very grateful!!!

You're using String class so I'd immediately suspect that - are you aware of all
the caveats regarding using it? If that might be the problem you could monitor free memory
to see if it is being eaten up.

Thanks Mark,

i have done my best to remove all String objects except for the method parameter in "buildAry(String input)" .

Is this okay or still an issue for the long run??:

void buildAry(String input) {
  for (int x = 0; x < input.length(); x++) {
    outBuffer[charIdx] = input[x];
    charIdx += 1;
  }
}

Full Sketch:

#include <SPI.h>
#include <Ethernet.h>
int uptime;
char data[256];
boolean motion;
int motion_sensor_pin = 22;
char myID[24] = {"C8"};
byte myIP[4] = {
  192,168,230,81};
byte SM[4] = {
  255,255,0,0};
//byte DNS[4] = {192,168,192,216};
//byte GW[4] = {192,168,192,20};
byte mac[] = { 
  0xAA, 0xAD, 0xBA, 0xEF, 0xFB, 0xC8 };
char server[] = "192.168.230.1";

IPAddress IP(myIP);

// fill in your Domain Name Server address here:
//IPAddress myDns(DNS);

// initialize the library instance:
EthernetClient client;

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 1*1000;  // delay between updates, in milliseconds

void setup() {
  // start serial port:
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial1.setTimeout(250);
  // give the ethernet module time to boot up:
  delay(1000);
  // start the Ethernet connection using a fixed IP address and DNS server:
  Ethernet.begin(mac, myIP);
  // print the Ethernet board/shield's IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());

  pinMode(motion_sensor_pin, INPUT);

}

void loop() {

  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    httpRequest();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

void readCh1() {
  while (Serial1.read() != -1) {
  }
  delay(10);
  Serial1.print("?");
  char CRC[16];
  for (int x = 0; x <= 255; x++) {
    data[x] = 0; 
  }
  Serial1.readBytesUntil('@',CRC,15);
  Serial1.readBytesUntil('\r',data,255);
}

int charIdx = 0;
char outBuffer[512];

void clearAry() {
  for (int x = 0; x <= 511; x++) {
    outBuffer[x] = 0;
  }  
  charIdx = 0;
}

void buildAry(String input) {
  for (int x = 0; x < input.length(); x++) {
    outBuffer[charIdx] = input[x];
    charIdx += 1;
  }
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    digitalWrite(motion_sensor_pin, LOW);
    motion = digitalRead(motion_sensor_pin);
    readCh1();
    Serial.println(motion);
    uptime = millis()/1000;
    //String data = "C:28917{\"TYP\":\"DriAir\",\"IDS\":\"D19285\",\"STE\":\"RUN\",\"TMP\":4055,\"DEW\":-49,\"BRD\": 88.26,\"RUN\":1}";
    //char Output = "GET /mon?ID=" +myID+ "&TIME=" + uptime +"&MOTI=" + motion + "&DATA=\"" + data + "\"";
    buildAry("GET /mon?ID=");
    buildAry(myID);
    buildAry("&TIME=");
    char v_time[24];
    sprintf (v_time, "%i", uptime);
    buildAry(v_time);
    buildAry("&MOTI=");
    char v_moti[1];
    sprintf (v_moti, "%i", motion);
    buildAry(v_moti);
    buildAry("&DATA=\"");
    buildAry(data);
    buildAry("\"");
    
    Serial.println("connecting...");
    Serial.print(outBuffer);
    Serial.println(" HTTP/1.1");
    // send the HTTP PUT request:
    client.println(outBuffer);
    client.println("Host: www.arduino.cc");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
    clearAry();
    // note the time that the connection was made:
    lastConnectionTime = millis();
  }
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println("disconnecting.");
    client.stop();
  }
}

i have done my best to remove all String objects except for the method parameter in "buildAry(String input)" .

If you'd really removed all Strings, you would not need that method. strcat() does the same thing that function does.

    String Output = "GET /mon?ID=" +myID+ "&TIME=" + uptime +"&MOTI=" + motion + "&DATA=\"" + data + "\"";

Looks like a String to me.

void clearAry() {
  for (int x = 0; x <= 511; x++) {
    outBuffer[x] = 0;
  }  
  charIdx = 0;
}

Isn't one stop sign enough for you? Do you really need 512 of them to stop? 512 elements in that array is way more than needed.

    char v_moti[1];
    sprintf (v_moti, "%i", motion);

Your array has room for the NULL and NO characters. You can't use it in this call.

    uptime = millis()/1000;

millis() returns an unsigned long. Even divided by 1000, it will still overflow an int, after 32,787 seconds.

    char v_time[24];
    sprintf (v_time, "%i", uptime);

Given that the range of an int is -32768 to 32767, the maximum length of the array needed is 7. Round to 8 if you want, but 24 is wasting space.