Pages: [1] 2   Go Down
Author Topic: TUTORIAL: ¿Por qué mi programa en Arduino se reinicia, falla, se bloquea, ... ?  (Read 6422 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1413
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Me gustaría usar este post para mencionar un par de cosas que creo que son muy útiles y que he ido descubriendo como suele ser habitual a base de horas y quebraderos de cabeza, junto con lecturas infinitas de foros, etc...
Esto va dirigido a los menos avanzados (como yo) que poco a poco nos ponemos con proyectos mas grandes y mas complejos.

Cuando realizamos un proyecto pequeño nos olvidamos de ciertas limitaciones que tienen estos pequeños microcontroladores, nos olvidamos que no son ordenadores con grandes capacidades de memoria o calculo. Conforme ampliaba un proyecto que empece cuando todavía encender un led era motivo de sonrisa de satisfacción,  empece a tener problemas de estabilidad en mi programa. No entendía porque de forma aleatoria se reiniciaba mi Arduino, se bloqueaba, fallaban las lecturas etc.

Poco a poco he aprendido 3 o 4 puntos importantes que me gustaría mencionar aquí para todos aquellos que se identifiquen con mi caso, seguro que a alguno le ahorra una infinidad de horas y de quebraderos de cabeza....que yo sufrí.

Vamos a utilizar como ejemplo el Arduino UNO ya que es el mas utilizado comúnmente, aunque esto es aplicable a otras placas.

Quote
Flash Memory   32 KB (ATmega328) of which 0.5 KB used by bootloader
SRAM   2 KB (ATmega328)
EEPROM   1 KB (ATmega328)
Nota: No voy a entrar a la explicación técnica de cada uno de estos puntos porque esta documentado en la red y yo no soy ningún experto y seguro que me dejo cosas.

Punto 1: Memoria SRAM
Cuando incluimos en nuestro programa lineas como las siguientes...

Code:
Serial.println(" ------------------------- Iniciando Arduino --------------------------");

Estamos ocupando memoria SRAM que resulta ser la mas escasa en nuestro pequeño microcontrolador. Si no controlamos el espacio libre llegaremos a machacar la memoria con datos unos encima de otros lo cual finalmente se traducirá en inestabilidad del programa y el reinicio del Arduino

Solución
Con un pequeño código podemos controlar la memoria SRAM disponible en cualquier momento. Yo suelo hacer que me muestre este valor al final del setup() y luego lo pongo el el loop() y compruebo que el valor no disminuye con el tiempo.
Code:
     #include <MemoryFree.h>
    Serial.print("freeMemory()=");        Serial.println(freeMemory());

Crear la libreria con estos dos archivos. No los pongo como adjuntos porque al ser tan cortos creo que es mejor tener el código aquí por si se eliminan los adjuntos.

File: MemoryFree.cpp
Code:
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;

#include "MemoryFree.h";

int freeMemory() {
  int free_memory;

  if((int)__brkval == 0)
     free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}
File: MemoryFree.h
Code:
// memoryFree header

#ifndef MEMORY_FREE_H
#define MEMORY_FREE_H

#ifdef __cplusplus
extern "C" {
#endif

int freeMemory();

#ifdef  __cplusplus
}
#endif

#endif

Se aconseja disponer al menos de 200 bytes de memoria SRAM libre durante la ejecución del programa para evitar problemas.

¿Como liberar espacio?
Para utilizar la Memoria Flash en lugar de la SRAM que es mucho mas escasa, podemos utilizar PROGMEM, esta todo descrito aquí:
http://arduino.cc/es/Reference/PROGMEM


Punto 2: Flash Memory.
En el caso de sobrepasar la memoria flash para almacenar el programa nos sera imposible subirlo a la placa, al intentarlo obtendremos un error.
Code:
Binary sketch size: 27242 bytes (of a 32256 byte maximum)
El problema es que en el compilador nos indica que tenemos kB totales para nuestro programa. No obstante hay un fallo en el IDE por el cual obtendremos un error que nos impedirá subir nuestro programa al Arduino con programas de tamaño ligeramente menor a ese valor, lo cual puede confundirnos respecto al origen del problema.
El tamaño total que puede tener nuestro programa es de
Code:
28672 bytes
sobrepasado este valor, no podremos subir el programa y el error que nos aparece no da mucha idea del motivo por el cual esta fallando. Así que recordarlo !

Punto 3: Reinicios del Arduino debido a perdida de internet[/b]
Usando el Ethernet Shield Oficial.
En ocasiones debido a un problema de conexión a internet cuando usamos el Ethernet Shield se puede ocasionar reinicios del Arduino. Añadiendo unas lineas podemos limitar el tiempo de espera que el Arduino intentara establecer la conexión y si no lo consigue seguirá con el programa.
Para ello añadiremos la librería.
Code:
 
  #include <utility/w5100.h>     // Advance Ethernet functions
En el setup() de nuestro programa añadiremos estas dos lineas
Code:
 
  W5100.setRetransmissionTime(0x07D0);  //setRetransmissionTime sets the Wiznet's timeout period, where each unit is 100us, so 0x07D0 (decimal 2000) means 200ms.
  W5100.setRetransmissionCount(3);      //setRetransmissionCount sets the Wiznet's retry count.

De esta forma cuando hagamos...            
Code:
if (client.connect()) {  
evitaremos que se quede colgado si la conexión no es exitosa.

Punto 4: Utilizar Watchdog.
Esta es una función muy útil para evitar que nuestro Arduino se quede en un bucle infinito o bloqueado en alguna parte del código. No voy a entrar en describirlo ya que esta muy documentado en la red pero si me parece importante mencionar que si disponemos de un Arduino duemilanove  tendremos que actualizar el bootloader ya que el que viene de serie tiene un fallo que en esencia hara que cuando se ejecute el watchdog, se establezca un valor de reinicio de muy bajo tiempo por lo que el Arduino se reiniciara constantemente.
Para solucionarlo si nos pasa esto no nos queda otra que crear un programa "vació" con un setup()  y loop() y probar y probar a subirlo al arduino hasta que entre.
Al margen de esto, el Watchdog se asegurara que no tengas que ir y manualmente reiniciar el Arduino en caso de fallo eventual. Muy útil cuando el Arduino se encuentra trabajando en una localización de difícil acceso o desatendido.

Punto 5: Tipos de Variables
Es muy importante cuando declaremos variables y cuando metamos datos en ellas que recordemos la capacidad de cada variable y el tipo. Esto también nos sera útil para ahorrar SRAM cuando sea posible, declarando variables de tamaño acorde al dato que ira dentro.
Aquí podéis ver que valores engloban cada variable y su tamaño.

http://sites.google.com/site/mechatronicsguy/arduinocheatsheet/Arduino%20cheet%20sheet%20v02bsmall.png

Quote
Datatype   RAM usage
void keyword   N/A
boolean   1 byte
char   1 byte
unsigned char   1 byte
int   2 byte
unsigned int   2 byte
word   2 byte
long   4 byte
unsigned long   4 byte
float   4 byte
double   4 byte
string   1 byte + x
array   1 byte + x
enum   N/A
struct   N/A
pointer   N/A
Espero que esto le sea de ayuda a alguien ya que sin duda a mi me habria ahorrado muchisimas horas de "que esta pasando!!" al no entender porque mi Arduino no se comportaba como yo esperaba.

Por favor, cualquier error o información adicional que penseis que puede ser util hacermelo saber y podemos ampliar todo lo aquí expuesto.
En cuanto lo revise una vez mas lo pasare a ingles por cubrir mas audiencia smiley-wink
Un saludo,
Sergegsx
« Last Edit: November 06, 2011, 04:28:47 pm by Sergegsx » Logged

* Si preguntas, pon el código de tu programa, hace mucho mas fácil ayudarte. Y me ahorro un mensaje pidiendo que lo hagas.
* Si consigues solucionar tu problema, dedica unos minutos a explicar en tu post como lo conseguiste para beneficio de todos.
* Cambia el 'Subject' de tu hilo y añade 'SOLUCIONADO' cuando hayas llegado a una solución al problema que planteaste.
* Utiliza un 'Subject' para tu hilo que explique de que va el hilo.
Si estas empezando:
* Comienza a usar Arduino
* Guías de iniciación a Arduino
* Ejemplos
* Referencia del Lenguaje
* Conceptos básicos
Guia de usuario de arduino
Tutoriales en Ingles
Si necesitas que alguien te escriba el código: http://www.freelancer.com/  o esta  http://www.guru.com/

Offline Offline
Edison Member
*
Karma: 23
Posts: 1375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow! Estupendástica recopilación de trucos! Clap, clap, clap
Seguro que nos salva de una cuantas horas de tirarnos de los pelos a muchos de nosotros smiley-grin
Logged

Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

0
Offline Offline
Edison Member
*
Karma: 8
Posts: 1040
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lo meto en mi cuaderno de arduino. Gracias Sergegsx
Logged

Trabajando en ...

    * Control Domotico (En montaje ...)
    http://casitadomotica.blogspot.com/
 

[url=https://bitbucket.org/fmalpartida

0
Offline Offline
Full Member
***
Karma: 1
Posts: 247
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

muy bueno!

Gracias
Logged


0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

al Playground? => http://arduino.cc/playground/Es/FAQ

Gracias!

smiley-wink
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

NO ME FUNCIONA.LO COMPILE ARDUINO 0022, ME TIRA ESTE ERROR

"In file included from sketch_nov18c.cpp:7:
sketch_nov18c:-1: error: previous declaration of 'int freeMemory()' with 'C++' linkage
MemoryFree.h:7: error: conflicts with new declaration with 'C' linkage
"

 smiley-cry smiley-cry smiley-cry smiley-cry smiley-cry smiley-cry smiley-cry
Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 149
LED
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Punto 2: Flash Memory.
En el caso de sobrepasar la memoria flash para almacenar el programa nos sera imposible subirlo a la placa, al intentarlo obtendremos un error: Binary sketch size: 27242 bytes (of a 32256 byte maximum)
El problema es que en el compilador nos indica que tenemos kB totales para nuestro programa. No obstante hay un fallo en el IDE por el cual obtendremos un error que nos impedirá subir nuestro programa al Arduino con programas de tamaño ligeramente menor a ese valor, lo cual puede confundirnos respecto al origen del problema.
El tamaño total que puede tener nuestro programa es de: 28672 bytes
sobrepasado este valor, no podremos subir el programa y el error que nos aparece no da mucha idea del motivo por el cual esta fallando. Así que recordarlo !

Creo que eso lo soluciona el nuevo Bootloader de WestfW (Optiboot 4.4), que ya viene incluido en el IDE 0023.
Logged

Arduino Uno (R2fix) / Duemilanove (328p)
Ethernet Shield SD (v5)

0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1413
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Punto 2: Flash Memory.
En el caso de sobrepasar la memoria flash para almacenar el programa nos sera imposible subirlo a la placa, al intentarlo obtendremos un error: Binary sketch size: 27242 bytes (of a 32256 byte maximum)
El problema es que en el compilador nos indica que tenemos kB totales para nuestro programa. No obstante hay un fallo en el IDE por el cual obtendremos un error que nos impedirá subir nuestro programa al Arduino con programas de tamaño ligeramente menor a ese valor, lo cual puede confundirnos respecto al origen del problema.
El tamaño total que puede tener nuestro programa es de: 28672 bytes
sobrepasado este valor, no podremos subir el programa y el error que nos aparece no da mucha idea del motivo por el cual esta fallando. Así que recordarlo !

Creo que eso lo soluciona el nuevo Bootloader de WestfW (Optiboot 4.4), que ya viene incluido en el IDE 0023.

estupendo porque a mi me hizo perder 2 o 3 horas hasta que encontre porque no subian los sketch.
no sabia que existe la versión 23, descargandola....
a ver si encuentro que cambios tiene el Optiboot 4.4.
gracias por el aviso.
Logged

* Si preguntas, pon el código de tu programa, hace mucho mas fácil ayudarte. Y me ahorro un mensaje pidiendo que lo hagas.
* Si consigues solucionar tu problema, dedica unos minutos a explicar en tu post como lo conseguiste para beneficio de todos.
* Cambia el 'Subject' de tu hilo y añade 'SOLUCIONADO' cuando hayas llegado a una solución al problema que planteaste.
* Utiliza un 'Subject' para tu hilo que explique de que va el hilo.
Si estas empezando:
* Comienza a usar Arduino
* Guías de iniciación a Arduino
* Ejemplos
* Referencia del Lenguaje
* Conceptos básicos
Guia de usuario de arduino
Tutoriales en Ingles
Si necesitas que alguien te escriba el código: http://www.freelancer.com/  o esta  http://www.guru.com/

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 149
LED
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

También viene incluido en la versión del IDE 1.0-rc2.
Lo que soluciona el bootloader de westfw (ahora el oficial) está escrito en el tema del foro al respecto.
En concreto sería el problema de "optiboot has problems uploading sketches bigger than about 30 KB". También es interesante que con su bootloader ya se puede usar el Uno como programador ISP, solucionando el problema "Optiboot does not support ArduinoasISP programmer".


Por cierto, ya se ha publicado el esquema y fotos de la nueva placa Uno R3, aunque de momento ni en la propia tienda oficial Arduino la venden, sólo en las tiendas americanas RadioShack.
El tema es que quitando las tonterías sacaperras (cambiar el color de la placa, cambiar la posición del pulsador reset, duplicar los pines TWI, añadir un pin sorpresa y un pin para compatibilidad con el Due), la modificación que han hecho al final para solucionar el problema del Reset de las Uno R2 (pico de tensión), es colocar un diodo entre Reset y +5V.
La modificación casera sería (supongo que con un 1N4148):
« Last Edit: November 18, 2011, 03:33:28 pm by Razorblade » Logged

Arduino Uno (R2fix) / Duemilanove (328p)
Ethernet Shield SD (v5)

Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

me baje el 0023, pero me sigue tirando el mismo error, no estoy poniendo p agregando codigo al codigo original.
Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 149
LED
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

AlexRodriguez, a ver si contesta Sergegsx, que yo nunca he usado esa librería.
El problema viene de mezclar C con C++.
Logged

Arduino Uno (R2fix) / Duemilanove (328p)
Ethernet Shield SD (v5)

Málaga, Spain
Offline Offline
Edison Member
*
Karma: 40
Posts: 2182
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Cual es ese pin sorpresa que lleva la R3?
Logged

   

Offline Offline
Edison Member
*
Karma: 23
Posts: 1375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Intenta averiguarlo xD
http://www.flickr.com/photos/jeremyblum/6162915410/

Aunque esa versión parece distinta de la R3, que parece que sigue siendo similar a la R2
http://www.flickr.com/photos/jeremyblum/6162915410/
« Last Edit: November 18, 2011, 06:05:15 pm by chiva » Logged

Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

segun lo q puede leer dice  IDREF, Q signifiaca, ni idea.


    smiley-cry smiley-cry smiley-cry smiley-cry
Logged

Málaga, Spain
Offline Offline
Edison Member
*
Karma: 40
Posts: 2182
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Puede ser un selector automático de tensión para los shields. Es decir detectar si se alimentan a 3.3V o 5V y alimentarlos adecuadamente o seleccionar el regulador para alimentar a todo.  Viendo el cirio que han montado con los operacionales para seleccionar la fuente de alimentación.
Logged

   

Pages: [1] 2   Go Up
Jump to: