Datalogger con dos SD

Muy buenas a tod@s

no se si esto tiene que venir aqui o en tutoriales pero bueno, ruego que si no está en el lugar adecuado sea movido.

El asunto es simple cuando implementamos un datalogger nos enfrentamos a un pequeño problema cuando necesitamos sacar la tarjeta sd para pasar los datos a un pc por ejemplo. En este caso a parte de perder los datos que se reciben mientras la sd no esta en arduino, necesitamos reiniciar el mismo para volver a inicializar la sd. En la inmensa mayoria de los casos esto no es critico pero la verdad que investigando un poco parece que tiene una solucion simple.

el bus SPI admite numerosos esclavos que se seleccionan mediante el CS (Chip Select). Asi pues he realizado un programita que nos permite seleccionar una tarjeta u otra para guardar los datos dejando la otra disponible para cambiarla.

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

const int slot_1=4;//indicamos que la tarjeta 1 tendra su SD en el pin 4
const int slot_2=5;//indicamos que la tarjeta 2 tendra su SD en el pin 5

const int selector=6;//interruptor para indicar en que tarjeta queremos guardar datos

const int led_1=7;//led que indica que la tarjeta 1 esta activa
const int led_2=8;//led que indica que la tarjeta 2 esta activa

float TEMP=25.35;//variable a guardar el la sd

void setup(){

Serial.begin(9600);//para depuración

pinMode(10,OUTPUT);//se debe configurar asi en la mayoria de las placas para que funcione (53 en el MEGA)

pinMode(selector,INPUT);//se define como entrada

pinMode(slot_1,OUTPUT);
pinMode(slot_2,OUTPUT);//creo que esto no haria falta pero asi queda algo mas claro

}

