Hola, buenos días estoy desarrollando un proyecto el cual me va a medir tres variables cada hora, las tres lecturas se van a almacenar en una micro SD en la cual se va a incluir la fecha y hora en que se hace la lectura mediante circuito RTC (la parte electrónica me funciona correctamente) luego solicitaré por bluetooth (por ahora simulado con serial) los valores medidos en una fecha específica, el programa se encargará de buscar dentro de la SD dicha fecha y enviará los valores de vuelta. Por ahora me funciona el poder enviar todos los datos porque esa parte, como saben es sencilla, he leído en diferentes foros y páginas sobre las lecturas linea a linea entre ellos:
http://www.extremadura-web.es/Blog/2013/01/16/leer-linea-fichero-sd-en-arduino/
http://forum.arduino.cc/index.php?topic=291243.0
http://forum.arduino.cc/index.php?topic=303081.0
De ahí me he guiado para llevar el siguiente código:
#include <SD.h>
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
String sensor1;
String sensor2;
String sensor3;
String hora;
String dia;
String mes;
String anio;
byte lectura;
unsigned long cursor;
char Ruta[9] = {'t', 'e', 's', 't', '.', 't', 'x', 't', '\0'};
int fila;
tmElements_t tm;
int cero=0;
const int analogInPin = A0;
const int analog1InPin = A1;
const int analog2InPin = A2;
//valores leidos desde los sensores
int sensorValue = 0;
int sensor1Value = 0;
int sensor2Value = 0;
//string para contener los datos de entrada por serial
String inputString = "";
//cuando el string esté completo o lleno
boolean stringComplete = false;
void setup() {
// iniciar la comunicacion con el puerto serial a 9600 bps:
Serial.begin(9600);
// reserva 200 bytes para la variable inputString:
inputString.reserve(200);
Serial.print("Iniciando tarjeta SD...");
// en la Ethernet Shield, CS es el pin 4. Es puesto como salida por defecto.
// (el pin 10 en las tarhetas Arduino, 53 en la Mega) debe ser definida como salida
// o la libreria SD no funcionará.
pinMode(10, OUTPUT);
if (!SD.begin(10)) {
Serial.println("Inicio fallido");
return;
}
Serial.println("Inicio hecho.");
}
void loop() {
// print the results to the serial monitor:
// print the string when a newline arrives:
if (stringComplete) {
//esta parte solo me calculará la linea final sabiendo que cada línea almacenada en la SD
//contiene 31 caracteres incluyendo \n
File myFile;
myFile = SD.open("test.txt");
if (myFile) {
while (myFile.available()){
lectura=myFile.read();
cursor=myFile.position();
}
lectura=0;
fila=cursor/31;
Serial.println(fila);
myFile.close();
}else {
Serial.println("error al abrir test.txt");
}
myFile.close();
//acá sabremos que día, mes y año se solicita teniendo en cuenta un orden para
//el string de entrada serial algo asi como 19032015# dia,mes,anio
String diab=inputString.substring(0,2);
String mesb=inputString.substring(2,4);
String aniob=inputString.substring(4,8);
Serial.println(diab);
Serial.println(mesb);
Serial.println(aniob);
//Por ahora sólo intenté leer una fila para saber si me clasificaba correctamente los datos
//almacenados luego agregaré el for
//for (int i=0;i<=fila;i++)
String Lin = ReadFile(10,Ruta);
Serial.println(Lin);
sensor1 = Lin.substring( 0,2);
Serial.print("sensor1:");
Serial.println(sensor1);
int dcPos = Lin.indexOf( "," );
sensor2 = Lin.substring( dcPos+1,dcPos+3 );
Serial.print("sensor2:");
Serial.println(sensor2);
int dPos = Lin.indexOf( "." );
sensor3 = Lin.substring( dPos+1,dPos+3 );
Serial.print("sensor3:");
Serial.println(sensor3);
int cPos = Lin.indexOf( "-" );
hora = Lin.substring( cPos+1,cPos+9 );
Serial.print("hora:");
Serial.println(hora);
int Pos = Lin.indexOf( "+" );
dia = Lin.substring( Pos+1,Pos+3 );
Serial.print("dia:");
Serial.println(dia);
int mPos = Lin.indexOf( "/" );
mes = Lin.substring( mPos+1,mPos+3 );
Serial.print("mes:");
Serial.println(mes);
int aPos = Lin.indexOf( ";" );
anio = Lin.substring( aPos+1,aPos+5 );
Serial.print("año:");
Serial.println(anio);
sensor1 = "";
sensor2 = "";
sensor3 = "";
hora = "";
dia = "";
mes = "";
anio = "";
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '#') {
stringComplete = true;
}
}
}
String ReadFile(int Linea,char Ruta[]){
int Lin=0;
String Resultado;
File myFile2;
byte Bin;
myFile2 = SD.open(Ruta);;
if (myFile2) {
while (myFile2.available()) {
Bin=myFile2.read();
if (Bin==13){Lin++;myFile2.read();}
else
{
if (Lin==Linea){Resultado=Resultado+(char(Bin));}
if (Lin>Linea){myFile2.close();return Resultado;}
}
}
myFile2.close();return Resultado;
}
}
Si, hay muchas variables que me sobran pero las necesito en otras partes del código, que si alguien necesita subiré luego para sus proyectos, tener en cuenta que las lineas almacenadas en la SD son así: FF,FF.FF-16:42:45+20/03;2015# (los primeros tres valores son hexadecimales como habrán notado)
Cuando pruebo únicamente la parte de leer una línea sin calcular la cantidad de filas si me devuelve los valores de cada sensor y las fechas de forma correcta, pero cuando agrego la primera parte para calcular la fecha solicitada del string me arroja valores vacíos, no entiendo el motivo, si ven algún error por favor podrían decírmelo, de antemano muchas gracias por su tiempo para leer el post y responder. Adjunto una imagen (fig1) de lo que me arroja por puerto serial. cuando invierto el orden si me da el resultado como espero (fig2), pero no puedo dejarlo así porque antes necesito primero saber que fecha se me solicita, esto es lo extraño y no encuentro explicación del por qué el orden me altera los resultados, muchas gracias de nuevo por cualquier aporte que puedan hacerme.