Problema di spazio con ethernet shield e micro SD

Salve a tutti.
Ho appena comprato l’ethernet shield per arduino e sto facendo i primi sketch, e le prime prove.
il problema è che quando compilo il codice, nell’interfaccia di output esce:

Lo sketch usa 21364 byte (66%) dello spazio disponibile per i programmi. Il massimo è 32256 byte.
Le variabili globali usano 1856 byte (90%) di memoria dinamica, lasciando altri 192 byte liberi per le variabili locali. Il massimo è 2048 byte.
Poca memoria disponibile, potrebbero presentarsi problemi di stabilità

controllando con avr-size, effettivamente la memoria è occupata, ma c’è qualche modo per risolvere questo problema?
dato che i risultati su monitor seriale sono completamente “sballati”

il codice:

//librerie per connessione alla rete, SD & stringhe
#include <Ethernet.h>
#include <SPI.h>
#include <SD.h>
#include <String.h>


void setup(){

 int button = 7;
 int state = 0;

 EthernetServer server(80);
 byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
 byte ip[] = {192, 168, 1, 200};
 byte gateway[] = {192, 168, 1, 1};
 byte subnet[] = {255, 255, 255, 0};

 String ascoltatore;
 char logs;
 
 File miofile;
 
 Sd2Card card;
 SdVolume volume;
 
 Ethernet.begin(mac, ip, gateway, subnet);
 ascoltatore = "";
 logs = "";
 
 pinMode(button, INPUT);
 
 Serial.begin(9600);
 while(!Serial){
   ;
 }

 delay(600);
 
 Serial.println("Sto inizializzando la scheda micro SD...\n");
 
 if(!SD.begin(4)){
   Serial.println("Inizializzazione fallita\n");
   Serial.println("* Controlla di aver impostato il pin quattro,");
   Serial.println("  come pin di Input");
   Serial.println("* Controlla di aver inserito la micro SD");
   return;
 }
 else{
   Serial.println("Inizializzazione completata");
   delay(2500);
   Serial.println("Configurazione terminata\n");

   delay(1600);
   
   Serial.print("Tipo di scheda micro SD:     ");
   switch (card.type()) {
     case SD_CARD_TYPE_SD1:
       Serial.print("SD1\n");
       break;
     case SD_CARD_TYPE_SD2:
       Serial.print("SD2\n");
       break;
     case SD_CARD_TYPE_SDHC:
       Serial.print("SDHC\n");
       break;
     default:
       Serial.print("Unknown\n");
   }

   Serial.print("Volume della micro SD:      \n");
   if (!volume.init(card)) {
     Serial.println("  Il volume identificato non è valido,"); 
     Serial.println("  prova a formattare la micro SD in FAT16 o FAT32 (ricorda:");
     Serial.println("  questa funzione potrebbe non funzionare con tutte le micro SD)\n");
   }
   else{
     Serial.print("  Il volume identificato FAT16/FAT32 corrisponde con le richieste\n");
   }

   delay(1800);
   
   if(SD.exists("logs.txt")){
     Serial.println("\n\n\nIl file logs.txt esiste\n");
   }
   else{
     Serial.println("\n\n\nIl file logs.txt non esiste\n");
     Serial.println("Sto creando un file dei logs.txt...");
     /*miofile = */SD.open("logs.txt", FILE_WRITE);
     
     if(SD.exists("logs.txt")){
       Serial.println("\nFile logs.txt creato\n\n");
     }
     else{
       Serial.println("\nFile logs.txt non creato\n\n");
     }
     
     delay(2500);
     //miofile.close();

     state = digitalRead(button);
   }  
 }
}


void loop(){

 int button = 7;
 int state = 0;

 EthernetServer server(80);
 byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
 byte ip[] = {192, 168, 1, 200};
 byte gateway[] = {192, 168, 1, 1};
 byte subnet[] = {255, 255, 255, 0};

 String ascoltatore;
 char logs;

 File miofile;

 Sd2Card card;
 SdVolume volume;

 EthernetClient client = server.available();
 state = digitalRead(button); 
 
 if(state == HIGH and SD.exists("logs.txt")){
     SD.remove("logs.txt");
     Serial.println("\nFile logs.txt eliminato");
     delay(10000);
   }

 if(client){
  while(client.connected()){
    if(client.available()){
     char c = client.read();
     ascoltatore.concat(c);

     if(c == "\n"){
         miofile.write(c);
         logs = SD.open("logs.txt", FILE_READ);
         Serial.println(logs);
       }
     }
   }
 } 
}
  1. é proprio necessario usare Stringhe? Non sarebbe possibile utilizzare array di char?
  2. in tutte le variabili che non superano il valore di 255 trattale byte.
  3. per tutte le Serial.print e le Serial.println ("testo"); trasformale in Serial.print e Serial.println (F("testo"));

Perchè le variabili le dichiari 2 volte, prima tutte nella setup e poi nella loop ?
mettile una volta sola in testa.

