Go Down

Topic: "Machacar" la memoria al declarar mal las variables?¿?¿? (Read 1 time) previous topic - next topic

Sergegsx

Aug 28, 2011, 09:53 pm Last Edit: Aug 28, 2011, 09:55 pm by Sergegsx Reason: 1
Hola, a raiz de este post que sigo investigando pero que parece que igual ya he visto la luz...
http://arduino.cc/forum/index.php/topic,70532.0.html

Me gustaria entender mejor como trabaja internamente el Arduino en estos casos y no se como se denomina este problema como para buscarlo por la red especificamente para Arduino.

Si declaras una variable tipo INT y despues durante tu programa le intentas meter un valor mayor por ejemplo un float?

he visto que en ocasiones funciona el programa (cuando este es sencillo), pero en programas mas extensos al final acaba bloqueandose.

como responde Arduino a este tipo de conflictos?
cosas como
Declaras una variable INT (2bytes) y le intentas guardar un float (4 bytes)
Declaras una variable LONG (4bytes) y le intentas guardar un float (4 bytes) pero con decimales y un rango distinto.
Declaras una variable byte (1bytes) y le intentas guardar un float (4 bytes) o lo que sea
etc etc.
ah y tambien, si declaras un char varible[4]; y luego le quieres meter mas bytes de los que has declarado

Igual entendiendo como responde Arduino a esto, consigo terminar de depurar mi programa.
Muchas gracias !!

josemanu

No los he probado pero a veces, por error, he caido en alguna de las situaciones que comentas.

En algunos casos da error de compilación.

Si quieres estar seguro te recomiendo que hagas pequeños skeches de prueba y fuerces el error a ver que pasa.

Sergegsx

no si el error ya lo he vivido. El problema es que si no declaras algo asi
int varible = 123.45;
sino que es dentro del programa y durante su ejecución que se llega a esa situación, el compilador no se entera y te deja subir el programa. Y no es hasta que ocurre la asociación que el arduino empieza a hacer cosas raras.

Es por ello que me interesa saber que ocurre dentro del Arduino en estos casos.
Gracias.

Igor R

#3
Aug 29, 2011, 10:40 am Last Edit: Aug 29, 2011, 10:43 am by Igor R Reason: 1
Yo diria, que como en todos los lenguajes de programacion, hace un "cast". Para "machacar", con punteros si que es facil....

Yo suelo usar "casting" en mis programas,asi estoy seguro. En las operaciones que quieres resultados en float y usas por ejemplo int o long,he tenido experiencias de resultados erroneos. De esta forma, controlas mas lo que deberia pasar.

Un ejemplo de usar cast:
long myvalue1;
long myvalue2;
float myresult;

myresult=(float)myvalue1/(float)myvalue2;


Salu2


Igor R.



Nota.- Ni acentos ni enyes (ordenador ingles)

Sergegsx

entiendo Igor, y que ocurre si intentas algo asi:
int myvalue1;
float myvalue2 = 1234.56;
long myvalue3 = 123456;

myvalue1 = (int)myvalue2;
myvalue1 = (int)myvalue3;
porque en este caso estas metiendo 4 bytes en 2, esto produciría un error supongo.

ah y ya que estamos, en la información de float http://arduino.cc/es/Reference/Float
dice que hay que poner un ".0" si realizas una división. esto para que es, para que lo considere un float ??
en caso de multiplicaciones tambien? no verdad?

Igor R

#5
Aug 29, 2011, 11:36 am Last Edit: Aug 29, 2011, 11:52 am by Igor R Reason: 1
Puedes hacer lo que dices, no tienes mas que probarlo.... ;)
http://arduino.cc/es/Reference/Cast

Lo de anydir el ".0" es para forzar el casting a float. Pero yo lo haria con (float), asi estas seguro.
Del ejemplo de la pagina de referencia:

  int x;
  int y;
  float z;

  x = 1;
  y = x / 2;            // y ahora contiene 0, la parte entera de la operación
  z = (float)x / (float)2;   // z ahora contiene 0.5 (se debe usar 2.0, en lugar de 2)


Sergegsx

Igor si probarlo ya lo he hecho, y miles de veces.
En serio llevo muchas horas en conseguir tener todo mi programa con las variables bien definidas y las operaciones matemeticas tambien bien definidas.
Y todo para que lo muestre por LCD con la porqueria de libreria que venia con la pantalla.

Vale, entonces es lo que pensaba, el .0 es para forzar el float.

Respecto a lo que comentaba de meter los datos de un float o un long a un int
int myvalue1;
float myvalue2 = 1234.56;
long myvalue3 = 123456;

myvalue1 = (int)myvalue2;
myvalue1 = (int)myvalue3;

aqui provocaria un fallo en el arduino o se supone que sabe solucionarlo? porque a mi se me queda clavado.
gracias !!

Igor R

Que es lo que te pasa? Que resultados sale en ese ejemplo si los sacas por puerto serie?

Sergegsx

Igor el problema es que el codigo esta en un programa muy largo.
Lo curioso es que a veces se queda colgado, a veces no. Es decir, en ocasiones hace la conversión bien y otras veces cuelga el programa.

Simplemente queria entender como trabaja Arduino con la memoria en estos casos en cuanto a como guarda los datos en su RAM y como los accede luego. Ya que supongo que ahi reside el problema.
De todas formas estoy intentando redefinir todo a ver si consigo que "aguante". Voy a hacer unas pruebas y si no funciona, seguimos por aqui.
Gracias !!!

Igor R

Ahh, como decias que se quedaba clavado el codigo que has puesto antes, por eso preguntaba....


Sergegsx


Ahh, como decias que se quedaba clavado el codigo que has puesto antes, por eso preguntaba....




Si si, es que ese codigo (bueno el real pero simplificado a eso) al descomentarlo del programa "grande" funciona el programa y sino se queda clavado.
pero como digo, voy a ver si consigo "mejorar" todo el codigo del LCD y deja de hacerlo.

Igor R

#11
Aug 29, 2011, 01:43 pm Last Edit: Aug 29, 2011, 02:07 pm by Igor R Reason: 1
Tus problemas vienen en el casting, o en las funciones de conversion de numero a texto de C ?

Mira como hacen en el core de Arduino la salida de datos por puerto serie de un float, podrias facilmente adaptarla para sacarlo por tu lcd. Donde utiliza un print(), puedes utilizar el BV4618_I::putch() (en un vistazo rapido, creo que es esa funcion la que manda un char en la libreria que usas).

void printFloat(double number, uint8_t digits)
{
 // Handle negative numbers
 if (number < 0.0)
 {
    print('-');
    number = -number;
 }

 // Round correctly so that print(1.999, 2) prints as "2.00"
 double rounding = 0.5;
 for (uint8_t i=0; i<digits; ++i)
   rounding /= 10.0;
 
 number += rounding;

 // Extract the integer part of the number and print it
 unsigned long int_part = (unsigned long)number;
 double remainder = number - (double)int_part;
 print(int_part);

 // Print the decimal point, but only if there are digits beyond
 if (digits > 0)
   print(".");

 // Extract digits from the remainder one at a time
 while (digits-- > 0)
 {
   remainder *= 10.0;
   int toPrint = int(remainder);
   print(toPrint);
   remainder -= toPrint;
 }
}




Go Up