Arduino deja de correr

que tal!
explico:
Arduino leonardo + reloj de tiempo real + arduino logger shield

con el siguiente codigo:

//librerias
#include <SPI.h>
#include <SD.h>
#include <MemoryFree.h>
//guardando datos (el nombre del archivo y luego en que Pin esta conectado)
File myFile;
const int chipSelect = 8; //la microsd shield de MCI viene con el 8.
//variables del reloj
#define DS1307_ADDRESS 0x68
//todas las variables
int sensorhumedadsustrato = A0;
int sensortemperaturasustrato = A3;
float sensorradiacionpar = A1;
float Tsustrato;
float HRsustrato;
float LuzPAR;
int i = 0;

void setup ()
{ 
  Wire.begin();
  Serial.begin(9600);
  //while (!Serial); // wait for serial port to connect. Needed for Leonardo only. tarjeta sd
  pinMode(SS, OUTPUT);
  pinMode (sensorhumedadsustrato, INPUT);
  pinMode (sensortemperaturasustrato, INPUT);
  pinMode (sensorradiacionpar, INPUT);
  
  if (!SD.begin(8, 11, 12, 13))
  {
    Serial.println("Tu tarjeta no esta, o algo se desoldo :[");
  }
  else
  {
    Serial.println("La tarjeta esta OK :]");
    myFile = SD.open("Estacion.txt", FILE_WRITE);
  }
  if(!myFile)
  {
    Serial.print("no puedo abrir el archivo :[");
  }
  else
  {
    myFile.println("Bienvenido a la estacion metereologica 0.2");
    myFile.print("Numero de estacion");
    myFile.print("\t");
    myFile.print("Fecha");
    myFile.print("\t");
    myFile.print("Hora");
    myFile.print("\t");
    myFile.print("Tº Sustrato");
    myFile.print("\t");
    myFile.print("H.R Sustrato");
    myFile.print("\t");
    myFile.println("Luz PAR");
    myFile.close();
  } 
}
void loop ()
{
  Tsustrato = analogRead(sensortemperaturasustrato);
  Tsustrato = -0.1054*Tsustrato+78.9;
  delay(100);
  HRsustrato = analogRead(sensorhumedadsustrato);
  HRsustrato = 0.461022+0.001740*HRsustrato-0.007479*Tsustrato;
  delay(100);
  LuzPAR = analogRead(sensorradiacionpar);
  delay(100);
  i = i++;
  if(i<1000)
  {    
    if(SD.begin(8, 11, 12, 13))
    {
      Serial.print("\t");
      
      myFile = SD.open("Estacion.txt", FILE_WRITE);
      Serial.print("\t");
      Serial.println("We did it!");
      myFile.print("01");
      myFile.print("\t");
      printDate(); //imprime en el archivo, ver funcion mas abajo, la fecha y hora).
      myFile.print("\t");
      myFile.print(Tsustrato);
      myFile.print("\t");
      myFile.print(HRsustrato);
      myFile.print("\t");
      myFile.println(LuzPAR);
      myFile.flush();
    }
    else
    {
      Serial.println("No busques donde no encontraras! no hay tarjeta :]");
    }
    myFile.close();
    delay(300);
  }
  else
  {
    software_Reset(); //reinicia la placa cada 1000 iteraciones, que son con 30 segundos, 8 horas. 
  }
  Serial.print("freeMemory()=");
  Serial.print("\t");
  Serial.println(freeMemory());   
}

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
  Serial.println("adios :)");
  asm volatile ("  jmp 0");  
}  

byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  byte zero = 0x00; //workaround for issue #527
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());

  //print the date EG   3/1/11 23:59:59
  myFile.print(month);
  myFile.print("/");
  myFile.print(monthDay);
  myFile.print("/");
  myFile.print(year);
  myFile.print("\t");
  myFile.print(hour);
  myFile.print(":");
  myFile.print(minute);
  myFile.print(":");
  myFile.print(second);
}

El reset lo inserte solo para ver si seguia funcionando luego… y si… funciona… pero por alguna razon deja de funcionar aproximadamente despues de 20XX loops o registros… probe con Freememory y esta no va en disminucion…

Alguna idea?
Gracias y saludos!

haber, tienes conectado un reloc Ic2 y una SDcard SPI. y 3 Sensor Temp ¿es asi?

por partes.

si te funciona todo por unos minutos y luego de bloquea el problema es q no a da a basto el pobre arduino.

por ejemplo el reloj puedes hacer una peticion(leer ) cada un 1 segundo.

unsigned long time=0; unsigned long timeA=0;

... ...... .....

if ( time - timeA>1000) { LeerReloj(); timeA=millis();

}

igual que las sd card .

Muy buenas camilochiang:

a ver si te puedo echar una mano empecemos desde el principio de tu programa

has incluido la libreria SPI.h en muchos ejemplos que he visto no la suelen incluir asi que probaria a comentarla y/o quitarla

declaras la variable const int chipSelect = 8;//que es la que emplea tu modulo

pero luego no veo que la uses (ya que la has declarado.. que son dos bytes :D :D)

en el setup

tienes comentada la instruccion

// while(!Serial);

si usas una placa leonardo deberias descomentarla

pones

pinMode(SS,OUTPUT);

pero no te la veo declarada por ningun lado

para no correr riesgos mejor pon

pinMode(10,OUTPUT);

if(!SD.begin(8,11,12,13))

no es necesario poner todos los pines del bus con poner

SD.begin(chipSelect); suficiente

por otro lado con esta misma instruccion si la SD no se inicializa simplemente pasas para adelante no te aseguras que este inicializada

para asegurarte de que se ha inicializado tienes dos opciones

opcion 1:

if(!SD.begin(chipSelect)){ Serial.println("no hay tarjeta"); return; }

opcion 2:

while(!SD.begin(chipSelect)){ Serial.prinln("no hay tarjeta); }

cualquiera de las dos hace lo mismo se queda ahi en bucle hasta que se inicializa (yo personalmente prefiero los while antes que los return se ve el codigo mas limpio)

en el caso del if(!myFile); exactamente igual que el caso anterior

en el loop

despues de tomar las medidas y antes de guardarlas en la sd vuelves a preguntar si la sd esta inicializada

no seria necesario ya que con las opciones que te he puesto antes ya te aseguras desde el setup que SI esta inicializada y Con tarjeta

pues eso es todo

quiza tambien probaria con quitar el reseteo por software al menos para probar ya que igual hace algo raro con la SD (la verdad que no se muy bien el efecto que tiene)

ahhh y una ultima cosa ¿de que tamaño es la SD? a ver si con tanto dato tan de seguido es que esta llena y no puede escribir mas

si no como ultimo recurso siempre puedes poner un

Serial.println("la parte del codigo que se esta ejecutando");//puede ser una marca para ver tu desde el serial monitor donde se para Serial.print("iteracion: "); Serial.print(i); asi sabes en que instruccion y en que iteracion se ha detenido

ya siento la "txapa"pero espero haberte ayudado

Gracias a ambos! vere que sucede ma;an y os comento!

Ok. No cambie absolutamente nada y lo itere desde el pC.... obtuve mas de 13000 iteraciones sin problema... Al parecer es al cambiar la fuente de poder desde el PC a un transformador de 9V DC.... alguien me explica que sucede porfavor? Gracias!

Puede ser que estes requiriendo mas energía de la que entrega el USB que son 500mA máximo. Mide el conjunto a ver si estas próximo a esos valores.

surbyte por lo que le he entendido es justamente lo contrario a lo que expones, segun parece si lo alimenta desde el pc funciona sin problemas ¿no es asi camilochang? por lo que el problema no es el consumo de corriente, puede ser que si utilizas una pila esta este gastada o no suministre de forma continua 9vdc prueba a poner un voltimetro entre la salida de 5v y gnd del arduino y pon a ejecutar el programa mientras vigilas la tension que tienes si cae por debajo de 4,8v puedes tener o bien problema con la pila o con el regulador de la placa.

ya nos diras saludos

Como ya te han comentado, realizar lecturas del reloj en cada ciclo del bucle principal loop() echa abajo a Arduino, sí o sí.

Hay dos cuestiones:

Primera. No sé si tendrá que ver algo con la librería del reloj o no, pero yo en la lectura de fecha/hora, no utilizo Wire.write(byte zero) sino Wire.send(0), directamente.

Segunda. Tarar un bucle de control de llamadas al reloj, de forma que solo leas el reloj cada cierto número de ciclos del bucle loop y no en todos, de otra forma se "atropella" que es lo que te está ocurriendo.

Quedaría algo así como

void loop ()
{
  byte bucle;
  
  if (bucle == 0) {
    Tsustrato = analogRead(sensortemperaturasustrato);
    Tsustrato = -0.1054*Tsustrato+78.9;
    //  delay(100);   // Es posible que con este método no haga falta, si ves que así no funciona, reintegra el delay
    HRsustrato = analogRead(sensorhumedadsustrato);
    HRsustrato = 0.461022+0.001740*HRsustrato-0.007479*Tsustrato;
    //  delay(100);   // Es posible que con este método no haga falta, si ves que así no funciona, reintegra el delay
    LuzPAR = analogRead(sensorradiacionpar);
    //  delay(100);   // Es posible que con este método no haga falta, si ves que así no funciona, reintegra el delay
    if(SD.begin(8, 11, 12, 13))
    {
      Serial.print("\t");
      
      myFile = SD.open("Estacion.txt", FILE_WRITE);
      Serial.print("\t");
      Serial.println("We did it!");
      myFile.print("01");
      myFile.print("\t");
      printDate(); //imprime en el archivo, ver funcion mas abajo, la fecha y hora).
      myFile.print("\t");
      myFile.print(Tsustrato);
      myFile.print("\t");
      myFile.print(HRsustrato);
      myFile.print("\t");
      myFile.println(LuzPAR);
      myFile.flush();
    }
    else
    {
      Serial.println("No busques donde no encontraras! no hay tarjeta :]");
    }
    myFile.close();
    //  delay(300);   // Es posible que con este método no haga falta, si ves que así no funciona, reintegra el delay
  Serial.print("freeMemory()=");
  Serial.print("\t");
  Serial.println(freeMemory()); 

  }

  bucle = ( bucle + 1 ) % 100; // Esto hace que lo que hay dentro del if (bucle == 0) se ejecute en un 1% de los pasos de loop
         // Cambiando el 100 por un número mayor, harás más lento el ciclo de llamadas y viceversa

  
}

Yo tengo echo este montaje, con sensores de temperatura, reloj y LCD y Arduino Uno y me está funcionando más de un mes -no he conseguido más tiempo sin que alguna vez salte la luz en casa, por otros motivos-

Espero te sirva

Efectivamente eso al parecer! lo estoy alimentando desde un transformador de 9V y sospechaba que era el reloj el que da el problema!

vere que sucede... lo dejare corriendo todo el fds y les cuento!

Gracias!

¿Funcionó bien? ¿se volvió a caer? Cuéntanos que ha pasado :roll_eyes:

Cierto, sería bueno que vayan actualizando los autores si han resuelto o no sus problemas para que sirva a otras personas del foro. Buen consejo @JohnnyDeauville,.

Hahaha nunca funciono El ambiente de trabajo es 100% humedo y probablemente la humedad y la placa no funcionen bien... y eso que esta en una caja sellada. en fin tengo otros 20 haciendo lo mismo en exterior y funcionan correctamente... cosas que pasan! saludos

Dos opciones:

1) Probaste usar esos absorvedores de humedad? Gel de sílice (silicato de sodio) es una alternativa, Cloruro de calcio es la mejor.

2) Tal vez considerar colocar una resistencia calefactora que podrias controlar con el mismo arduino para SECAR el ambiente, podría darte la diferencia que buscas.