Unable to use DS3231 with Ethernet and SD Card

I have been using Arduino Uno with an Ethernet shield and RTC DS3231 for a Project. The project is about monitoring analogue channel data on a webpage and logging that data on an SD card using an Ethernet shield. I am using DS3231 for time stamping when logging the data on SD Card.

All the three components are working fine individually and also in pairs of two i.e. RTC and SD Card Logging, SD Card and Ethernet. But when Using RTC DS 3231 and Ethernet simultaneously the serial monitor gets stuck or hang. Or else I get an error that the file can not be opened.

Also, I want to create an event-based system such that if I press a button on the webpage, It'll create a new file on SD Card and log the data for a pre-specified time limit. Please let me know if that is possible or not.

I suspect that the issues may be related to the communication, SPI and I2C.

p.s. I have used Interrupts to update the value of ADC as soon as it is changed. as the system that I am trying to develop is time-critical.

Also, I am not very efficient in this programming so please don't mind any errors or mistakes and do let me know about the same.

The codes are attached below. Kindly help me with the same.

Thank You.

The code for SD Card and RTC is as below

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

#include <Wire.h> //include Wire.h library
#include "RTClib.h" //include Adafruit RTC library

RTC_DS3231 rtc; //Make a RTC DS3231 object

//Set the names of days
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

int data;
const int CH_Num = 7;   //Number of channels +1
int myData[CH_Num] = {0,0,0,0,0,0};   //Initialize each

void 
DataLog(){

  DateTime now = rtc.now();
  
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 1 ; analogPin < 7; analogPin++) {
    int sensor = myData[analogPin];

    float Voltage = sensor * 4.196 / 1023.0;

    dataString += String(Voltage);
    if (analogPin < 6) {
      dataString += ",";
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.csv", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {

    //Print RTC time to Serial Monitor
    dataFile.print(now.year(), DEC);
    dataFile.print('/');
    dataFile.print(now.month(), DEC);
    dataFile.print('/');
    dataFile.print(now.day(), DEC);
    dataFile.print(" (");
    dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
    dataFile.print(") ");
    dataFile.print(now.hour(), DEC);
    dataFile.print(':');
    dataFile.print(now.minute(), DEC);
    dataFile.print(':');
    dataFile.print(now.second(), DEC);
    dataFile.print(" , ");
    
    dataFile.println(dataString);
    dataFile.println(" ");
    dataFile.close();
    // print to the serial port too:
   // Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.csv");
  }  
  return;
}

void setup() {
  //To set up continuous sampling of analog pin A0

  //Clear ADCSRA and ADCSRB registers
  //To receive new values
 // ADCSRA = 0;
  //ADCSRB = 0;

  ADMUX |=(1 << REFS0);   //|(0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0);  //Set Reference voltage 
  
  ADMUX |=(0<<ADLAR);  //Select 10 bit ADC 
  //ADMUX |=(1<<ADLAR);  //Select 8 bit ADC   
  
  ADCSRA |=(1<<ADPS2)|(1<<ADPS0);  //Set ADC clock with 32 prescaler
                                   //16MHz/32 = 500KHz
                                   
  ADCSRA |=(1<<ADATE);  //Enable auto trigger
  ADCSRA |=(1<<ADIE);  //Enable interrupts when measurement complete
  ADCSRA |=(1<<ADEN);  //Enable ADC

  sei(); //Enable Interrupts

  ADCSRA |=(1<<ADSC);  //Start ADC measurements

    Serial.begin(9600);  //Begin serial communication

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  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");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  
  //Print the message if RTC is not available
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  //Setup of time if RTC lost power or time is not set
  if (rtc.lostPower()) {
    //Sets the code compilation time to RTC DS3231
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }  

  //DateTime now = rtc.now();
  
//  cli();  //Disable Interrupts

  
}

ISR(ADC_vect){
 myData[data] = ADC;  //Add ADC Reading to Array

 if(++data>=CH_Num){    //increment data and check whether it is >= Channel no. i.e 7
  data =0;    //If channel no is grater than 7 data =0
 }

  ADMUX =(1 << REFS0)|(0<<ADLAR)|data;    //Select the channel to send data reading on
  ADCSRA |=(1<<ADSC);   //Start ADC
}

void loop() {

  DateTime now = rtc.now();
  
  //Print RTC time to Serial Monitor
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  
  Serial.print("R 1 = ");
  Serial.print(myData[1]);

  Serial.print(": R 2 = ");
  Serial.print(myData[2]);
  
  Serial.print(": R 3 = ");
   Serial.print(myData[3]);

  Serial.print(": R 4 = ");
  Serial.print(myData[4]);

  Serial.print(": R 5 = ");
  Serial.print(myData[5]);

  Serial.print(": R 6 = ");
  Serial.println(myData[6]);

  DataLog();

  delay(1000);
}

The code for SD Card and Ethernet shield webserver is as below:

/*
 * Project Name:
 * Real Time Data Monitoring and Logging Using Ethernet Shield
 * 
 * Project Objective:
 * To Display the reading on a static Webserver using Ethernet
 * To Logg data in a SD Card
 * 
 * Project Description:
 * 
 * Pins Used:
 * Analog pin A0-A5: To read analog sensor reading
 * Digital pin 10, 11, 12, 13: Connected to Ethernet Shield
 * Digital pin 4 - SD Card
 * 
 * ADC Calculations:
 * The clock Frequency of Arduino is 16MHz
 * Default Prescaler is 128
 * For the current project the prescaler selected is 32
 * Thus, 16MHz/32 = 500KHz ADC clock
 * 
 * A single ADC conversation takes around 13 clock cycle
 * Thus, 500KHz/13 = 38,000Hz (38,461) i.e. Sample Rate
 * 
 * Thus, it takes approx 26microseconds to update to new value.
 * 
 * 
 * Functions:
 * ISR i.e Interrupt Service Routine. 
 * 
 * The ISR will automatically update the the ADC
 * When new data is available on the Analog Channel
 * Insted of using the internal AnalodRead() function.
 * 
 * The value when updated will be stored in array i.e myData[]
 * This readings stored in the array will then be used to display on a webserver
 * using Ethernet and will be send to SD card for Logging
 * 
 * Webserver():
 * This is a userdefine function that contains various parameters and routines to
 * create a static webpage and to send the data from the Arduino to the webpage.
 * 
 * The Webpage is written in basic HTML code
 * 
 * This code can be found in the example codes of the Arduino IDE.
 * Follow the steps mentioned below:
 * 1) Open File from the top menu bar
 * 2) Select Example
 * 3) Select Ethernet
 * 4) Select Webserver
 * 
 * The IP Address of the Ethernet and the Webserver can be obtained using the following steps:
 * 
 * 1) Open Network and internet sharing option from settings
 * 2) Open Change Adapter Settings
 * 3) Select the appropriate Ethernet option
 * 4) Open Properties 
 * 5) Select IPV4 Settings
 * 6) Copy the IP Address and paste below
 * 
 * DataLog():
 * This is also a userdefine Function that contains the parameters and routines to logg data
 * from the Arduino Analog Channels on the SD Card.
 * 
 * The Ethernet Shield has a SD Slot and the pin to use the SD Card is connected on the 
 * Digital Pin 4 on the Arduino.
 * 
 * This code can be found in the example code in the Arduino IDE.
 * 
 * Follow the steps below to find the Example code:
 * 1) Open File from the top menu bar
 * 2) Select Example
 * 3) Select SD
 * 4) Select Datalogger
 * 
 * P.S. The example code mentioned above i.e Webserver and Datalog are Changed and modified 
 * to fulfil the requirement of the current project.
 * 
 * Created by 
 * Aryansinh Zala
 * From 20th January 2022
 * TO 30th April 2022
 * 
 */


//////////////////SPI Parameters //////////////////////////

#include <SPI.h>        //Include SPI Library

//////////////////////////////////////////////////////////

///////////////// Ethernet parameters///////////////////////

#include <Ethernet.h>   //Include Ethernet Library

// Enter a MAC address and IP address for your controller below.
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// The IP address will be dependent on your local network:
IPAddress ip(192, 168, 137, 30);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

////////////////////////////////////////////////////////////

///////////////// SD Card parameters///////////////////////

#include <SD.h>   //Include SD card Library

const int chipSelect = 4;   //Select the digital pin 4 for SD Card

//////////////////////////////////////////////////////////

///////////////// Analog Reading parameters///////////////////////

int data;         //define a variable to store data
const int CH_Num = 7;     //Initialize variable to select the number of analog channels
                          //Total 6 Analog channels in Arduino UNO
                          
int myData[CH_Num] = {0, 0, 0, 0, 0, 0}; //Initialize and Array to store the Analog Values 
                                         //from each Analog channels

////////////////////////////////////////////////////////////

///////////////// Function to display Analog Channel readings on Webserver///////////////////////

void 
WebServer() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    
    while (client.connected()) {
      if (client.available()) {
        
        char c = client.read();
        
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 0.1");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          client.println("<head>");
          client.println("<h1> Webserver to Display Analog Sensors Reading </h1>");
          client.println("</head>");

          client.println("<body style=\"text-align:center;font-size:25px;background-color:powderblue\">");

          // output the value of each analog input pin
          for (int analogChannel = 1; analogChannel < 7; analogChannel++) {
            int sensorReading = myData[analogChannel];  //Take the values form Each channels
                                                        // and store it in a variable

            //map(sensorReading, 0, 255, 0, 1023);

            float Voltage = sensorReading * 4.196 / 1023.0; //Calibrate to convert ADC reading
                                                            //to voltage reading
            //To print the voltage reading on the webpage
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.print(" Measured Voltage is ");
            client.print(Voltage);
            client.println("<br />");
          }
          client.println("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");

    return;
  }
}

//////////////////////////////////////////////////////////////////

///////////////// Function to log Data on the SD Card///////////////////////

void 
DataLog(){
    // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 1 ; analogPin < 7; analogPin++) {
    int sensor = myData[analogPin];

    float Voltage = sensor * 4.196 / 1023.0;

    dataString += String(Voltage);
    if (analogPin < 6) {
      dataString += ",";
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.csv", FILE_WRITE);

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

////////////////////////////////////////////////////////////////////

///////////////// Setup Function ///////////////////////

void 
setup() {
  Serial.begin(9600);  //set baudrate @ 9600

  //  cli();  //Disable Interrupts

  //To set up continuous sampling of analog pin A0

  //Clear ADCSRA and ADCSRB registers
  //To receive new values
  // ADCSRA = 0;
  //ADCSRB = 0;

  ADMUX |= (1 << REFS0);  //|(0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0);  //Set Reference voltage
  ADMUX |= (0 << ADLAR); //Left align the ADC values,
  //so we can read the highest 8 bits from ADCH register only
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //Set ADC clock with 32 prescaler
  //16MHz/32 = 500KHz
  ADCSRA |= (1 << ADATE); //Enable auto trigger
  ADCSRA |= (1 << ADIE); //Enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //Enable ADC

  sei(); //Enable Interrupts

  ADCSRA |= (1 << ADSC); //Start ADC measurements

  //-----------------------

  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");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  //--------------------

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

////////////////////////////////////////

///////////////// ISR Function///////////////////////

ISR(ADC_vect) {
  myData[data] = ADC;  //update the variable with new value from A0

  if (++data >= CH_Num) {   //Increment data and check if it is >= CH_Num
    data = 0;   //If channel no. is greater than 7, data = 0;
  }

  ADMUX = (1 << REFS0) | (0 << ADLAR) | data;
  ADCSRA |= (1 << ADSC);
}

////////////////////////////////////////////////////

///////////////// Loop Function///////////////////////

void 
loop() {
  WebServer();
  DataLog();

  delay(100);
}

////////////////////////////////////////////////////

///////////////// End of Code ///////////////////////

The code for SD Card, Ethernet Webpage and RTC DS 3231 is as below:

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

#include <Wire.h> //include Wire.h library
#include "RTClib.h" //include Adafruit RTC library

RTC_DS3231 rtc; //Make a RTC DS3231 object

//Set the names of days
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

int data;
const int CH_Num = 7;   //Number of channels +1
int myData[CH_Num] = {0,0,0,0,0,0};   //Initialize each

#include <Ethernet.h>   //Include Ethernet Library

// Enter a MAC address and IP address for your controller below.
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// The IP address will be dependent on your local network:
IPAddress ip(192, 168, 137, 30);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void 
WebServer() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    
    while (client.connected()) {
      if (client.available()) {
        
        char c = client.read();
        
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 0.1");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          client.println("<head>");
          client.println("<h1> Webserver to Display Analog Sensors Reading </h1>");
          client.println("</head>");

          client.println("<body style=\"text-align:center;font-size:25px;background-color:powderblue\">");

          // output the value of each analog input pin
          for (int analogChannel = 1; analogChannel < 7; analogChannel++) {
            int sensorReading = myData[analogChannel];  //Take the values form Each channels
                                                        // and store it in a variable

            //map(sensorReading, 0, 255, 0, 1023);

            float Voltage = sensorReading * 4.196 / 1023.0; //Calibrate to convert ADC reading
                                                            //to voltage reading
            //To print the voltage reading on the webpage
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.print(" Measured Voltage is ");
            client.print(Voltage);
            client.println("<br />");
          }
          client.println("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");

    return;
  }
}

void 
DataLog(){

  DateTime now = rtc.now();
  
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 1 ; analogPin < 7; analogPin++) {
    int sensor = myData[analogPin];

    float Voltage = sensor * 4.196 / 1023.0;

    dataString += String(Voltage);
    if (analogPin < 6) {
      dataString += ",";
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.csv", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {

    //Print RTC time to Serial Monitor
    dataFile.print(now.year(), DEC);
    dataFile.print('/');
    dataFile.print(now.month(), DEC);
    dataFile.print('/');
    dataFile.print(now.day(), DEC);
    dataFile.print(" (");
    dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
    dataFile.print(") ");
    dataFile.print(now.hour(), DEC);
    dataFile.print(':');
    dataFile.print(now.minute(), DEC);
    dataFile.print(':');
    dataFile.print(now.second(), DEC);
    dataFile.print(" , ");
    
    dataFile.println(dataString);
    dataFile.println(" ");
    dataFile.close();
    // print to the serial port too:
   // Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.csv");
  }  
  return;
}

void setup() {
  //To set up continuous sampling of analog pin A0

  //Clear ADCSRA and ADCSRB registers
  //To receive new values
 // ADCSRA = 0;
  //ADCSRB = 0;

  ADMUX |=(1 << REFS0);   //|(0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0);  //Set Reference voltage 
  
  ADMUX |=(0<<ADLAR);  //Select 10 bit ADC 
  //ADMUX |=(1<<ADLAR);  //Select 8 bit ADC   
  
  ADCSRA |=(1<<ADPS2)|(1<<ADPS0);  //Set ADC clock with 32 prescaler
                                   //16MHz/32 = 500KHz
                                   
  ADCSRA |=(1<<ADATE);  //Enable auto trigger
  ADCSRA |=(1<<ADIE);  //Enable interrupts when measurement complete
  ADCSRA |=(1<<ADEN);  //Enable ADC

  sei(); //Enable Interrupts

  ADCSRA |=(1<<ADSC);  //Start ADC measurements

    Serial.begin(9600);  //Begin serial communication

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

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

  delay(1000);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  
  //Print the message if RTC is not available
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  //Setup of time if RTC lost power or time is not set
  if (rtc.lostPower()) {
    //Sets the code compilation time to RTC DS3231
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }  

  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  //DateTime now = rtc.now();
  
//  cli();  //Disable Interrupts
}

ISR(ADC_vect){
 myData[data] = ADC;  //Add ADC Reading to Array

 if(++data>=CH_Num){    //increment data and check whether it is >= Channel no. i.e 7
  data =0;    //If channel no is grater than 7 data =0
 }

  ADMUX =(1 << REFS0)|(0<<ADLAR)|data;    //Select the channel to send data reading on
  ADCSRA |=(1<<ADSC);   //Start ADC
}


void loop() {
  DataLog();
  WebServer();

  delay(1000);
}

SD_RTC_Web.ino (7.8 KB)
SD_RTC.ino (4.7 KB)
CSV_WebColor.ino (10.9 KB)

What does the compiler say about SRAM (dynamic memory) usage ?

I think that you have what most of us have experienced.
The Ethernet and SD library need a lot of memory, they work barely on a Arduino Uno. You don't use the 'F()' macro, so your sketch uses more SRAM memory than needed.

In the past the solution was to move to the Arduino Mega 2560.
However, the Ethernet Shield uses low-level communication. The ESP32 with Wifi is better for internet.

If you use the 'F()' macro and PROGMEM for the names of the days, it might just be enough to make it work. That gives you time to think about a better solution.

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