Datlogger MEGA and Ethernet shield with SD card / no writing, only reading works

Hello everyone
I am testing a simple data logger from the SdFat library on a Arduino Mega and w5100 ether shield library and cannot open a file on SD card.

The output show me :

[Info] Opened the serial port - /dev/tty.usbmodem14401
Data00.csv
error: file.open

Any suggestions would be welcome !

The complete source code :

/*
 * Simple data logger.
 */
#include <SPI.h>
#include <SdFat.h>

#define SDCARD_CS 4	// Chip Select SD Card on W5100  - HIGH Deactive DOWN Active
#define ETHERNET_CS 10	


// SD chip select pin.  Be sure to disable any other SPI devices such as Enet.
//const uint8_t chipSelect = 4;

// Interval between data records in milliseconds.
// The interval must be greater than the maximum SD write latency plus the
// time to acquire and write data to the SD to avoid overrun errors.
// Run the bench example to check the quality of your SD card.
const uint32_t SAMPLE_INTERVAL_MS = 1000;

// Log file base name.  Must be six characters or less.
#define FILE_BASE_NAME "Data"
//------------------------------------------------------------------------------
// File system object.
SdFat sd;

// Log file.
SdFile file;

// Time in micros for next data record.
uint32_t logTime;

//==============================================================================
// User functions.  Edit writeHeader() and logData() for your requirements.

const uint8_t ANALOG_COUNT = 4;
//------------------------------------------------------------------------------
// Write data header.
void writeHeader() {
  file.print(F("micros"));
  for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
    file.print(F(",adc"));
    file.print(i, DEC);
  }
  file.println();
}
//------------------------------------------------------------------------------
// Log a data record.
void logData() {
  uint16_t data[ANALOG_COUNT];

  // Read all channels to avoid SD write latency between readings.
  for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
    data[i] = analogRead(i);
  }
  // Write data to file.  Start with log time in micros.
  file.print(logTime);

  // Write ADC data to CSV record.
  for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
    file.write(',');
    file.print(data[i]);
  }
  file.println();
}
//==============================================================================
// Error messages stored in flash.
#define error(msg) sd.errorHalt(F(msg))
//------------------------------------------------------------------------------


void ChipSelect(uint8_t pin, bool enable)      //   debugging
{
	if (enable)
		//digitalWrite(pin, !digitalRead(pin));  
	{	pinMode(pin, OUTPUT);
		digitalWrite(pin, LOW); // active
	}
	else
		//digitalWrite(pin, digitalRead(pin));   
	{
		pinMode(pin, OUTPUT);
		digitalWrite(pin, HIGH); // de active
	}
}




void setup() {
  
  pinMode(4, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(10,HIGH);  // Ethernet not active
  digitalWrite(4,LOW);     // SD Card active
  

//ChipSelect(ETHERNET_CS, false);     // Ethernet not active
//ChipSelect(SDCARD_CS, true);		// SD Card active
  
  
  
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";

  Serial.begin(115200);
  
  // Wait for USB Serial 
  while (!Serial) {
    SysCall::yield();
  }
  delay(1000);

  
  /*
  Serial.println(F("Type any character to start"));
  while (!Serial.available()) {
    SysCall::yield();
  }
  */

  // Initialize at the highest speed supported by the board that is
  // not over 50 MHz. Try a lower speed if SPI errors occur.
  if (!sd.begin(SDCARD_CS)) {
    sd.initErrorHalt();
  }

  // Find an unused file name.
  if (BASE_NAME_SIZE > 6) {
    error("FILE_BASE_NAME too long");
  }
  while (sd.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      error("Can't create file name");
    }
  }
  if (!file.open(fileName, O_WRONLY | O_CREAT | O_EXCL)) {
    Serial.println(fileName); //debug
    error("file.open");
  }
  // Read any Serial data.
  do {
    delay(10);
  } while (Serial.available() && Serial.read() >= 0);

  Serial.print(F("Logging to: "));
  Serial.println(fileName);
  Serial.println(F("Type any character to stop"));

  // Write data header.
  writeHeader();

  // Start on a multiple of the sample interval.
  logTime = micros()/(1000UL*SAMPLE_INTERVAL_MS) + 1;
  logTime *= 1000UL*SAMPLE_INTERVAL_MS;
}









//------------------------------------------------------------------------------
void loop() {
  // Time for next record.
  logTime += 1000UL*SAMPLE_INTERVAL_MS;

  // Wait for log time.
  int32_t diff;
  do {
    diff = micros() - logTime;
  } while (diff < 0);

  // Check for data rate too high.
  if (diff > 10) {
    error("Missed data record");
  }

  logData();

  // Force data to SD and update the directory entry to avoid data loss.
  if (!file.sync() || file.getWriteError()) {
    error("write error");
  }

  if (Serial.available()) {
    // Close file and stop.
    file.close();
    Serial.println(F("Done"));
    SysCall::halt();
  }
}

