Datalogging in a SD card and connecting to internet al the same time

Hello!!

I have a project where the main goal is to detect tension failure in a power line, register the time of the power outtage in a SD card and send an alert to a PC connected to the local network. I have these functionalities working perfectly in two diferent sketches, one for SD datalogging and another one for sending the alert trought the local network.

The problem comes when i try to put those two codes together and have both functionalities working at the same time as it should be when finished. The ethernet client works perfectly until i connect the SD card, then the client won’t connect and the SD won’t log anything neither.

I’ve been doing some research and i’ve found out that the problem is in the SPI port limitation, after researching on that i found a solution where you toggle HIGH/LOW ports 4 or 10 depending if you need ethernet to work or SD card to work. I tried implementing that in my code and i couldn’t make it work, not sure if the implementation wasn’t correct or if i have any other problem that causes it to not work properly.

If anyone can help me find the error or the solution i’d be so thankful.

Hardware used:

-Arduino Uno
-Ethernet Shield R3
-RTC DS3231

#include <Ethernet.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
#include <SD.h>

#define SS_SD_CARD   4
#define SS_ETHERNET 10


File logFile;
 
RTC_DS3231 rtc;

//configuració ethernet
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 2, 197);
EthernetServer server(80);

const int rele = 8;

bool tensio = false;
bool estatActual = LOW;
bool estatAnterior = LOW;
 
String daysOfTheWeek[7] = { "Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte" }; //days of the week in my language
String monthsNames[12] = { "Gener", "Febrer", "Març", "Abril", "Maig",  "Juny", "Juliol","Agost","Setembre","Octubre","Novembre","Desembre" };  //names of the months in my laguange

void setup() {

    pinMode(SS_SD_CARD, OUTPUT);
    pinMode(SS_ETHERNET, OUTPUT);
    digitalWrite(SS_SD_CARD, HIGH);  // SD Card not active
    digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active

pinMode(rele, INPUT);
  
Ethernet.begin(mac, ip);
Serial.begin(19200);

//Comprovar que hi ha la placa i esta conectat el cable
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("La placa d'Ethernet no esta connectada");
    while (true) {
      delay(1); // si no hi ha placa d'ethernet no fa res
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("El  cable d'Ethernet no esta connectat");
  }
//Arrancar el servidor
  server.begin();
  Serial.print("La IP del servidor és: ");
  Serial.println(Ethernet.localIP());

// rellotge i sd
    DateTime now = rtc.now();
   Serial.print(F("Iniciando SD ..."));
     if (!SD.begin(4))
   {
      Serial.println(F("Error al iniciar"));//start error
      return;
   }
   Serial.println(F("Iniciado correctamente"));// start correct

 
 
   if (!rtc.begin()) {
      Serial.println(F("No s'ha pogut trobar el RTC"));
      while (1);
   }
}

void printDate(DateTime date){
   Serial.print(date.year(), DEC);
   Serial.print('/');
   Serial.print(date.month(), DEC);
   Serial.print('/');
   Serial.print(date.day(), DEC);
   Serial.print(" (");
   Serial.print(daysOfTheWeek[date.dayOfTheWeek()]);
   Serial.print(") ");
   Serial.print(date.hour(), DEC);
   Serial.print(':');
   Serial.print(date.minute(), DEC);
   Serial.print(':');
   Serial.print(date.second(), DEC);
   Serial.println();
}
void logValue(DateTime date, int value){
   logFile.print(date.year(), DEC);
   logFile.print('/');
   logFile.print(date.month(), DEC);
   logFile.print('/');
   logFile.print(date.day(), DEC);
   logFile.print(" ");
   logFile.print(date.hour(), DEC);
   logFile.print(':');
   logFile.print(date.minute(), DEC);
   logFile.print(':');
   logFile.print(date.second(), DEC);
   logFile.print(" ");
   logFile.println(value);
}




void loop() {

            tensio = digitalRead(rele);
 // listen for incoming clients
 digitalWrite(SS_ETHERNET, HIGH);
  EthernetClient client = server.available();
  if (client) { //comunicació amb el servidor i enviament de dades
    //Serial.println("client nou");
    // an http request ends with a blank line
    bool currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        //Serial.write(c);
        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: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          //A partir d'aqui s'envia el text a la pagina
          client.println("hola");
          

          if (tensio == true){
            client.println("Hi ha tensio");
          }
            else{ 
            client.println("<script>");
            client.println("alert('ATENCIO, NO HI HA TENSIO');");
            client.println("</script>");
          }
  
          
          //fins aqui s'envia el text a la pagina
            client.println("
");
          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;
        }
      }
    }
    delay(1);
    // tancar la conexió
    client.stop();
    //Serial.println("client desconectat");

  }
  delay(5000);
   digitalWrite(SS_ETHERNET, LOW);
   digitalWrite(SS_SD_CARD, HIGH);
     DateTime now = rtc.now();

   estatActual = digitalRead(rele);
    
    if (estatActual != estatAnterior){
    bool tensio = digitalRead (rele);
      if (tensio == LOW) {
        logFile = SD.open("datalog.txt", FILE_WRITE);
        Serial.print("no tensio ");
        //printDate(now);
        int value = 8;
        logFile.print("Tall de tensió a les:"); //power cut at:
        //logValue(now, value);
        logFile.close();
   }
   delay(50);
   } 
     if (estatAnterior == LOW && estatActual == HIGH) { 
        logFile = SD.open("datalog.txt", FILE_WRITE);
        Serial.print("tensio ");
       // printDate(now);
        int value = 8;
        logFile.print("Torna la tensió a les:"); //tension returns at
        //logValue(now, value);
        logFile.close();
   }
   digitalWrite(SS_SD_CARD, LOW);
       estatAnterior = estatActual; //last state= actual state
       
}

If you have any question on the code or anything else please ask, i tried to explain everything that i think its important. Thanks for everything!!

Are you using recent versions of the official Arduino libraries?

The SD card and Ethernet libraries should be setting their respective slave select lines during SPI communication so there should be no need to manually set them.

Your attempts to set them manually don't make sense. Remember slave select in this context is 'active low'. To make things clearer for yourself, add a comment next to each one that says '// enable' or '// disable'.