void loop(){

//Para escribir en la tarjeta 1

if(digitalRead(selector)==HIGH){//si el interruptor esta activo
if(!SD_1.begin(slot_1)){//inicializamos la tarjeta 1
Serial.println("fallo tarjeta 1");
return;//intentamos reinicializarla hasta que lo logremos
}
Serial.println("tarjeta 1 inicializada2);
digitalWrite(led_1,HIGH);//activamos el led que la tarjeta 1 esta inicializada
digitalWrite(led_2,LOW);//indicamos que la tarjeta 2 esta desconectada

file dataFile = SD_1.open("valores.txt",FILE_WRITE);//abrimos el fichero para guardar los datos (si no existe se crea)

if(dataFile){//si el fichero es correcto escribimos en el
dataFile.print("Temperatura: ");
dataFile.println(TEMP);
dataFile.close();//una vez escrito cerramos el fichero

Serial.print("guardado correcto");//avisamos que se ha guardado ok
}
else{
Serial.print("error al guardar en fichero");//avisamos que se ha producido un error
}
delay(5000);//esperamos para tomar otro valor
}//hasta aqui para la tarjeta 1

else if(digitalRead(selector)==LOW){//si el interruptor esta desactivado
if(!SD_2.begin(slot_2)){//inicializamos la tarjeta 2
Serial.println("fallo tarjeta 1");
return;//intentamos reinicializarla hasta que lo logremos
}
Serial.println("tarjeta 2 inicializada2);
digitalWrite(led_2,HIGH);//activamos el led que la tarjeta 2 esta inicializada
digitalWrite(led_1,LOW);//indicamos que la tarjeta 1 esta desconectada

file dataFile = SD_2.open("valores.txt",FILE_WRITE);//abrimos el fichero para guardar los datos (si no existe se crea)

if(dataFile){//si el fichero es correcto escribimos en el
dataFile.print("Temperatura: ");
dataFile.println(TEMP);
dataFile.close();//una vez escrito cerramos el fichero

Serial.print("guardado correcto");//avisamos que se ha guardado ok
}
else{
Serial.print("error al guardar en fichero");//avisamos que se ha producido un error
}
delay(5000);//esperamos para tomar otro valor
}
}

NOTA: aun no he podido probarlo ya que solo dispongo de un SD, estoy en espera de que me llegue el otro

Estuve haciendo pruebas con el codigo y un solo slot sd pero me daba nuemrosos errores :disappointed_relieved: :disappointed_relieved: :disappointed_relieved:

asi que esperare a tener los dos slots y cuando tenga algo mas claro lo publicare

yo creo que libreria sd no funciona. :astonished:

porque ??, porque aunque uno ponga un (Cs)LOW , o High .
la libreria no corta no deja de enviar datos a la Sd card, por lo cual
si pones una segunda cosa SPI, en tu caso otro Sd, se crea un conflicto
y se bloquean mutamente.

he preguntado yo en los foros pero nadie me diopelota.

para resolver esto he usado un chip SN74AHCT08N, con esto
desconecto SCK, de la sd card y le conecto a la ora sd card

muy buenas: ya he estado repasando el codigo y creo que este si que debe de funcionar correctamente

#include<SD.h>

const int principal=8;//declaramos el pin 9 para comunicar con la tarjeta 1
const int auxiliar=9;//declaramos el pin 10 para comunicar con la tarjeta 2
const int selector_principal=7;//declaramos el pin 8 para elegir trabajar con la tarjeta 1
const int selector_auxiliar=6;//declaramos el pin 7 para elegir trabajar con la tarjeta 2
const int led_tarjeta_principal=5;//declaramos el pin 6 como señalizacion tarjeta 1 activa
const int led_tarjeta_auxiliar=4;//declaramos el pin 5 como señalizacion tarjeta 2 activa

void setup(){
pinMode(principal,OUTPUT);//declaramos el pin como salida
pinMode(auxiliar,OUTPUT);//declaramos el pin como salida
pinMode(led_tarjeta_principal,OUTPUT);//declaramos el pin como salida
pinMode(led_tarjeta_auxiliar,OUTPUT);//declaramos el pin como salida
pinMode(selector_principal,INPUT);//declaramos el pin como entrada
pinMode(selector_auxiliar,INPUT);//declaramos el pin como entrada
pinMode(10,OUTPUT);//hay que declaralo como salida en el caso del MEGA seria el pin 53

digitalWrite(led_tarjeta_principal,LOW);//nos aseguramos que el led este desactivado
digitalWrite(led_tarjeta_auxiliar,LOW);//nos aseguramos que el pin este desactivado
digitalWrite(principal,HIGH);//para asegurarnos que no se selecciona
digitalWrite(auxiliar,HIGH);//para asegurarnos que no se selecciona
digitalWrite(selector_principal,HIGH);//activamos la pullup para que se active por nivel bajo
digitalWrite(selector_auxiliar,HIGH);//activamos la pullup para que se active por nivel bajo
}

void loop(){

if(digitalRead(selector_principal)==LOW && digitalRead(selector_auxiliar)==HIGH){//si esta seleccionada la tarjeta principal
digitalWrite(auxiliar,HIGH);//desconectamos el pin de seleccion de la tarjeta auxiliar(se desconecta por nivel alto
digitalWrite(led_tarjeta_auxiliar,LOW);//desconectamos el led de tarjeta auxiliar

While(!SD.begin(principal)){//mientras la SD no se inicie con el pin principal
SD.begin(principal);//se inicia la tarjeta principal
digitalWrite(led_tarjeta_principal,HIGH);//se activa el led de la tarjeta principal
}
}

if(digitalRead(selector_principal)==HIGH && digitalRead(selector_auxiliar)==LOW){//si esta seleccionada la tarjeta auxiliar
digitalWrite(principal,HIGH);//desconectamos el pin de seleccion de la tarjeta principal (se desconecta por nivel alto)
digitalWrite(led_tarjeta_principal,LOW);//desconectamos el led de tarjeta principal

While(!SD.begin(auxiliar)){//mientras la SD no se inicie con el pin auxiliar
SD.begin(auxiliar);//se inicia la tarjeta auxiliar
digitalWrite(led_tarjeta_auxiliar,HIGH);//se activa el led de la tarjeta auxiliar
}
}

if((digitalRead(selector_principal)==HIGH && digitalRead(selector_auxiliar)==HIGH)||(digitalRead(selector_principal)==LOW && digitalRead(selector_auxiliar)==LOW)){//si no hay tarjeta seleccionada
digitalWrite(principal,HIGH);//desactivamos la tarjeta principal
digitalWrite(auxiliar,HIGH);//desactivamos la tarjeta auxiliar
digitalWrite(led_tarjeta_principal,LOW);//desactivamos el led de la tarjeta principal
digitalWrite(led_tarjeta_auxiliar,LOW);//desactivamos el led de la tarjeta auxiliar
}

if((digitalRead(led_tarjeta_principal)==HIGH&&digitalRead(led_tarjeta_auxiliar)==LOW)||(digitalRead(led_tarjeta_principal)==LOW&&digitalRead(led_tarjeta_auxiliar)==HIGH)){//comenzamos el proceso de grabar datos en la SD
File dataFile = SD.open("valores.txt", FILE_WRITE);//abrimos el archivo para escribir en el (si no existe se crea automaticamente)

if(dataFile){//si esta abierto
dataFile.print(temp_amb_hab1);
dataFile.close();
}
}
}

Naruto128:
yo creo que libreria sd no funciona. :astonished:

porque ??, porque aunque uno ponga un (Cs)LOW , o High .
la libreria no corta no deja de enviar datos a la Sd card, por lo cual
si pones una segunda cosa SPI, en tu caso otro Sd, se crea un conflicto
y se bloquean mutamente.

muy buenas Naruto:
segun he podido leer en esta pagina Arduino + Shield Tarjeta SD
las lineas de SCLK,MOSI y MISO son comunes a todos los elementos del bus y lo unico que tienes para seleccionar el esclavo es el CS por defecto esta siempre a nivel HIGH y cuando se quiere comunicar con uno se ha de poner su CS a nivel LOW. los datos y la linea de SCLK le llegan a todos pero solo le hacen caso los que tienen el CS a LOW de hay puede venr el problema, si te fijas en las condiciones me aseguro de poner el CS de la otra SD a nivel alto y luego inicio la biblioteca con el otro de esta forma solo mantengo uno activo.
Como bien dices la bibliteca no es que esté muy fina ya que no permite crear variables (como la lyquidCristal que te permite crear varias variables para poder seleccionar con que lcd quieres trabajar (en el caso de paralelo por ejemplo). y esto provoca que sea un engorro tener que andar iniciando la biblioteca en el codigo lo cual consume bastante tiempo unos 200ms en el mejor de los casos. he intentado modificarla para que permita variables pero mis conociemientos de programacion de arduino a un nivel tan bajo son bastante limitados asi que he hecho esta "ñapa" esperando que funcione

mmm, otra cosa que no se como vaciar el buss, como por ejemplo
el puerto serial, lo puedes vaciar asi Serial.flush() ;, es decir si cabio
de aparato debe quedar "datos sueltos" que elotro aparato a va leer
y se bloquera.

al reiniciar la sd ahi se vacia, pero se pierde tiempo.

debe agun comando de que deje enviar o se vacie .

SPI.transfer(val) ; //vall=?

pues la unica forma que se me ocurre es con un pequeño delay de unos pocos microsegundos.
de todas formas creo que no quedan mas narices que reinicializar la biblioteca al cambiar de dispositivo

yo la verdad que lo quiero para no perder datos asi que normalmente solo estara una tarjeta activa. lo que pasa que si guardar los datos esta bien pero algun dia hay que sacarlos :smiley: :smiley: y claro no es plan de sacar la tarjeta a las bravas o desconectar el arduino. cuando llegue ese momento cambio el selector el programa inicia la otra tarjeta y deja la que estaba en uso libre para poder sacarla y meterla en un pc. una vez se vuelquen los datos se mete de nuevo y hasta la proxima