Try changing
pinMode(10, OUTPUT);
to
pinMode(53, OUTPUT);
which is standard practice for Mega. This should be demonstrated in the examples that came with your library.

Hello Nick !
I add pinMode(53, OUTPUT) and nothing.

The Arduino board communicates with the shield using the SPI bus.
This is on digital pins 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega.
On both boards, pin 10 is used as SS.
On the Mega, the hardware SS pin, 53, is not used to select the Ethernet controller chip, but it must be kept as an output or the SPI interface won't work

First, I testing QuickStart.ino too and it work well.
Then but when I use Arduino MEGA and W5100 with ReadWrite.ino minimal example

I can initialize the card and list files but I cannot create or open a file.

I use Arduino MEGA and W5100 with ReadWrite.ino example

I took the the precaution of putting pin 10 as the output and high and pin 53 as output too.

#define SD_CS_PIN 4
#define DISABLE_CHIP_SELECT 10
#define SS 53
pinMode(DISABLE_CHIP_SELECT, OUTPUT);
digitalWrite(DISABLE_CHIP_SELECT, HIGH);
pinMode(SD_CS_PIN, OUTPUT);
digitalWrite(SD_CS_PIN, LOW);
pinMode(SS, OUTPUT);

but the output not change

Initializing SD card..initialization done.
error opening test.txt
error opening test.txt

The readwrite.ino code

/*
  SD card read/write
 This example shows how to read and write data to and from an SD card file
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 This example code is in the public domain.
 */

#include <SPI.h>
//#include <SD.h>
#include "SdFat.h"
SdFat SD;

#define SD_CS_PIN 4
#define DISABLE_CHIP_SELECT 10
#define SS 53
File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

//pinMode(DISABLE_CHIP_SELECT, OUTPUT);
//digitalWrite(DISABLE_CHIP_SELECT, HIGH);

pinMode(SD_CS_PIN, OUTPUT);
digitalWrite(SD_CS_PIN, LOW);
pinMode(SS, OUTPUT);



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

  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

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

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}

The "precaution" of calling pin10 is either a bad idea or an unnecessary one. The W5100 works fine on a Mega. Your code seems overly complicated but that may be down to the SDFat library, and I cannot comment on that. Mellis and Igoe only deal with the standard SD library. I suggest you do the same until you are sure you need SDFat.

Another very simple code, now with SD. h, just only Arduino MEGA and SD module

/*
  SD card file dump

  This example shows how to read a file from the SD card using the
  SD library and send it over the serial port.
  Pin numbers reflect the default SPI pins for Uno and Nano models.

  The circuit:
   SD card attached to SPI bus as follows:
 ** SDO - pin 11
 ** SDI - pin 12
 ** CLK - pin 13
 ** CS - depends on your SD card shield or module.
        Pin 10 used here for consistency with other Arduino examples
   (for MKRZero SD: SDCARD_SS_PIN)

  created  22 December 2010
  by Limor Fried
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.
*/

#include <SD.h>

const int chipSelect = 53;

void setup() {
  
  pinMode(chipSelect, OUTPUT);
//digitalWrite(chipSelect, HIGH);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // wait for Serial Monitor to connect. Needed for native USB port boards only:
  while (!Serial);

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

  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("1. is a card inserted?");
    Serial.println("2. is your wiring correct?");
    Serial.println("3. did you change the chipSelect pin to match your shield or module?");
    Serial.println("Note: press reset or reopen this serial monitor after fixing your issue!");
    while (true);
  }

  Serial.println("initialization done.");

  // 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.txt");

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

void loop() {
}

and the same output

SPI pins:
MISO: 50
MOSI: 51
SCK: 52
SS: 53

Initializing SD card...initialization done.
error opening datalog.txt

[/code]

Confusion reigns. Unless you have a shield specifically for the Mega, and I bet you don't, CS is pin 4. The only code you need to change is pin 10 to pin 53, as mentioned above

I concluded that it is a hardware problem, I don't know, possibly the sd card socket. I connected another SD module directly to pin 4 of the ethernet module and was able to initialize, open and write to the file. I don't know why, with the previous scheme (MEGA and WIZ5100) it allowed me to initialize the card only. Thank you very much.
Regards

/*
  SD card read/write
 This example shows how to read and write data to and from an SD card file
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 This example code is in the public domain.
 */

#include <SPI.h>
//#include <SD.h>
#include "SdFat.h"
SdFat SD;

#define SD_CS_PIN 4
#define DISABLE_CHIP_SELECT 10
#define SS 53
#define SPI_SPEED SD_SCK_MHZ(4)
File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

pinMode(DISABLE_CHIP_SELECT, OUTPUT);
digitalWrite(DISABLE_CHIP_SELECT, HIGH); 

pinMode(SD_CS_PIN, OUTPUT);
digitalWrite(SD_CS_PIN, LOW);

pinMode(SS, OUTPUT);


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

  if (!SD.begin(SD_CS_PIN, SPI_SPEED)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

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

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}