Pages: [1]   Go Down
Author Topic: Pasar de un tipo de variable a otro  (Read 1122 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

Hola, me gustaria abrir este post para analizar los metodos de pasar de un tipo de variable a otro.
Estoy teniendo muchos problemas con mi pantalla LCD ya que cuando le envio datos para mostrar si no tengo las variables perfectamente definidas y segun espera la libreria, me cuelga el programa.
Le he metido muchiiiiiisimas horas y algo he avanzado, a ver si entre todos me ayudais a terminar de pulirlo porque sigue dandome problemas
El titulo del post no menciona nada de LCD porque en principio este post deberia servir para cualquier caso.
Al tema...

La libreria de mi pantalla LCD I2C realiza esta función.
Code:
// **************************************************************
// sends string
// **************************************************************
void BV4618_I::puts(char *s)
{
char *sp=s;  
  Wire.beginTransmission(_i2adr);
  // send *s as bytes of date
  while(*sp)
    Wire.send(*(sp++));
  Wire.endTransmission();
}  


Esto funciona sin problemas ya que es un simple string y es el ejemplo mas sencillo.
Code:
di.puts("Hello World");

A partir de ahi empiezan los problemas cuando la sentencia que le envio no es como quiere.
Esto funciona, no entiendo porque ya que si currentMillis es 12345 el resultado de la división es 12.345 que es un float en lugar de un long ????¿?¿?¿?
Code:
unsigned long currentMillis;
char time_str[4];  // Define as a string (4 bytes)
currentMillis = millis();

di.puts(ltoa (currentMillis/1000, time_str, 10));

Esto funciona y tampoco entiendo porque, ya que apparentPower es un double y no un long para usar ltoa
Code:
double apparentPower;
char time_str[4];  // Define as a string (4 bytes)
...
      di.rowcol(2,1);
      di.puts(ltoa(apparentPower, time_str, 10));   di.puts(" Watts ");

Esto lo aprendi ayer y me ha ayudado mucho ya que esto me funciona en un programa por separado donde solo haya este codigo.
Code:
char lcd_data[70];
  di.rowcol(1,1);
  
float horas = time/3600000;
long segminuto = ((time - (int)horas*3600000));
int minutos = (segminuto / 60000);
int segundos = ((segminuto - minutos*60000) / 1000);
// coge todos los segundos y le resta los segundos correspondientes a las horas de "horas"
// de esta resta nos quedan los segundos sin contar las horas (es decir los segundos hacia
// la proxima hora completa

  sprintf(lcd_data,"Time: %0d:%02d:%02d",(int)horas,minutos,segundos);
  di.puts(lcd_data);

En cambio ahora quiero hacer eso mismo en un proyecto y se me bloquea el programa. Si descomento estas lineas el programa entero funciona perfecto.
Code:
char uptime_data[4];

              float horas;
                    horas = ((float)currentMillis/3600000.0);
              long minutos;
                   minutos = currentMillis - (int)horas*3600000;  
                                     
              int horass;
                  horass = (int)horas;
              
                sprintf(uptime_data,"T: %0d  ",horass);
                di.puts(uptime_data);

He leido mucho de tipos de variables pero no termino de saber que pasa.
Se que hay mucho aquí, pero si alguien tiene alguna sugerencia igual puede ayudarme.
gracias
« Last Edit: August 26, 2011, 08:57:42 am 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/

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

por lo que veo si intento realizar muchos calculos en una misma linea me da mas problemas, ahora lo he pasado a esto y por serial me aparece bien, pero al descomentar la linea que lo envia al LCD se bloquea

Code:
             int horas;
                    horas = (int)((float)currentMillis/3600000.0);
              long minutos;
                   minutos = (int)horas*3600000;  
                   minutos = currentMillis - minutos;
                   minutos = (int)((float)minutos / 60000.0);
              int iminutos = (int)minutos;    
              Serial.print(horas);Serial.print(":");Serial.print(iminutos);Serial.println();

                sprintf(uptime_data,"T: %0d  ",(int)horas);
                di.puts(uptime_data);


si quito:
Code:
               sprintf(uptime_data,"T: %0d  ",(int)horas);
                di.puts(uptime_data);

por serial me aparece bien, pero si se lo envio al LCD se bloquea, y eso que solo estoy enviado "horas"
importante: creo que es el sprintf lo que falla ya que si comento esa linea si que funciona.
lo que no enteindo es que en principio estoy haciendo lo mismo que en los ejemplos anteriores,no?
« Last Edit: August 26, 2011, 09:02:32 am 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/

Euskadi
Offline Offline
God Member
*****
Karma: 16
Posts: 721
Arduinotarrak
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset



Hola,
Creo que estás machacando memoria, y eso origina resultados imprevisibles:
Code:
char uptime_data[4];           
sprintf(uptime_data,"T: %0d  ",horass);
defines una  cadena char uptime_data[4] de 4 bytes (3 caracteres + null), y luego le estás metiendo una 'T', un ':', un espacio, uno o dos caracteres de la hora y dos espacios, en total  6 o 7 caracteres!
Prueba definiendo
char uptime_data[10]; 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 48
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

La solución mas practica es reescribir la libreria y sobrecargar el metodo en cuestion.
Te pongo un trozo de codigo de la libreria que tengo hecha para mi pantalla.
Code:
void LCD128x64Class::Write(char* st)
{
  Serial1.print(st);
}

void LCD128x64Class::Write(int st)
{
  Serial1.print( st, DEC );
}

void LCD128x64Class::Write(long st)
{
  Serial1.print(st, DEC );
}

void LCD128x64Class::Write(float st)
{
  static char * valor = "         ";
  valor = dtostrf( st, 4, 2, valor );
  Serial1.print(valor);
}

void LCD128x64Class::Write(float st, int decimales)
{
  static char * valor = "         ";
  valor = dtostrf( st, 4, decimales, valor );
  Serial1.print(valor);
}
Lo mismo que yo e sobrecargado el metodo Write tu puedes hacerlo con tu metodo puts(char *s).

Saludos.
Logged

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



Hola,
Creo que estás machacando memoria, y eso origina resultados imprevisibles:
Code:
char uptime_data[4];          
sprintf(uptime_data,"T: %0d  ",horass);
defines una  cadena char uptime_data[4] de 4 bytes (3 caracteres + null), y luego le estás metiendo una 'T', un ':', un espacio, uno o dos caracteres de la hora y dos espacios, en total  6 o 7 caracteres!
Prueba definiendo
char uptime_data[10];  


mm... bien visto, sin duda eso puede ser uno de los problemas. pero sigue sin funcionar.

Code:
int horas;
                horas = (int)((float)currentMillis/3600000.0);
char uptime_data[10];
                sprintf(uptime_data,"%d%d",(int)horas,(int)horas);
                di.puts(uptime_data);

he dejado al margen iminutos a ver si consigo que al menos me aparezca 2 veces hora.
« Last Edit: August 26, 2011, 09:37:13 am 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/

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

La solución mas practica es reescribir la libreria y sobrecargar el metodo en cuestion.
Te pongo un trozo de codigo de la libreria que tengo hecha para mi pantalla.

Lo mismo que yo e sobrecargado el metodo Write tu puedes hacerlo con tu metodo puts(char *s).

Saludos.


sin duda creo que esa es la solución final, pero ahora mismo me viene un poco grande hacer eso ya que si estoy teniendo tantos problemas con unas conversiones y mostrarlo en pantalla, todavia no me veo reescribiendo la libreria.
en el enlace este dicen que van a hacerlo en el futuro, pero no cuento con ello ya que lo pusieron hace mucho tiempo. http://doc.byvac.com/index.php5?title=Talk:Arduino_BV4618

adjunto la libreria, no para que me la reescribas sino por si hay algo que yo no veo y hace que no funcione el programa, aunque creo que tengo un lio absoluto en las conversiones.

gracias por vuestra ayuda

* bv4618_I.rar (4.43 KB - downloaded 4 times.)
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/

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

Pregunta...
Es posible que a lo largo del programa cuando he utilizado código tipo el siguiente, este "dañando" la memoria y que luego aunque haga una conversión bien, falle ????

Code:
double apparentPower;
char time_str[4];  // Define as a string (4 bytes)
...
      di.rowcol(2,1);
      di.puts(ltoa(apparentPower, time_str, 10));   di.puts(" Watts ");


Tengo el proyecto al 99% a falta de tan solo imprimir en el LCD una linea con el tiempo que lleva el arduino encendido (uptime).
y de paso a ver si aprendo a hacer bien las conversiones y sacarlas por LCD.

os agradezco mucho la ayuda.
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/

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

lo que has dicho curro de machacar la memoria me ha llevado a comentar todo el codigo que menciono en mi primer mensaje de "funciona pero no se porque"
y ahora el tema de las horas ya funciona,
voy a seguir investigando pero puede que tuviese un codigo que "funcionaba" pero que estropeaba cosas por dentro de la memoria y hace que el programa se bloquee en otros trozos de codigo
no se si me explico.
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/

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

La solución mas practica es reescribir la libreria y sobrecargar el metodo en cuestion.
Te pongo un trozo de codigo de la libreria que tengo hecha para mi pantalla.
Code:
void LCD128x64Class::Write(char* st)
{
  Serial1.print(st);
}

void LCD128x64Class::Write(int st)
{
  Serial1.print( st, DEC );
}

void LCD128x64Class::Write(long st)
{
  Serial1.print(st, DEC );
}

void LCD128x64Class::Write(float st)
{
  static char * valor = "         ";
  valor = dtostrf( st, 4, 2, valor );
  Serial1.print(valor);
}

void LCD128x64Class::Write(float st, int decimales)
{
  static char * valor = "         ";
  valor = dtostrf( st, 4, decimales, valor );
  Serial1.print(valor);
}
Lo mismo que yo e sobrecargado el metodo Write tu puedes hacerlo con tu metodo puts(char *s).

Saludos.


Dukatus cuando tienes esa funcion llamada en todos los casos igual, como decide cual tiene que ejecutar cuando es llamada? Que hace mirar lo que estas enviando y en base a eso escoger entre ellas?
cuando llamas a la funcion le indicas el tipo?
LCD.Write(float 123.24)
o solo envias el numero?

acabo de ver que usas "dtostrf", a ver si puedo adaptar mi libreria y hacer lo mismo y asi no tengo que hacer cosas como esta en el codigo del programa.
Code:
float coste;
      coste = (emon.sumakw/1000)*preciokwh;    // por decidir donde lo meto
      int costedecimales = (coste - (int)coste) * 100;
      sprintf(coste_data,"%0d.%02d E  ",(int)coste,costedecimales);  //d - el argumento es tratado como un integer y presentado como un número decimal (con signo).
      di.puts(coste_data);

seria pillar esto y adaptarlo,no?
Code:
// **************************************************************
// sends char
// **************************************************************
void BV4618_I::putch(char c)
{
  Wire.beginTransmission(_i2adr);
  Wire.send(c);
  Wire.endTransmission();


// **************************************************************
// sends string
// **************************************************************
void BV4618_I::puts(char *s)
{
char *sp=s; 
  Wire.beginTransmission(_i2adr);
  // send *s as bytes of date
  while(*sp)
    Wire.send(*(sp++));
  Wire.endTransmission();

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/

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

bueno Arduino me esta matando !!
Si no fuese poco con los cuelgues del programa debido a las conversiones, ayer el "ethernet shield" decidio que dejaba de funcionar. no se si abrir post para esto o no, el tema es que no funciona ni el ejemplo "webclient" que viene con arduino pero si el "webserver", es decir que si tiene que acceder a internet no funciona, pero por lo demas si, increible.

como solucion para no dejar mi proyecto sin registrar datos me puse a escribir como un loco codigo para usar la memoria SD del "ethernet shield" y guardar los datos ahi.
lo basico funciona pero vuelvo al mismo PROBLEMA:

algo hago mal en las conversiones ya que el codigo funciona cogido con pinzas. es decir, ahora mismo tal como esta funciona. pero si añado un simple Serial.println o lo que sea, ya no va bien y se reinicia.

os puedo poner todo el codigo pero es larguisimo, alguien ve algo que yo no?

Code:
void saveSD(){

  DateTime now = RTC.now();
//  long power = emon.apparentPower;  // tambien he probado a pasarlo a long con cast pero tmb se ralla.
 
//  double apparentPower = 1234.56;
 
//*************************** 

  char s[32];
  dtostrf(emon.apparentPower, 4, 2, s);

/*
char s[32];
Serial.println(dtostrf(-1.0001, 2, 5, s));
*/

String dataString = String(now.unixtime()) + ";" + String(s);

//  String dataString = " Hello ethernet";             // con esta linea va bien siempre
//String dataString = String(count) + ";" + String(count);// + String(charapparentPower);    // + ";230;0.95;1;45";     pretendia que guardase mas valores pero en cuanto habilito mas codigo se reinicia
//***************************

  //Open a file to write to
  //Only one file can be open at a time
  File dataFile = SD.open("loga.txt", FILE_WRITE);
        if(dataFile)
        {
          dataFile.println(dataString);
          dataFile.close();
          Serial.println(dataString);
        }
        else
        {
          Serial.println("Couln't access file");
        }
 
count++;
}


ahora lo tengo almacenando el unixtime stamp y solo 1 parametro ya que si pongo mas se reinicia.
no se si pedir otra ethernet, pero no lo entiendo proque iba perfectamente.
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/

Pages: [1]   Go Up
Jump to: