Boa tarde.

  Estou tentando ler os dados de um cartão SD em um arquivo texto que contém 4 linhas :

   80
   60
   40
   20

   Utilizo a pequena rotina abaixo :

MyFile = SD.open("teste.txt");
if (MyFile) {
while (MyFile.available()) {
A = MyFile.read();
B = MyFile.read();
C = MyFile.read();
D = MyFile.read();
}
MyFile.close();
}else{
Serial.println("ERRO");
}

A,B,C e D são Strings e   File  =  MyFile 

 Quando mando printar na Serial ele retorna para A,B,C e D :

  50
  48
  13
   -1

   E não faço ideia de onde o programa acima tira isso.

   Algum consegue me dizer onde está meu erro ?

   Grato desde já por qualquer ajuda.

Exibições: 1088

Responder esta

Respostas a este tópico

olá César.

      Dai a César o que é de César.

      Pois é,  é por isso que está ocorrendo isso no seu código:  ele está te dando de volta exatamente o que vc fez antes no seu arquivo.  Mas brincadeiras à parte, isso está ocorrendo de fato. Então vejamos o porquê:

      Vc disse:  "não faço ideia de onde o programa acima tira isso".

      Então César, ele tira exatamente do seu arquivo, e estes números estão lá, conforme mostro mais à frente.

      Mas antes, de mostrar isso,  é preciso que vc entenda que está lendo os dados de forma inadequada para o que aparentemente vc pretende.  O  loop "while"  da  forma  que vc o implementou,  fica lendo indefinidamente o arquivo,  até que  chegue ao fim do próprio arquivo. Assim, mesmo depois que vc já leu o suficiente e atribuiu essas leituras às variáveis "A, B, C, D",  o seu loop  ainda  continua lendo o arquivo, e quando o arquivo chega ao fim,  o "MyFile.read()" retorna o último valor,  que será o "-1".  Vc deve estar se perguntando e de onde vem esse "-1" ?   Veja o link a seguir, da referência do Arduino  classe "SD", na parte "Returns":   "read SD()"

      Então é preciso alterar como o loop "while" está operando no seu código (ou seja, a lógica usada ali).

      Agora vejamos de onde saíram os valores que foram "printados".  Eu já tinha dito que saíram do seu próprio arquivo "txt".  E claro, esse arquivo vc criou em algum momento. Quando isso ocorreu, haviam duas possibilidades para a finalização de cada linha de texto do arquivo, as quais são:

      1) primeira possibilidadelinhas terminadas com caracteres <CR> e <LF>  (ou em C++, o "\r" e "\n" respectivamente).  O <CR> é o caracter ASCII  "Carriage Return",  e o <LF> é o "Line Feed", e os seus códigos ASCII correspondentes em Hexadecimal são o 0x0D (ou "13" em decimal) e o 0x0A (ou "10" em decimal).

          Se seu arquivo "txt" tivesse sido criado desta forma, então ao "destrincharmos"  este arquivo byte a byte, encontraremos o que mostra a figura a seguir:

(clique na figura para "zoom")

          E nesse caso, os três últimos "valores" que seriam lidos do arquivo, seriam os que estão marcados em amarelo na figura anterior (48, 13, e 10).

      2) segunda possibilidadelinhas terminadas apenas com o caracter <CR>  (ou em C++, o "\r").  O <CR> é o caracter ASCII "Carriage Return", e o seu código ASCII  correspondente em Hexadecimal  é o 0x0D (ou "13" em decimal).

        Se seu arquivo "txt" foi criado desta forma, então ao "destrincharmos"  este arquivo byte a byte, encontraremos o que mostra a figura a seguir:

(clique na figura para "zoom")

      Então é isso:  é  a  segunda possibilidade  que está ocorrendo no seu caso. Veja na figura anterior os valores 50, 48 e 13,  que são os últimos três a serem lidos do arquivo (e foram atribuídos respectivamente às variáveis "A", "B", e "C").  E o último valor "printado"  não é um caracter lido do arquivo:  ele é o "-1"  informando que o arquivo terminou, e vc acabou atribuindo este "-1" à sua variável "D".

      E claro, embora as variáveis  "A", "B", "C", e "D" sejam Strings,  o "auto casting" da linguagem C++  converte para String  os valores lidos do arquivo,  já que seu código está ordenando isso.

     Ideia é o que não falta por aqui, então certamente o pessoal que colabora aqui irá te ajudar a "corrigir" isso, caso seja da vontade de César.

      Mas minha sugestão é que vc mesmo analise a coisa,  por motivos de aprendizado,  e assim consiga que seu código execute o que vc deseja.

      Abrçs,

      Elcids

Entendi perfeitamente e vou tentar implementar o código de forma correta.

Muito grato por toda a explicação.

  O arquivo a ser lido eu crio via programação . Neste exemplo, veja o que ocorre :

