Help, ethernet and SD, error ÿ

Hi, my program is working fine the first time it runs, but when i put the codes and save changes to the SD card, the Ethernet request start to return ÿÿÿÿÿÿÿÿÿÿÿÿ instead of the content of the file recorded on the SD, and don't stop, so it breaks.
The code in below, the comments are in Portuguese, but i can pass to English if needed.
The code is a little huge, and its attached.

I think that maybe the error is in this part of the code:
But i don't know.

if(regular_relogio != 2){
        Serial.println("Opened!");// caso contrário enviamos uma menssagem padrão de OK 
 
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/plain");
          client.println();
          
          myFile = SD.open(filename);// Abrimos o arquivo que foi solicitado
          
          int8_t c;
          while(myFile.available())
          {
           
           c = myFile.read();
           Serial.print("RAM Livre: ");
           Serial.println(freeRam());
           client.print((char) c);
           
         Serial.print("c = ");
        
         Serial.println((char) c);//Dai imprimimos na tela do cliente e na serial tudo que tem no arquivo
          }
          myFile.close();// fecha o arquivo do SD que fora aberto 
      }

Thanks.

ver_arquivos_SD_acessar.ino (23.4 KB)

ver_arquivos_SD_acessar.ino (23.4 KB)

And i'm using an Arduino Mega 2560, an WizNet Ethernet Shield my Micro SD card it's plugged to it, an NOKIA 5110 lcd display, and a keyboard 4x4.

Thats all.

Thanks

Maybe it is not opening the file? You should check.

         myFile = SD.open(filename);// Abrimos o arquivo que foi solicitado
         if(!myFile) Serial.println("file open failed");

edit: The funny y = ÿ = 255 = -1 = fail.

No, the error is still there and myFile is opened.
I don't know but a get in the serial C = y
C = y, and it keep going like this forever, until i reset the arduino.

Thanks for the help.

guilherme_ebio:
when i put the codes and save changes to the SD card

Can you explain exactly what this means?

Is this an Uno or Mega? I just took a look at your entire code.You sure are using a lot of SRAM with those constant strings. Maybe you are running out of SRAM? 8K in the Mega, and 2K in the Uno. The Ethernet and SD libraries takes a bunch of that.
You never see this?

           Serial.print("RAM Livre: ");
           Serial.println(freeRam());

You should use the "F" function to user those strings from program memory rather than transferring it into SRAM.

Serial.println("This string is transferred to SRAM before printing");
Serial.println(F("This string is printed from program memory"));

PeterH:

guilherme_ebio:
when i put the codes and save changes to the SD card

Can you explain exactly what this means?

Yes, a use the Ethernet to browse the files on the SD card, and see the files, and i use an keyboard and some info to save the data to the SD card, like the date and the sector chosen, etc, so when a start the arduino i can see the files and browse then, but after a used the keyboard to save new data on the SD the error occurs, it's not all the time but it happens a lot.

Thanks.

And,

SurferTim:
Is this an Uno or Mega? I just took a look at your entire code.You sure are using a lot of SRAM with those constant strings. Maybe you are running out of SRAM? 8K in the Mega, and 2K in the Uno. The Ethernet and SD libraries takes a bunch of that.
You never see this?

           Serial.print("RAM Livre: ");

Serial.println(freeRam());




You should use the "F" function to user those strings from program memory rather than transferring it into SRAM.



Serial.println("This string is transferred to SRAM before printing");
Serial.println(F("This string is printed from program memory"));

Yes, i see, i still got almost 4k of SRAM when the error occurs, but of course i will change all of then to F.

Thanks a lot for the advise.

SurferTim:
Is this an Uno or Mega? I just took a look at your entire code.You sure are using a lot of SRAM with those constant strings. Maybe you are running out of SRAM? 8K in the Mega, and 2K in the Uno. The Ethernet and SD libraries takes a bunch of that.
You never see this?

           Serial.print("RAM Livre: ");

Serial.println(freeRam());




You should use the "F" function to user those strings from program memory rather than transferring it into SRAM.



Serial.println("This string is transferred to SRAM before printing");
Serial.println(F("This string is printed from program memory"));

Sorry i forgot to say but and using a Mega 2560.

Thanks.

I see LCD display and keypad code. How is that connected? Is that SPI also? The datasheet indicates it may be. It has a data, clock and CS on the interface.

SurferTim:
I see LCD display and keypad code. How is that connected? Is that SPI also? The datasheet indicates it may be. It has a data, clock and CS on the interface.

Yes, the LCD display is SPI, but the keypad is matrix and it's using 8 digital pins, 22 to 29 digital pins on Mega 2560.
![](http://KeyPad
http://www.b2cqshop.com/images/thumbs/0000403_300.jpg
Display
http://www.b2cqshop.com/images/thumbs/0000321_300.jpg
Display
http://img2.mlstatic.com/modulo-lcd-84x48-nokia-5110-arduino-pic-robotica-robo_MLB-O-189303220_8161.jpg)

Hey guy's the problem is still here, i can't find a way to fix it, i made some modifications, i think the problem can be in this part of the code:

if(pegar_codigo == 3)// último menu, salva os dados no SD
  {
  lcd.setCursor(0,0);
  lcd.print(F("SALVANDO...                                                "));
  digitalWrite(4,LOW);
  digitalWrite(10,HIGH);
  
  
  
   
   myFile = SD.open(nome_arquivo, FILE_WRITE);//Abri, ou cria, o arquivo que será gravado.
  // se abrir o arquivo, vai gravar no mesmo os dados que foram coletados
  if (myFile) {
    Serial.print(F("Writing to test.txt...")); //Para uso do programador, será retirado mais afrente.
    myFile.println(F("---------------------------------------------------------------------"));
    myFile.println(F(" "));
    myFile.print(F("Setor: "));
    myFile.print(setor);
    myFile.print(F("         Hora:  "));
    myFile.print(hora2);
    myFile.print(F(":"));
    myFile.println(minuto2);
    myFile.print(F("Data: "));
    myFile.print(dia2);
    myFile.print(F("/"));
    myFile.print(mes2);
    myFile.print(F("/"));
    myFile.print(ano2);
    myFile.print(F("          Peso: "));
    myFile.print(peso);
    myFile.println(F(" Kg"));
    myFile.println(F(" "));
    myFile.println(F("---------------------------------------------------------------------"));
    myFile.close();//fecha o arquivo
    Serial.println(F("done.")); //Para uso do programador, será retirado mais afrente.
    digitalWrite(4,HIGH);
  digitalWrite(10,LOW);
    //Para uso do programador, será retirado mais afrente.
  } 
  else {
    // Se o arquivo não abrir imprime um erro na serial, debug
    lcd.print(F("Erro no SD"));
    delay(2000);
  }
  

     pegar_codigo=4;
     lcd.clear();
}

I will upload the entire code again with some modifications.

Thanks.

ver_arquivos_SD_acessar.ino (24.4 KB)

guilherme_ebio:
Yes, a use the Ethernet to browse the files on the SD card, and see the files, and i use an keyboard and some info to save the data to the SD card, like the date and the sector chosen, etc, so when a start the arduino i can see the files and browse then, but after a used the keyboard to save new data on the SD the error occurs, it's not all the time but it happens a lot.

I'm sorry, but I'm still not clear what you mean. Does "keyboard" mean "PC"? Where does "ethernet" come into this? I think you need to explain in more detail what your solution consists of and what sequence of actions you go through to cause the problem, and to avoid it.

I'm sorry, but I'm still not clear what you mean. Does "keyboard" mean "PC"? Where does "ethernet" come into this? I think you need to explain in more detail what your solution consists of and what sequence of actions you go through to cause the problem, and to avoid it.

Sorry, i will try to explain better.
The program is to help to control the amount of trash generated by some sectors, the sector are listed in the code below:

switch (codigo)// faz o cadastro dos setores na variável setor
 {    
   case 82:
  
       setor  = "UTI Adulto";  
   break;
  
    case 84:
  
       setor  = "UTI Neo-Natal";  
    break;
    
  case 88:
  
       setor = "    Pronto     Atendimento";  
   break;
   
   case 90:
      setor = "Esterilizacao";  
   break;
   
  case 74:
  
      setor  = "   Unidade    Internacao A";  
  break;
  
   case 75:
  
    setor  = "   Unidade    Internacao B";  
   break;
   
   case 76:
  
    setor = "   Unidade    Internacao C";  
   break;
   
   case 77:
  
     setor = "   Unidade    Internacao D";  
   break;
  
  case 107:
  
     setor  = "Hemodinamica";  
  break;
  
   case 79:
  
     setor  = "    Centro      Cirurgico";  
  break;
   
   case 86:
  
     setor = "Bercario";  
  
   break;
   
   case 105 :
   
      setor = "Litotripsia";  
   break;
  
   case 54:
  
      setor = "IPAC";  
          break;
   
   case 216:
  
      setor  = "Mamografia STA CLARA IMAGEM";  
  break;
  
   case 212:
      setor = "RX - Santa Clara Imagem ";
      break;
       
   case 211:
      setor = "USG - Santa Clara Imagem";
     break;
     
   case 52: 
  
  setor = "Clinicas Joao    Pinheiro";  
   break;
   
   case 51:
  
      setor = "Clinicas Santos Dumont";  
    break;
     
   case 80:
      setor = "Centro Obstetrico";  
      break;
      
     default:
     setor = " ERRO : Setor Invalido !";
     break; 
   }

So the system must store the sector choose by the user, save this sector, the date and time, and another data that will be transferred by Serial (this last part is not done yet) in the MicroSD in the Ethernet shield, and the administrator of the system must be capable of accessing this data on the SD by the Ethernet using his browser.

The keyboard is not the computer, the image of it and all the other hardware are attached below

So this is how it works, when the system turns on it ask the date and time (only the first time is turned on)
the code is here:

har key = keypad.getKey(); // variável key que armazena a tecla que foi presionada no teclado
 if(regular_relogio == 0)// caso seja a primeira vez que é ligado, ajustar relógio
  {
    if(tracos == 0){//Se tracos = 0 imprime na tela os traços onde a hora ficará depois
    lcd.setCursor(0,0);
       lcd.print(F("Entre a hora: "));
       lcd.print(F("Exemplo 08:30"));
       lcd.setCursor(0,3);
       lcd.print("    __:__");
       lcd.setCursor(0,4);
       lcd.print(F("* - Corrige"));
       tracos = 1;
  }
  if(key)
   { 
     if (key == '*')// se key = * zera as teclas e volta ao começo do menu, essa tecla é a de correção da hora
     {
     cont_3_teclas = 0;
     tracos = 0;
     }
     
     else{// vai varendo , sempre que o usuário precionar uma tecla ele pega a hr, os min, depois a data completa
     if(cont_3_teclas == 0 )// Pega a primeira tecla e imprime na tela
     {
       lcd.setCursor(0,3);
       lcd.print(F("    "));
       numero_hr_0 = key - 48;// o - 48 é para passar de string/char para int.
       lcd.print(numero_hr_0);
       lcd.print(F("_:__"));
      
     }
    if(cont_3_teclas == 1)//Pega a primeira tecla e imprime na tela
    { 
      
    numero_hr_1 = key - 48;
    lcd.setCursor(0,3);
       lcd.print(F("    "));
       numero_hr_1 = key - 48;
       lcd.print(numero_hr_0);
       lcd.print(numero_hr_1);
       lcd.print(F(":__"));
    
    }
    if(cont_3_teclas == 2)
    {
     numero_min_0 = key - 48;
     lcd.setCursor(0,3);
     lcd.print(F("    "));
     lcd.print(numero_hr_0);
       lcd.print(numero_hr_1);
       lcd.print(F(":"));
       lcd.print(numero_min_0);
       lcd.print(F("_"));
     }
     if(cont_3_teclas == 3)
    {
     numero_min_1 = key - 48;
     lcd.setCursor(0,3);
     lcd.print(F("    "));
     lcd.print(numero_hr_0);
       lcd.print(numero_hr_1);
       lcd.print(F(":"));
       lcd.print(numero_min_0);
       lcd.print(numero_min_1);
      delay(1000); 
       lcd.setCursor(0,0);
      lcd.print(F("Entre a Data: "));
      lcd.print(F("Ex: 07/09/12"));
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(F("__/__/__"));
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
         
    } 
    if(cont_3_teclas == 4)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(F("Entre a Data: "));
      lcd.print(F("Ex: 07/09/12"));
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(F("__/__/__"));
      numero_dia_0 = key - 48;
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(numero_dia_0);
      lcd.print(F("_/__/__"));
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
         
     }
     if(cont_3_teclas == 5)
     {
      numero_dia_1 = key - 48;
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(numero_dia_0);
      lcd.print(numero_dia_1);
      lcd.print(F("/__/__"));
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
         
     }
     
     if(cont_3_teclas == 6)
     {
      numero_mes_0 = key - 48;
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(numero_dia_0);
      lcd.print(numero_dia_1);
      lcd.print(F("/"));
      lcd.print(numero_mes_0);
      lcd.print(F("_/__"));
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
         
     }
     
     if(cont_3_teclas == 7)
     {
      numero_mes_1 = key - 48;
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(numero_dia_0);
      lcd.print(numero_dia_1);
      lcd.print(F("/"));
      lcd.print(numero_mes_0);
      lcd.print(numero_mes_1);
      lcd.print(F("/__"));
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
         
     }
     
     if(cont_3_teclas == 8)
     {
      numero_ano_0 = key - 48;
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(numero_dia_0);
      lcd.print(numero_dia_1);
      lcd.print(F("/"));
      lcd.print(numero_mes_0);
      lcd.print(numero_mes_1);
      lcd.print(F("/"));
      lcd.print(numero_ano_0);
      lcd.print(F("_"));
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
         
     }
    if(cont_3_teclas == 9)
     {
      numero_ano_1 = key - 48;
      lcd.setCursor(0,3);
      lcd.print(F("    "));
      lcd.print(numero_dia_0);
      lcd.print(numero_dia_1);
      lcd.print(F("/"));
      lcd.print(numero_mes_0);
      lcd.print(numero_mes_1);
      lcd.print(F("/"));
      lcd.print(numero_ano_0);
      lcd.print(numero_ano_1);
      lcd.setCursor(0,4);
      lcd.print(F("* - Corrige"));
      delay(1000);
      lcd.clear();
      regular_relogio = 23;// Acaba a parte de regular o relógio, logo podemos seguir em frente com os menus          
      hr = (numero_hr_0 * 10) + (numero_hr_1);// passa os dados digitados para números inteiros, 1 e 0 para 10.
      minuto =  (numero_min_0 * 10) + (numero_min_1); 
      dia = (numero_dia_0 * 10) + (numero_dia_1);
      mes = (numero_mes_0 * 10) + (numero_mes_1);
      ano = (numero_ano_0 * 10) + (numero_ano_1);
      setTime(hr,minuto,0,dia,mes,ano);// impõe a hora e a data no arduino como sendo a hr e a data que foram entradas na sistema.
      
   }
    
    
    
    cont_3_teclas = cont_3_teclas + 1;// vai incrementando a variável que controla os menus, essa parte do programa inteira só roda quando a pessoa preciona uma tecla
   }
  }}

So after this the program asks if the user wants to get the weigh of the trash,

 if (regular_relogio == 23)
 {
  if(cont_pesagem_tela == 0){
  lcd.clear(); 
  lcd.setCursor(0,0);  
  lcd.println(F("Realizar       pesagem?"));
  lcd.println(F("        A - Sim"));
 cont_pesagem_tela = 1;  
}
 if(key)
  {
  if(key == 'A')
  {
  regular_relogio = 2;
  

  }
 }}

Sorry the other images are attach here,
So the codes continue, if the person put A in the keyboard the program ask the code of the sector

and compares it to the fist list and code i put whit the sectors

if(regular_relogio == 2)// Se já acabou de regular relógio, ou se ele já está regulado
  { 
    if(pegar_codigo == 0)// Pegar os codigos(Menu códigos inicial)
    {
    lcd.setCursor(0,0);
    lcd.print(F("Entre o Codigo"));
    lcd.setCursor(0,1);
    lcd.print(F("   do setor:"));
    lcd.setCursor(0,2);
    if(cont_print_uma_vez == 0){
    lcd.print(F("      ___                  "));
  cont_print_uma_vez = cont_print_uma_vez +1 ;}
    if (key)
    { if (key == '*')// corrige os dados reiniciando o menu
     {
     cont_setor = 1;
     lcd.print(F("      ___"));
     }
     else if(key == '#') // COnfirma a código e vai para o próximo menu
     {
      cont_setor = 4;
      pegar_codigo = 1;
      lcd.clear();
     }
      else
      {
      if(cont_setor == 1)
      {
       setor_1 = key;
       lcd.setCursor(0,2);
       lcd.print(F("      "));
       lcd.print(F("__"));
       lcd.print(setor_1);
      }
      if(cont_setor == 2)
      {
      setor_2 = setor_1; 
      setor_1 = key;
      lcd.setCursor(0,2);
       lcd.print(F("      "));
       lcd.print(F("_"));   
       lcd.print(setor_2);
       lcd.print(setor_1);
    
      }
      if(cont_setor == 3)
      {
      setor_3 = setor_2;
      setor_2 = setor_1;  
      setor_1 = key;
      lcd.setCursor(0,2);
       lcd.print(F("      "));
       lcd.print(setor_3);
       lcd.print(setor_2);
       lcd.print(setor_1);  
    }
     cont_setor = cont_setor + 1;
      }
    }
  }
  if(pegar_codigo == 1)//pega os valores que o usario digitou e trasforma elas no codigo
  {int setor1 = setor_1 - 48;
   int setor2 = setor_2 - 48;
   int setor3 = setor_3 - 48;
   codigo = (setor3 *100)+ (setor2*10) + (setor1);
   lcd.setCursor(0,0);

It converts the codes in char to int, so that's why the -48.

so it asks for confirmation, and if the sector in invalid or wrong it returns and asks to the code of the sector again

lcd.print(F("Confirma ?"));// menu de confirmação do setor selecionado
   lcd.setCursor(0,1);
   lcd.print(setor);
   lcd.setCursor(0,3);
   lcd.print(F("A - S / B - N"));
  
             
           if(key == 'B')// Se B não confirma e volta ao menu código inicial
           {
           pegar_codigo = 0;// Reinicia os contadores para voltar no menu códigos inicial
           cont_print_uma_vez= 0;
           cont_setor = 1;
            setor_1 = '0';// Reinicia os valores
   setor_2 = '0';
   setor_3 = '0';
           }
           else if(key == 'A')// se confirmar com A o programa pode seguir, e verificar
           {
              if(setor == " ERRO : Setor Invalido !")// se o setor for inválido e a pessoa confirmar, volta ao menu código inicial
              {pegar_codigo = 0;
           cont_print_uma_vez= 0;
           cont_setor = 1;
       setor_1 = '0';// Reinicia os valores
   setor_2 = '0';
   setor_3 = '0';  
       }
           else{// caso a pessoa confime e o setor for válido, o programa procede para o próximo menu.
           pegar_codigo = 2;
           lcd.clear();
         } }
  }

0000403_300.jpg

0000321_300.jpg

modulo-lcd-84x48-nokia-5110-arduino-pic-robotica-robo_MLB-O-189303220_8161.jpg

So it asks for the person to weigh trash, () not done yet

  if(pegar_codigo == 2)
  {
    lcd.setCursor(0,0);
   lcd.print(F("Pese o lixo e"));
  lcd.setCursor(0,1);
 lcd.print(F("Clique o botao"));
 lcd.setCursor(0,2);
 lcd.print(F("Envia na balanca"));
 lcd.setCursor(0,3);
 lcd.print(F("# - Confirma"));
 if(key)
 {
 if (key == '#')
 {
 peso = 150;
 pegar_codigo = 3;
 }
 }
 
  }

And after this it saves all on the MicroSD

if(pegar_codigo == 3)// último menu, salva os dados no SD
  {
  lcd.setCursor(0,0);
  lcd.print(F("SALVANDO...                                                "));
  digitalWrite(4,LOW);
  digitalWrite(10,HIGH);
  
  
  
   
   myFile = SD.open(nome_arquivo, FILE_WRITE);//Abri, ou cria, o arquivo que será gravado.
  // se abrir o arquivo, vai gravar no mesmo os dados que foram coletados
  if (myFile) {
    Serial.print(F("Writing to test.txt...")); //Para uso do programador, será retirado mais afrente.
    myFile.println(F("---------------------------------------------------------------------"));
    myFile.println(F(" "));
    myFile.print(F("Setor: "));
    myFile.print(setor);
    myFile.print(F("         Hora:  "));
    myFile.print(hora2);
    myFile.print(F(":"));
    myFile.println(minuto2);
    myFile.print(F("Data: "));
    myFile.print(dia2);
    myFile.print(F("/"));
    myFile.print(mes2);
    myFile.print(F("/"));
    myFile.print(ano2);
    myFile.print(F("          Peso: "));
    myFile.print(peso);
    myFile.println(F(" Kg"));
    myFile.println(F(" "));
    myFile.println(F("---------------------------------------------------------------------"));
    myFile.close();//fecha o arquivo
    
//    digitalWrite(4,HIGH);
//    digitalWrite(10,LOW);
    //Para uso do programador, será retirado mais afrente.
  } 
  else {
    // Se o arquivo não abrir imprime um erro na serial, debug
    lcd.print(F("Erro no SD"));
    delay(2000);
  }
  

     pegar_codigo=4;
     lcd.clear();
}
  
  
  if(pegar_codigo == 4)
  {
  lcd.print(F("Salvo!"));
  delay(1000);
  lcd.clear();
  pegar_codigo = 0;
  cont_print_uma_vez= 0;
  cont_setor = 1;
  setor_1 = '0';// Reinicia os valores
  setor_2 = '0';
  setor_3 = '0';  
  cont_pesagem_tela = 0;
  regular_relogio = 23; 
  }

The other parts o fthe code are this one taking care of the time:

// Faz a contagem do tempo para mostrar e para salvar no SD 
time_t tempo = now();
hora2 = hour(tempo);
minuto2 = minute(tempo);
int segundo2 = second(tempo);
dia2 = day(tempo);
mes2 = month(tempo);
ano2 = year(tempo);
if(segundo2 == 0)// Limpar a tela para não ter lixo no relógio
{
lcd.setCursor(0,4);
lcd.print("                 ");
}
//Plota a hora e a data no display.
lcd.setCursor(0,4);
lcd.print(hora2);
lcd.print(F(":"));
lcd.print(minuto2);
lcd.print(F(":"));
lcd.print(segundo2);
lcd.setCursor(0,5);
lcd.print(dia2);
lcd.print(F("/"));
lcd.print(mes2);
lcd.print(F("/"));
lcd.print(ano);

// Faz operações para pega ros numeros de mês e ano para tranformar em string e usar como nome do arquivo a ser gerado de log
itoa(ano,pasta_ano,10);
itoa(mes2,nome_arquivo2,10);

if (mes2 < 10)
{
nome_arquivo2[1]=nome_arquivo2[0];
nome_arquivo2[0]= '0';
}
if (ano < 10)
{
pasta_ano[1]=pasta_ano[0];
pasta_ano[0]='0';
}

This one to save the file on the SD with the name containing Month_Year.log

nome_arquivo[0]=nome_arquivo2[0];
nome_arquivo[1]=nome_arquivo2[1];
nome_arquivo[2]='_';
nome_arquivo[3]=pasta_ano[0];
nome_arquivo[4]=pasta_ano[1];
nome_arquivo[5]='.';
nome_arquivo[6]='l';
nome_arquivo[7]='o';
nome_arquivo[8]='g';

This function to find and list the files on the SD and transform then int links in the HTML

void printDirectory(File dir, int numTabs, EthernetClient client) {
  
  dir.rewindDirectory();
  while(true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // Significa que já não tem nenhum arquivo para ser lido
      
      break;
    }
//    for (uint8_t i=0; i<numTabs; i++) {
//      Serial.print('\t');
//      
//  }
    client.print(F("<li><a href=\""));  
    client.print(entry.name());
    
    Serial.print(entry.name());
    client.print(F("\">"));
    client.print(F("<ul>"));
    client.print(entry.name());
    client.print(F("</a>"));
    if (entry.isDirectory()) {
      Serial.println(F("/"));
      
      printDirectory(entry, numTabs+1, client);
    } 
    else {
     
      client.print('.');
      Serial.print(F("\t\t"));
      Serial.println(entry.size(), DEC);
      client.print(entry.size(),DEC);
      client.print(F(" bytes"));
      client.print(F("</ul>"));
      
      
  }
    // fecha o arquivo q foi aberto
    entry.close();
  }
}

this one to show the free ram

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

And for last the one responsible for the hole Ethernet connection

//Serial.println(freeRam());
  char clientline[BUFSIZ];// cria avariável para armazenar os dados enviados pelo cliente ethernet
  int index = 0;// Auxilia no armazenamento dos dados enviados pelo cliente ethernet
  EthernetClient client = server.available();// cria o objeto cliente, como sendo disponível
  
  if (client) {
   
boolean currentLineIsBlank = true;// checa se a linha é vazia, opções do HTTP/HTML

index = 0; // Zera a variável index, que anda no vetor clientline para sempre pegar. 

 while (client.connected())// Enquanto cliente conectado
    {
    if (client.available())// Se o cliente estiver disponível
    {
      char c = client.read();// Lê caracter por caracter do request do cliente
      if(c != '\n' && c != '\r') // verifica se o caracter é \n ou \r, se nao for significa que tem dados a ler, se for pode pular fora do loop
      {
      clientline[index] = c;// armazena cada caracter que o cliente manda em um buffer para criar a string
      index++;
      
      if (index >= BUFSIZ) // Se o index ultrapassar o tamanho do BUFSIZ faz index = BUFSIZ e descarta o resto dos dados
         index = BUFSIZ - 1;
       
       continue;
      }
      clientline[index] = 0;//faz o último caracter do vetor clientline nulo, para o programa reconhecer que o vetor acaba ali
      
      Serial.println(clientline);// imprime na serial oque o cliente solicitou, para debug
      
      if (strstr(clientline, "GET / ") != 0) // Procura na  string que o cliente enviou o comando GET / se achar:
      {
      client.println(F("HTTP/1.1 200 OK"));// Envia menssagens padrão de conecção aceita e OK
      client.println(F("Content-Type: text/html"));
      client.println();
      client.print(F("<center>"));
      client.println(F("<h1>Hospital e Maternidade Santa Clara<h1>"));// Imprime na página a frase centrada
      client.print(F("</center>"));
      client.print(F("<center>"));
      client.println(F("<h1>Controle de dejetos Infectantes<h1>"));// Imprime na página a frase centrada
      client.print(F("</center>"));
      client.print(F("<center>"));
      client.println(F("<h1>Arquivos no SD: <h1>"));// Imprime na página a frase centrada
      client.print(F("</center>"));
      
      root = SD.open("/");// DEfine a variável root como sendo a entrada root do cartão

      printDirectory(root, 0, client);// chama a função que escaneia todo o SD procurando todos os arquivo e os imprime na tela do client já como links    
      }
      
      else if (strstr(clientline, "GET /") != 0)// caso encontre a GET / sem espaço depois significa que estará solicitando algum arquivo, 
      {
       char *filename;
       
       filename = clientline + 5;// então salvamos essa solicitação de arquivo em outra variável com um pequeno truque para pegar o nome do arquivo
       
       (strstr(clientline, " HTTP"))[0] = 0; // Então anulamos a substring HTTP
       
       Serial.println(filename);// Debug
       
       if(!SD.open(filename))// Se não conseguirmos abrir o arquivo solicitado enviamos uma menssagem padrão de erro
       {
            client.println(F("HTTP/1.1 404 Not Found"));
            client.println(F("Content-Type: text/html"));
            client.println();
            client.println(F("<h2>File Not Found!</h2>"));
            break;
       }
       if(regular_relogio != 2){
        Serial.println(F("Opened!"));// caso contrário enviamos uma menssagem padrão de OK 
 
          client.println(F("HTTP/1.1 200 OK"));
          client.println(F("Content-Type: text/plain"));
          client.println();
          
          myFile = SD.open(filename);// Abrimos o arquivo que foi solicitado
          if(!myFile) Serial.println(F("file open failed"));
          
          int8_t c;
          while(myFile.available())
          {
            if(parar_erro == 20)
            {
              Serial.println(F("Erro, o cartão retornou está em loop !"));
            delay(4000);
            break;
            parar_erro == 20
            }
           char buffer_arquivo[20];
           int k = 0;
           
           while(k < 20)
           { 
           
             c = myFile.read();
           
           if(c == -1)
           {
            Serial.println(F("Erro, o cartão retornou -1 !"));
           parar_erro ++;
           break;
           
           }
           buffer_arquivo[k] = char(c);
           k++;
           if(k == 20){
             
            for (int i=0; i < 20; i++)
            {
           client.print(buffer_arquivo[i]);
           Serial.print(buffer_arquivo[i]);
           }
         }
        
        
         //Serial.println((char) c);//Dai imprimimos na tela do cliente e na serial tudo que tem no arquivo
          }}
          myFile.close();// fecha o arquivo do SD que fora aberto 
      }
      if(regular_relogio == 2)
      {
      client.print(F("Equipamento atualmente em uso, ou travado na tela errada! 
 Caso esse erro persista cheque o equipamento"));
      }}
      
      else// Qualquer outra coisa é a menssagem padrão de não encontrado
      {
          client.println(F("HTTP/1.1 404 Not Found"));// Código padrão HTTP para página não encontrada
          client.println(F("Content-Type: text/html"));// Código padrão HTTP, para tipo html de texto
          client.println();// pula uma linha, navegador saber que a parte de códigos, hand_shake, acabou.
          client.println(F("<h2>Arquivo Não Encontrado!</h2>"));// Plota na tela a menssagem de arquivo não encontrado 
      }
      break;
           }
    }
 // Delay para que o cliente tenha tempo para receber os dados 
    delay(1);
    // encerra a conexão
    client.stop();
}

Here are my setup

void setup() //Função setup padrão, roda apenas uma vez, basicamente uma função para configurações 
{
Serial.begin(9600);// Inicializa a comunicação USD na velociade 9600 
lcd.begin(84,48); // Inicializa o display de 84X48 pixels
pinMode(10, OUTPUT);// Pôe o pino dez como saída
digitalWrite(4, LOW);// põe o pino quatro em baixo
  digitalWrite(10,HIGH);// e o dez em alto, para iniciar e configurar o cartão SD
if (!SD.begin(4)) {
    Serial.println(F("Erro na inicializacao do SD"));// Printa na USB-serial caso o SD não seja iniciado
    return;
  }
Serial.println(F("SD iniciado com sucesso"));// caso o SD seja iniciado com sucesso mostra isso no serial-USB


Ethernet.begin(mac, ip); // Inicializa o Ethernet
 server.begin();// Inicializa o servidor
 Serial.print(F("server is at "));// imprime na serial USB o endereço do servidor
 Serial.println(Ethernet.localIP());
}

And finally all my library's and variables:

// incluindo as bibliotecas do relogio do teclado e do display
#include <Time.h>// inclui a biblioteca de tempo, para as datas e horas
#include <Keypad.h>// inclui a biblioteca para o teclado de menbrana
#include <PCD8544.h>// inclui a biblioteca do LCD Nokia 5510, será substituida em breve
#include <SD.h>// inclui a biblioteca do cartão SD
#include <SPI.h>// Inclui a biblioteca SPI para o display, o ethernet, e o SD
#include <Ethernet.h>// Inclui a biblioteca Ethernet
#define BUFSIZ 100 // Váriável para leitura dos dados do cartão e para posterios impressão na página via Ethernet

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };// endereço MAC do equipamento (Pode ser alterado)
IPAddress ip(10,200,0,99);// Endereço IP do equiopamento, depende da rede.

byte gateway[] = { 10, 200, 7, 254 };   // Gateway padrão da rede a que a equipamento está conectado, opcional.
byte subnet[]  = { 255, 255, 248, 0 }; // Mascara de subrede.

EthernetServer server(80);// porta de comunicação do servidor, 80 padrão HTML
File myFile;// Definindo o objeto myFile, que será utilizado para operações do SD
File root;// Definindo o objeto root, que é o root do directório SD

const byte ROWS = 4; //quatro linhas do teclado de membrana
const byte COLS = 4; //quatro colunas do teclado de menbrana
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};// Mapeando a matriz do teclado com as teclas que eu quero, podem ser as mesmas do teclado ou podem ser diferentes.
byte rowPins[ROWS] = {29, 28, 27, 26}; //(De 1 a 4), são os pinos das linhas, nos quais o teclado está conectado fisicamente com o Mega
byte colPins[COLS] = {25, 24, 23, 22}; //(De 5 a 8),  são os pinos das colunas, nos quais o teclado está conectado fisicamente com o Mega
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);//inicializando o tecladocom todas as variáveis definidas anteriormente 
static PCD8544 lcd;// definindo o objeto do lcd
String setor;// Variável que guarda o setor que foi escolhido
int cont_3_teclas = 0;// variável para ir contando e ir pegando os números das datas e hora
int numero_hr_0;// variaveis para armezenar datas e horas no formato 00:00:00 e 00/00/00, porém pegando número a número
int numero_hr_1;
int numero_min_0;
int numero_min_1;
int numero_dia_0;
int numero_dia_1;
int numero_mes_0;
int numero_mes_1;
int numero_ano_0;
int numero_ano_1;
// variáveis para juntar as anteriores e deixar no formato xx.
int hr;
int minuto;
int dia;
int mes;
int ano;
int tracos = 0;// variável para plotar inicialmente , antes de clicar qualquer key.
int regular_relogio = 0;// Variável para saber se é a primeira ligada e ajustar o relógio
char setor_1 = '0';// variável do primeiro numero do codigo do setor
char setor_2 = '0';// variável do segundo numero do codigo do setor
char setor_3 = '0';// variável do terceiro numero do codigo do setor
int cont_setor = 0;// Váriávle de auxpilio para pegar cada um dos três números do código do setor, e auxiliar no menu de setor
int cont_print_uma_vez = 0;// Váviávle de auxílio para imprimir no display
int pegar_codigo = 0;// Variável de auxílio para mudança de menus, e correção de dados errado.
int codigo;// pega os três números dos setor e junta eles em um código, depois compara para saber qual setor corresponde o código
int  hora2;//Armazena a hora pega em um instante.
int minuto2;//
int dia2;//
int mes2;//
int ano2;//
int peso;// Armazena o peso que a balança envia
char pasta_ano[2];//Armazena o Ano em um string de char
char nome_arquivo2[2];//Armazena o Mês em um string de char
char nome_arquivo[10];//Armazena o Nome final do arquivo que é gerado na forma MM_AA.log
int cont_pesagem_tela = 0;
int parar_erro = 0;

i guess that's all, i will also put the entire code attach to here. thanks a lot guys.

ver_arquivos_SD_acessar.ino (24.4 KB)

So the problem happens when the code is here:

while(myFile.available())
          {
            if(parar_erro == 20)
            {
              Serial.println(F("Erro, o cartão retornou está em loop !"));
            delay(4000);
            break;
            parar_erro == 20
            }
           char buffer_arquivo[20];
           int k = 0;
           
           while(k < 20)
           { 
           
             c = myFile.read();
           
           if(c == -1)
           {
            Serial.println(F("Erro, o cartão retornou -1 !"));
           parar_erro ++;
           break;
           
           }
           buffer_arquivo[k] = char(c);
           k++;
           if(k == 20){
             
            for (int i=0; i < 20; i++)
            {
           client.print(buffer_arquivo[i]);
           Serial.print(buffer_arquivo[i]);
           }
         }

But only after i have saved files to the SD in the section, i mean the error occurs only after this code happens:

if(pegar_codigo == 3)// último menu, salva os dados no SD
  {
  lcd.setCursor(0,0);
  lcd.print(F("SALVANDO...                                                "));
  digitalWrite(4,LOW);
  digitalWrite(10,HIGH);
  
  
  
   
   myFile = SD.open(nome_arquivo, FILE_WRITE);//Abri, ou cria, o arquivo que será gravado.
  // se abrir o arquivo, vai gravar no mesmo os dados que foram coletados
  if (myFile) {
    Serial.print(F("Writing to test.txt...")); //Para uso do programador, será retirado mais afrente.
    myFile.println(F("---------------------------------------------------------------------"));
    myFile.println(F(" "));
    myFile.print(F("Setor: "));
    myFile.print(setor);
    myFile.print(F("         Hora:  "));
    myFile.print(hora2);
    myFile.print(F(":"));
    myFile.println(minuto2);
    myFile.print(F("Data: "));
    myFile.print(dia2);
    myFile.print(F("/"));
    myFile.print(mes2);
    myFile.print(F("/"));
    myFile.print(ano2);
    myFile.print(F("          Peso: "));
    myFile.print(peso);
    myFile.println(F(" Kg"));
    myFile.println(F(" "));
    myFile.println(F("---------------------------------------------------------------------"));
    myFile.close();//fecha o arquivo
    
//    digitalWrite(4,HIGH);
//    digitalWrite(10,LOW);
    //Para uso do programador, será retirado mais afrente.
  } 
  else {
    // Se o arquivo não abrir imprime um erro na serial, debug
    lcd.print(F("Erro no SD"));
    delay(2000);
  }
  

     pegar_codigo=4;
     lcd.clear();
}

And it happens only some times, its not all the times.

Thanks again, and i hope you guys can help me.