Como leer datos de una SD?

Hola, mi nombre es Santiago estoy utilizando el arduino DUE y tengo el siguiente problema: Necesito guardar 18 valores de unas variables de calibración de un sensor en una tarjeta SD, los cuales varían entre 0-250. Al imprimirlos a la SD con SD.println(valor); los datos quedan de la siguiente manera:

15 18 117 ...etc.

Luego de apagar el equipo y volver a encenderlo necesito tomar esos datos e introducirlos en nuevas variables para no tener que volver a realizar el proceso de calibración. El problema es que no sé como leer todas las líneas y guardar los valores. Estuve leyendo posts de este tema: https://forum.arduino.cc/index.php?topic=127073.0

Pero sigo sin entender como hacerlo, se que debo armar dos arrays, uno de char y otro de eteros e ir leyendo el documento guardarlo en el array de char y luego pasarlos al de enteros convirtiéndolo. Pero necesito si alguien me puede poner un ejemplo de lo anterior ya que no domino la programación.

Muchas gracias. Santiago.

Hola Azzimutt, aqui tienes una pagina para aprender;

http://www.educachip.com/como-leer-y-escribir-datos-en-la-tarjeta-sd-de-arduino/

Suerte!

Gracias, estuve leyendo pero no se como implementarlo a lo que yo necesito, ya que en dicha página solo muestra como leer lo que está en el archivo y mostrarlo todo en el monitor serial y no como leer línea por línea para guardar la información.

Saludos.

Hola, mira supongamos que tienes la siguiente secuencia grabada en el SD en un archivo “datos.txt”

18,255,1,24,156,23,123,200,21,12,34,23,33,77,88,99,11,100,

asi, tal cual separado por comas y finalizando en una coma (esos son los 18 datos)

Bueno, el siguiente codigo es ridiculo pues como no conozco bien como pasar ASCII a numeros hice lo siguiente que igual funciona bien. Espero que te sirva, saludos.

#include <SPI.h>
#include <SD.h>

File f;
int num;
int a,b;
int aux[4];
int dato[19];

void setup() {
 Serial.begin(9600);
//------------------------------------------------
 Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
//------------------------------------------------
f = SD.open("datos.txt");
//------------------------------------------------  
}

void loop() {
while (f.available()) {
     
      delay(100);
      a=a+1;
      num = int(f.read());
         if (num == 49) {aux[a]=1;}  
         if (num == 50) {aux[a]=2;}
         if (num == 51) {aux[a]=3;}  
         if (num == 52) {aux[a]=4;}
         if (num == 53) {aux[a]=5;}  
         if (num == 54) {aux[a]=6;}
         if (num == 55) {aux[a]=7;}  
         if (num == 56) {aux[a]=8;}
         if (num == 57) {aux[a]=9;}  
         if (num == 48) {aux[a]=0;}

         if (num == 44)  {
         b=b+1;
         Serial.println("-----");
         if (a == 2) {dato[b]= aux[1]; }
         if (a == 3) {dato[b]= aux[1]*10+aux[2]; }
         if (a == 4) {dato[b]= aux[1]*100+aux[2]*10+aux[3]; }
         
         Serial.println(dato[b]);
         aux[1]=0;
         aux[2]=0;
         aux[3]=0;
         a=0;                              
         }
    } 

 f.close();
}

Los números de ASCCI se pasan simplemente restando '0' Si recibes algo en la variable num y contiene un ASCCI pues simplemente lo tendras asi en decmal

 num = f.read()-'0'; // en decimal

surbyte: Los números de ASCCI se pasan simplemente restando '0' Si recibes algo en la variable num y contiene un ASCCI pues simplemente lo tendras asi en decmal

 num = f.read()-'0'; // en decimal

Oh, que maravilla!, claro porque cero es 48

gracias

Dices que no sabes cómo leer línea por línea, pues es muy simple.

En tu ejemplo anterior colocaste comas para separar números, lo mismo ocurre con las líneas de texto. Ahora quizá te preguntes: ¿qué es lo que las separa? A igual que las comas, existe un caracter (o dos) que cumple esa misma función: marcar donde termina una línea y empieza la otra.

En consolas y editores de texto, esto se ve simplemente como un "salto de línea"; lo que lo convierte un caracter invisible o "no imprimible".