MyFile = SD.open("teste.txt", FILE_WRITE);
if (MyFile) {
MyFile.print("20;40;60;80")
MyFile.close();

Quando leio via código , a serial devolve :

MyFile = SD.open("teste.txt");
if (MyFile) {
while (MyFile.available()) {
Serial.write(MyFile.read());
}
MyFile.close();
}else{
Serial.println("ERRO");

}

Resultado na Serial :

20;40;60;80;
0
0
0

De onde ele tira as 4 inserções no arquivo? Se eu mandei ele inserir apenas 1 linha no arquivo?

Ele não deveria retornar apenas 20;40;60;80; ?  Como escrevo no arquivo para ele incluir apenas 1 linha como no exemplo e mais nada?   Agradeço desde já qualquer ajuda.

 Alguém possui  um Sketch exemplo para esse meu problema ? Grato.

Boa noite Sr. CC,

o que está ocorrendo nesta sua nova tentativa de gravar, é que possivelmente

existem mais dados no seu SD card, e ao ler está também imprimindo novas linhas.

Este sketch que estou postando, ele apaga qq possível arquivo que tenha no seu SD card,

em seguida cria um teste.txt novo e grava os dados 80;60;40;20 nele.

Experimente este sketch e depois conte o resultado pra gente.

https://pastebin.com/ecD2REni

RV

 Boa noite.  Caramba, matou de primeira o problema. Perfeito!

 Muito grato mesmo.

 Abs

Desculpe minha falta de conhecimento. Seu código retorna certinho os 4 valores do arquivo (eu somente alterei no código para me mostrar em linhas (println) os 4 valores.

 Porém, eu tento neste momento capturar cada um dos valores associando a uma variável (A,B,C,D) mas embora mostre os valores na Serial direitinho, as variáveis só retornam = 0.

  Como associo esse valores lidos do arquivo a cada uma dessas variáveis? Nesse seu código, consegue me passar um exemplo qualquer?  Grato por qualquer ajuda desde já.

Bom dia Sr. 2C,

seria interesante que o Sr. detalha-se melhor seu projeto.

A razão desta necessidade  é para que possamos entender melhor a forma destes dados e como os

são gerados.

Vou explicar as diferenças de dados.

Qdo voce diz que em um arquivo no SD car vão ter os valores 80, 60, 40 e 20, podemos entender de

3 formas.

vamos detalhar:  80 decimal é  o valor hexadecimal 50,  80 hexadecimal é o valor decimal 128,  e 80

com dois dígitos é a composição do valores 8 e 0   que são respectivamente os valores

hexadecimais 50(hexa38) e 48 (hexa30)..

Se estes valores foram escritos da forma que coloquei no sketch exemplo que escrevi, ao você abrir

o SD card no windows, vai ler 80;60;40;30.

Ao ler com o sketch vai obter os seguintes dados  " 5048595248595448595648 ", 

50 = 8, 48 = 0  = 80  e  59 = ;  52 = 6. 48 = 0 e 59 =; e assim por diante.

Para conseguir ler estes dados e separa-los da forma que voce precisa, tive que fazer uma "gambiara de software"

Teste este sketch abaixo e veja se consegue entender o que fiz e se ele atende sua necessidade .

RV

https://pastebin.com/ecD2REni

  Consegui adequar seu código ao meu e me atendeu perfeitamente.

  Muito grato.

 

Bom, pela descrição da sua postagem, imagino que queira pegar os dados que vão está fixos no arquivo, talvez para ser usado como parâmetros, caso seja isso, fiz um exemplo (dois na verdade). 

Montei um código para salvar dois arquivos no SD, um para armazenar os dados separados por ponto e vírgula, outro para armazenar os dados em cada linha, o código ficou assim:

https://pastebin.com/Kucgs9Jn

Já na parte da leitura, fiz um único código capaz de ler ambos os arquivos e colocar os valores lidos em um array, o mesmo ficou assim:

https://pastebin.com/SDeq00Qf

(Lembrando que você deve especificar qual arquivo quer abrir)
Espero que lhe ajude de alguma forma. Grande abraço!

   Bom dia Eduardo

   Excelente seu código, muito obrigado.

   A única coisa que não consegui foi como gravar os dados do array (depois de já manipulados) novamente no cartão usando sua função criarArquivo()  (gravação dos dados em linhas)

   Eu tentei assim, mas não roda ...   criarArquivo("teste.txt", DADOS_SD[0]+'\n'+DADOS_SD[1]+'\n'+DADOS_SD[2]+'\n'+DADOS_SD[3]); 

   Agradeço desde já qualquer ajuda.
   

Você não pode usar aspas simples na hora de concatenar, precisa ser aspas duplas, observe que a função espera uma String. Quando você usa a aspas simples ele entende como char e ocorre uma ambiguidade.

Deve ser assim:

criarArquivo("teste.txt", DA...[0] + "\n" + DA...[1] + "\n" + DA...[2] + "\n" + DA...[3]); 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço