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.
Tags:
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 possibilidade: linhas 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 possibilidade: linhas 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.
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
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]);
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por