En un sistema computacional, un archivo es simplemente un array de bytes en una memoria no volátil; cuya identificación y localización física es posible gracias al llamado "sistema de archivos". Para simplificarnos el ajetreo que implica localizar una porción de memoria que se define como "archivo", este sistema nos permite encontrarlo mediante un identificador tan humano como lo es el nombre. El directorio o carpeta es simplemente un mecanismo para agrupar varios archivos o carpetas de manera jerárquica (se puede decir que representable con una estructura de árbol).

Independientemente de que si contiene texto, una imagen, sonido, video, etc; sigue siendo un motón de bytes. La diferencia no la hace realmente lo que viene después del . en el nombre; sino en cómo son interpretados esos bytes.

Después de toda la teoría sobre archivos informáticos, al punto que quiero llegar es que aunque en consolas y editores de texto claramente hayan líneas bien definidas; para el sistema sigue siendo como si todo estuviera en una sola. Por ejemplo:

Hola mundo de Arduino.
Estoy escribiendo un archivo de texto para probar mi tarjeta SD.



¡Gracias por su atención!

Si el texto anterior lo guardaras en el Bloc de notas de Windows, el contenido final del archivo sería más o menos así:

Hola mundo de Arduino.\r\nEstoy escribiendo un archivo de texto para probar mi tarjeta SD.\r\n\r\n\r\n\r\n¡Gracias por su atención!

Nótesen los "\r\n", ¿qué son esos y de donde vienen?. Si comparas ambos ejemplos, notarás un patrón muy interesante: aparecen exactamente cuando el texto cambió de línea.

Acertaste... ¡es el separador de líneas! Pero recuerda que son caracteres no imprimibles, ¿entonces por qué usé esta representación en particular? Simple: así es como en código se introducen saltos de línea en cadenas de caracteres (strings).

"\r\n" no representa un solo caracter sino dos:

\r es el "retorno del carro" (valor decimal de 13). Antiguamente por sí solo era el separador de línea en Mac. Muy pocas consolas lo interpretan como "caracter de control", cuya acción era devolver el cursor a la primera columna de la línea actual. \n es el propiamente "salto de línea" (valor decimal de 10). Por sí solo es el típico separador de línea en UNIX/Linux; y "caracter de control" que ninguna consola suele ignorar. Podría ser interpretada como la orden para realizar el cambio de línea que todos conocemos, o simplemente para mover el cursor una fila abajo.

\r y \n juntos son el separador de línea más común y además es el típico en Windows. En ciertas consolas esta pareja es necesaria para realizar un cambio de línea como debe ser (cursor en la primera columna, una fila abajo).

Una vez explicado todo lo que hay por debajo, volvemos a tu pregunta: ¿cómo leer línea por línea?

Existe una función llamada readBytesUntil, la cual debes especificarle el array donde almacenar las lecturas, el valor terminador y la cantidad máxima de lecturas. Desde la perspectiva de software, Arduino es básicamente lenguaje C o C++; lo que significa que hay que colocar el valor cero justo después del último caracter de la cadena. Justamente readBytesUntil retorna un int que representa la cantidad de bytes/caracteres que en realidad se leyeron; podemos aprovechar esto para determinar en qué índice del array debemos colocar el cero (recuerda que no todas las líneas en un texto tienen la misma longitud).

El mecanismo de lectura de líneas vendría siendo el siguiente:

string[f.readBytesUntil('\r', string, sizeof(string) - 1)] = 0;
while (f.read() != '\n'); // Descartar el resto hasta llegar a la siguiente línea

Nótese que de primer parámetro hay un '\r', desde Windows es justamente donde termina una línea de texto. El caracter indicado no se incluye en la lectura.

Y ya con esto acabas de recuperar una línea de texto completa (si es que cabe en el array). Si solo hay un número por línea, atoi es lo que falta en la ecuación final; si son varios separados también por algo, strtok también entra en juego.

Y finalmente, eso es todo lo que tengo que decir. ¡Gracias por su atención!

Muchas gracias a los dos! Muy útil su ayuda, ahora me queda analizar y estudiar la información y los ejemplos brindados. Lamentablemente no estoy para poder hacerlo y probar con el hardware hasta dentro de una semana.

Cualquier cosa, de no ser mucha molestia, en una semana les vuelvo a consultar de no haber solucionado el problema.

Saludos!

Azzimutt: Cualquier cosa, de no ser mucha molestia, en una semana les vuelvo a consultar de no haber solucionado el problema.

Adelante, sin miedo ;)