Poi segui consigli di @silente ed inoltre:

  1. const byte button = 7;
  2. Leva quel while(!Serial){ ; } serve solo per la Leonardo
  3. in tutti casi anche se usi F() sei su una piccola MCU, poca memoria, le "frasi" occupano spazio, abbrevia quei romanzi di frasi che hai scritto.
  4. ma che ti frega di sapere che tipo di SD è stata inserita ? mi pare un pezzo di codice inutile.

Grazie mille per avermi aiutato.
Vorrei chiederti solo cos'è e come funziona F()

Provando ad applicare i cambiamenti ( @Silente ), anche se non ho ancora creato gli array, l'output è questo:

exit status 1
Errore durante la compilazione per la scheda Arduino/Genuino Uno.

@nid69ita si lo so ma nell'interfaccia di output, diceva che gran parte era occupata dalle variabili globali, quindi ho provato a crearne due ma locali

Da quel msg d'errore non si capisce nulla. Di sicuro se guardi la lista c'e' scritto la linea dove c'e' l'errore.
Avrai sbagliato a mettere F()

Serial.println( F("Sto inizializzando la scheda micro SD...\n") );
E poi, sii un pò più conciso:
Serial.println("Inizializzo scheda micro SD...\n");

ti ho eliminato un po di dichiarazioni doppie
non ho applicato la F() che dice Silente

//librerie per connessione alla rete, SD & stringhe
#include <Ethernet.h>
#include <SPI.h>
#include <SD.h>
#include <String.h>

byte button = 7;
byte state = 0;
EthernetServer server(80);
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192, 168, 1, 200};
byte gateway[] = {192, 168, 1, 1};
byte subnet[] = {255, 255, 255, 0};

//   String ascoltatore;
char logs;
File miofile;
Sd2Card card;
SdVolume volume;

void setup() {
   Ethernet.begin(mac, ip, gateway, subnet);
   pinMode(button, INPUT);

   Serial.begin(9600);
   Serial.println("Sto inizializzando la scheda micro SD...\n");

   if (!SD.begin(4)) {
      Serial.println("Inizializzazione fallita\n");
      Serial.println("* Controlla di aver impostato il pin quattro,");
      Serial.println("  come pin di Input");
      Serial.println("* Controlla di aver inserito la micro SD");
      return;
   } else {
      Serial.println("Inizializzazione completata");
      delay(2500);
      Serial.println("Configurazione terminata\n");

      delay(1600);

      Serial.print("Tipo di scheda micro SD:     ");
      switch (card.type()) {
         case SD_CARD_TYPE_SD1:
            Serial.print("SD1\n");
            break;
         case SD_CARD_TYPE_SD2:
            Serial.print("SD2\n");
            break;
         case SD_CARD_TYPE_SDHC:
            Serial.print("SDHC\n");
            break;
         default:
            Serial.print("Unknown\n");
      }

      Serial.print("Volume della micro SD:      \n");
      if (!volume.init(card)) {
         Serial.println("  Il volume identificato non è valido,");
         Serial.println("  prova a formattare la micro SD in FAT16 o FAT32 (ricorda:");
         Serial.println("  questa funzione potrebbe non funzionare con tutte le micro SD)\n");
      } else {
         Serial.print("  Il volume identificato FAT16/FAT32 corrisponde con le richieste\n");
      }

      delay(1800);

      if (SD.exists("logs.txt")) {
         Serial.println("\n\n\nIl file logs.txt esiste\n");
      } else {
         Serial.println("\n\n\nIl file logs.txt non esiste\n");
         Serial.println("Sto creando un file dei logs.txt...");
         /*miofile = */SD.open("logs.txt", FILE_WRITE);

         if (SD.exists("logs.txt")) {
            Serial.println("\nFile logs.txt creato\n\n");
         } else {
            Serial.println("\nFile logs.txt non creato\n\n");
         }
         delay(2500);
         //miofile.close();
      }
   }
}

void loop() {
   EthernetClient client = server.available();
   state = digitalRead(button);

   if (state == HIGH and SD.exists("logs.txt")) {
      SD.remove("logs.txt");
      Serial.println("\nFile logs.txt eliminato");
      delay(10000);
   }

   if (client) {
      while (client.connected()) {
         if (client.available()) {
            char c = client.read();
            //            ascoltatore.concat(c);

            if (c == '\n') {                     //<--------------------
               miofile.write(c);                //<--------------------

               logs = SD.open("logs.txt", FILE_READ);
               Serial.println(logs);
            }
         }
      }
   }
}

ma dopo aver messo tutto in ascoltatore sulla sd stampi \ n e sulla serial 1 che succede?

Ho creato l'array e ho messo byte al posto di int, ma la ram rimane piena (93%)

Anche con le F?
Allora non so che cosa essa contenga.
E hai anche semplificato le pappardelle?

eliminando la pappardella
comprese sd2card e sdvolume arrivo a 63%

@Patrick_M, grazie ci ho pensato anche io, infatti ora le tolgo

@Silent si ho fatto tutto e sono arrivato a 63%