Error Opening File on SD Ethernet Shield

I am having trouble combining a couple of sketches that I have. What I am doing is:

  • Powering 8 motors using TIP120 transistors (full power on)
  • Powering 8 electromagnetic solenoids with PWM
  • Reading 8 potentiometer inputs via a multiplexer (CD74HC4067) to output PWM to the solenoids
  • Reading and logging time via DS1307 RTC
  • Reading and logging temperature from 8 LM335Z analog sensors

I am using an Ethernet shield to log data to the SD card and the Arduino Mega 2560 R3 microcontroller. My first sketch works great. It reads time and temp data and logs both to SD card. My second sketch works as well. It turns the motors on and runs the solenoids with PWM through the multiplexer. When I try to combine these sketches I am having an error opening the file on the SD card. I know that the card is formatted correctly and the file is present as sketch 1 works. I can use sketch 1 to test the RTC and temp probes and logging functionality. In my combination sketch the motors are running, the solenoids are working and the multiplexer is reading - it’s just not opening the file on the SD card per the error message in the serial monitor “error opening data.csv”

Sketch 1: 8 temp sensor data log with time stamp

#include <SD.h>
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68 
#include "RTClib.h"

RTC_DS1307 RTC;
float tempK;  
int sensor;   
const int chipSelect = 4;
int analogPin = 1;     
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

void setup(){
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
    if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));}
   
   Serial.print("Initializing SD card...");
   pinMode(10, OUTPUT); 
   digitalWrite(10, HIGH); 
   if (!SD.begin(chipSelect)) 
    Serial.println("Card failed, or not present");
        return;
   Serial.println("card initialized.");
  
  pinMode(1, INPUT);}

void loop(){
   String dataString = getDateDs1307();
  dataString += String(" ");
   for (analogPin = 1; analogPin < 9; analogPin++){
        if( analogPin < 9){
     tempK = ((analogRead(analogPin)/ 1023.0) * 500.0) ;
     sensor = (9/5)*(tempK - (273.15))+(32.0); 
    }
    dataString += String(sensor);
    if (analogPin < 9) {
      dataString += ", "; 
    }
    delay(100) ; //delay between temp readings
  }
  File dataFile = SD.open("data.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    Serial.println(dataString);
  }  
  else {
    Serial.println("error opening datalog.csv");
  } 
}
String getDateDs1307()
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  second     = bcdToDec(Wire.read() & 0x7F);
  minute     = bcdToDec(Wire.read());
  hour       = bcdToDec(Wire.read() & 0x3F);  
  dayOfWeek  = bcdToDec(Wire.read());
  dayOfMonth = bcdToDec(Wire.read());
  month      = bcdToDec(Wire.read());
  year       = bcdToDec(Wire.read());
  
  String dataString = "";
  
  dataString += Print2Digit(bcdToDec(month)); 
  dataString += String("/");
  dataString += Print2Digit(dayOfMonth); 
  dataString += String("/");
  dataString += Print2Digit(bcdToDec(year));
  dataString += String(" ");
  dataString += String(",");
  dataString += Print2Digit(hour);
  dataString += String(":");
  dataString += Print2Digit(minute);
  dataString += String(":");
  dataString += Print2Digit(second);
  dataString += String(",");
  return dataString;
}
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}
String Print2Digit(byte Val)
{
  String dataString = "";
  if (Val < 10)
  {
    dataString = "0";
  }  
  dataString += String(Val, DEC);
  return dataString;
}

I ran out of room on this post so the combined sketch is in the following post below

Combined sketch: adding motor and solenoid power and multiplexer reading
This is the sketch that gives me the error “error opening data.csv” and therefore no time or temp readings will be taken and read

#include <SD.h>
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 
#include "RTClib.h"

int electromagnet1 = 6;
int electromagnet2 = 7;
int electromagnet3 = 8;
int electromagnet4 = 9;
int electromagnet5 = 10;
int electromagnet6 = 11;
int electromagnet7 = 12;
int electromagnet8 = 13;
int motor1 = 31;
int motor2 = 33;
int motor3 = 35;
int motor4 = 37;
int motor5 = 39;
int motor6 = 41;
int motor7 = 43;
int motor8 = 45;
int s0 = 2;
int s1 = 3;
int s2 = 4;
int s3 = 5;
int SIG_pin = 0; //MUX Sig pin in analog 0

RTC_DS1307 RTC;
float tempK;  
int sensor;   
const int chipSelect = 4;
int analogPin=1;      //Sensors begin in analog 1
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

void setup(){
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
   
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);  
  if (!SD.begin(chipSelect)) {
  Serial.println("Card failed, or not present");
  return;
     
  Serial.println("card initialized.");
  //Defines sensor as an INPUT on PIN Number 1
  pinMode(1, INPUT);
  
  RTC.adjust(DateTime(__DATE__, __TIME__)); }
  
  pinMode(31, OUTPUT);
  pinMode(33, OUTPUT);
  pinMode(35, OUTPUT);
  pinMode(37, OUTPUT);
  pinMode(39, OUTPUT);
  pinMode(41, OUTPUT);
  pinMode(43, OUTPUT);
  pinMode(45, OUTPUT);
  
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(13,OUTPUT);
    
  pinMode(s0, OUTPUT); 
  pinMode(s1, OUTPUT); 
  pinMode(s2, OUTPUT); 
  pinMode(s3, OUTPUT); 

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);}
  
void loop(){
{
  digitalWrite(motor1, HIGH);
  digitalWrite(motor2, HIGH);
  digitalWrite(motor3, HIGH);
  digitalWrite(motor4, HIGH);
  digitalWrite(motor5, HIGH);
  digitalWrite(motor6, HIGH);
  digitalWrite(motor7, HIGH);
  digitalWrite(motor8, HIGH);  }
  
  int value1 = analogRead(readMux (0));
  int value2 = analogRead(readMux (1));
  int value3 = analogRead(readMux (2));
  int value4 = analogRead(readMux (3));
  int value5 = analogRead(readMux (4));
  int value6 = analogRead(readMux (5));
  int value7 = analogRead(readMux (6));
  int value8 = analogRead(readMux (7));
  
  int electromagnet_flux1 = value1/4; 
  int electromagnet_flux2 = value2/4; 
  int electromagnet_flux3 = value3/4; 
  int electromagnet_flux4 = value4/4; 
  int electromagnet_flux5 = value5/4; 
  int electromagnet_flux6 = value6/4; 
  int electromagnet_flux7 = value7/4; 
  int electromagnet_flux8 = value8/4; 
  {
  analogWrite(electromagnet1,electromagnet_flux1);
  analogWrite(electromagnet2,electromagnet_flux2);
  analogWrite(electromagnet3,electromagnet_flux3);
  analogWrite(electromagnet4,electromagnet_flux4);
  analogWrite(electromagnet5,electromagnet_flux5);
  analogWrite(electromagnet6,electromagnet_flux6);
  analogWrite(electromagnet7,electromagnet_flux7);
  analogWrite(electromagnet8,electromagnet_flux8);

  delay(2000);

  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(8, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  
  delay(2000);  }

  String dataString = getDateDs1307();
  dataString += String(" ");
  for (analogPin = 1; analogPin < 9; analogPin++){
  if( analogPin < 9){
  tempK = ((analogRead(analogPin)/ 1023.0) * 500.0) ;
  sensor = (9/5)*(tempK - (273.15))+(32.0); }
 
  dataString += String(sensor);
  if (analogPin < 9) {
  dataString += ", "; 
    }
    delay(100) ;  }

  File dataFile = SD.open("data.csv", FILE_WRITE);

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

}
String getDateDs1307()
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  second     = bcdToDec(Wire.read() & 0x7F);
  minute     = bcdToDec(Wire.read());
  hour       = bcdToDec(Wire.read() & 0x3F);  
  dayOfWeek  = bcdToDec(Wire.read());
  dayOfMonth = bcdToDec(Wire.read());
  month      = bcdToDec(Wire.read());
  year       = bcdToDec(Wire.read());
  
  String dataString = "";
  
  dataString += Print2Digit(bcdToDec(month)); 
  dataString += String("/");
  dataString += Print2Digit(dayOfMonth); 
  dataString += String("/");
  dataString += Print2Digit(bcdToDec(year));
  dataString += String(" ");
  dataString += String(",");
  dataString += Print2Digit(hour);
  dataString += String(":");
  dataString += Print2Digit(minute);
  dataString += String(":");
  dataString += Print2Digit(second);
  dataString += String(",");

  return dataString;
}
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}
String Print2Digit(byte Val)
{
  String dataString = "";
  if (Val < 10)
  {
    dataString = "0";
  }  
  dataString += String(Val, DEC);
  return dataString;
}

int readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };
  for(int i = 0; i < 4; i ++){
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
  int val = analogRead(SIG_pin);
  return val;
}

You can't do this:

  digitalWrite(10, LOW);

...then try this:

 File dataFile = SD.open("data.csv", FILE_WRITE);

D10 is the SPI slave select for the w5100. You do not want it LOW (active) while opening the SD file.

SurferTim: You can't do this:

  digitalWrite(10, LOW);

...then try this:

 File dataFile = SD.open("data.csv", FILE_WRITE);

D10 is the SPI slave select for the w5100. You do not want it LOW (active) while opening the SD file.

Right! I was unconsciously using pin 10 as an output to control electromagnet 5 (pulsed on and off). I had forgotten about that. So is pin 10 taken up by using the Ethernet shield? I could just reassign electromagnet to another pin output.

alphacheese: Right! I was unconsciously using pin 10 as an output to control electromagnet 5 (pulsed on and off). I had forgotten about that. So is pin 10 taken up by using the Ethernet shield? I could just reassign electromagnet to another pin output.

Yes. D10 is the SPI slave select for the w5100 ethernet controller. If you set D10 LOW, it activates the w5100 SPI MISO line (becomes a driving output rather than hi-z). That interferes with the SD MISO line, and could cause damage to one or both devices.

Use another pin.