Pages: [1]   Go Down
Author Topic: problema sumando bytes  (Read 1822 times)
0 Members and 1 Guest are viewing this topic.
Algeciras
Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

Es la primera vez que escribo en esta sección del foro, lo que estoy intentando hacer es una tontería, pero no consigo que funcione.... Lo único que quiero hacer es imprimir una posición de un lcd de manera que aparezcan barras verticales de derecha a izquierda hasta rellenar el carácter...
O lo que es lo mismo, tener un byte[8] que se inicie en [00000,00000,00000,00000,00000] y progresivamente vaya convirtiéndose de la siguiente forma:

00000,
00000,
00000,
00000,
00000

00001,
00001,
00001,
00001,
00001

00011,
00011,
00011,
00011,
00011


etc...


Aquí os dejo el código con los serial outputs para el debug:

Code:
#include <LiquidCrystal.h>
// custom charaters
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
byte p6[8];
 
void setup()   {
  lcd.begin(16, 2);
  lcd.createChar(6, p6);
  Serial.begin(9600);
}

void loop()
{
byte p6[8] = {
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00};
  lcd.setCursor(0, 0);
  for (int i = 0; i < 16; i = i + 1) {
    lcd.print(" ");
  }
  lcd.setCursor(0,0);
  lcd.write(6);
//Vertical
for (int j= 0; j<5;j++){
    Serial.println(" ");
    Serial.print("VALOR DE J: ");
    Serial.println(j);
    Serial.print("VALOR DE 2 Elevado a J: ");
    Serial.println(pow(2,j));
    Serial.println("----------");
    for (int i=0; i<8;i++){             
      delay(50);   
      p6[i]=p6[i]+pow(2,j); 
      Serial.print("valor de i: ");
      Serial.println(i);
      Serial.print("valor de p6[i]: ");
      Serial.println(p6[i]);
    }   
    lcd.createChar(6, p6);
    lcd.write(6);   
}
Serial.println("-------------------------");
delay (1000);
lcd.print("1");
delay(4000);
}

Yo creo que el problema viene dado porque al sumar el byte con el pow de 2^i por alguna razón que desconzco se le resta uno al resultado de la potencia...

Bueno espero que alguien pueda echarme una mano...

Muchas gracias de antemano
Logged

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

Me parece que te quieres complicar demasiado con pow():

Code:
byte mascara[9]={0,1,3,7,15,31,63,127,255};

for(int i=0; i<9; i++)  // Vamos rellenando los carácteres de columnas
  for(int j=0; j<5; j++)  // Cambiamos cada uno de los 5 carácteres
    p6[j]=mascara[i];

en mascara [ i ] tienes el valor que quieres poner en los carácteres en cada paso:
0 ---> [00000000]
1 ---> [00000001]
3 ---> [00000011]
5 ---> [00000111]
...
255 -> [11111111]

Si quieres hacerlo con calculos, piensa en desplazamientos en lugar de potencias (multiplicar algo por 2 es hacer un desplazamiento a la izquierda)
Logged

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

Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
byte p[8];

void setup(){
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
 
  byte barra = 0;
  for (byte i=0; i<5; i++){
    barra = (1 << i) | barra;
    for (byte j=0; j<8; j++){
      p[j] = barra;
    }
    lcd.createChar(i, p);
    lcd.write(i);
  }
}

void loop(){}

Hará más de una año que no manejo una pantalla de estas, asi que espero que funcione
Logged

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

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

Gracias a los dos parecen soluciones mucho más sencillas y lógicas que lo que yo planteaba (tengo el arduino y la pantalla en el trabajo así que lo probaré mañana), pero, siendo un poco cabezota, sabéis por qué no me funciona de la forma que lo he planteado???


Un saludo smiley
Logged

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

Si la compilación del código que he hecho en mi cabeza es correcta, según lo que has escrito debería aparecer en cada carácter una línea vertical que se va moviendo hacia la izquierda, pero no se rellena el espacio dejado a la derecha de esta.
Logged

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

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

Chivas tu código no me muestra nada en pantalla de cualquier forma me ayudaría mucho que me aclaraseis por qué este trocito de código:

Code:
void loop()
{
byte p6[8] = {
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00};
for (int j= 0; j<5;j++){
    for (int i=0; i<8;i++){              
      p6[i]=p6[i]+pow(2,j);  
 
      Serial.print(p6[i]);
      Serial.print("-");
    }    
}Serial.println("------------------------------");
}

No devuelve los valores de p6 que cabe esperar...


esto es lo que yo entiendo que debe salir:

1-1-1-1-1-1-1-1-3-3-3-3-3-3-3-3-7-7-7-7-7-7-7-7-15-15-15-15-15-15-15-15-31-31-31-31-31-31-31-31

y esto lo que sale:

1-1-1-1-1-1-1-1-3-3-3-3-3-3-3-3-6-6-6-6-6-6-6-6-13-13-13-13-13-13-13-13-28-28-28-28-28-28-28-28

Para cada iteración de void loop()
« Last Edit: June 01, 2012, 02:39:12 am by piratadelestrecho » Logged

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

Según la referencia de Arduino, el uso de pow() requiere parámetros de tipo float, y el exponente debe ser fraccional.

http://arduino.cc/en/Reference/Pow

Puede que no funcione correctamente con los parámetros que le estás pasando.

De todas formas, lo que quieres hacer es mucho más sencillo como te hemos dicho: utilizando directamente los valores en un array o bien calculándolos a partir de desplazamientos.

¿Podrías poner los resultados que te salen con los ejemplos que hemos puesto? ¿Y el código que has utilizado?
Logged

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

Con el código de chiva no me sale nada. con el tuyo funciona perfectamente.
En cuanto al fallo, con este código que está todavía más simplificado se ve perfectamente como al pasar de float a int por alguna razón que desconozco le resta uno al resultado...

Code:
void setup(){
  Serial.begin(9600);
}
void loop(){
float k=2;
for (float p= 0; p<5;p++){
Serial.print(pow(k,p));
Serial.print("-");
Serial.println(int(pow(k,p)));
}
}

La salida es la siguiente:

Quote
1.00-1
2.00-2
4.00-3
8.00-7
16.00-15
Como véis el pow se hace bien pero al pasarlo a int pierde un valor a partir de la segunda iteración...

Ya no es por el tema del display jorge que con tu sugerencia funciona perfectamente, es que no entiendo porqué falla la conversión, debe ser algo muy tonto pero es que se me escapa...

Gracias por vuestra ayuda una vez más smiley


Logged

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

El mio no muestra nada en la parte del PC.

Cambia pow(2,j) por (1 << j)
Logged

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

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

Como véis el pow se hace bien pero al pasarlo a int pierde un valor a partir de la segunda iteración...

Ya no es por el tema del display jorge que con tu sugerencia funciona perfectamente, es que no entiendo porqué falla la conversión, debe ser algo muy tonto pero es que se me escapa...

Te vuelvo a dirigir a la referencia de la función. Si utilizas valores enteros como parámetros, puede (y parece que lo hace) funcionar mal. De hecho, en la referencia pone que el exponente sea fraccional (<1). Al utilizarla de la manera que pretendes, puede que en algún paso de la conversión pierda precisión y por eso el resultado final es distinto.
Logged

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

El mio no muestra nada en la parte del PC.

Cambia pow(2,j) por (1 << j)

Chivas qué hace exactamente 1<< j????? por cierto funciona de lujo

nunca había visto esa expresión...
en cuanto a la conversión, que puedes decirme?
Logged

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

Chivas qué hace exactamente 1<< j?????

nunca había visto esa expresión...
en cuanto a la conversión, que puedes decirme?

Es la otra opción que te estamos planteando, utilizar desplazamientos binarios:
Si j= 3:
1<<3 Desplaza un 1 tres posiciones a la izquierda en un byte (en binario):
Valor inicial: 00000001
Desplazamiento de una posición a la izquierda: 00000010
Desplazamiento de dos posición a la izquierda: 00000100
Desplazamiento de tres posición a la izquierda: 00001000

Como puedes ver según el valor de j, el uno va desplazandose a la izquierda j posiciones.

Si conviertes los números a decimal verás que cada desplazamiento es como multiplicar por 2

PD: También está el desplazamiento a la derecha (>>) que hace el proceso inverso.
Logged

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

@piratadelestrecho, el problema de pasar float a int,e s que float no representa un número de forma exacta, si no aproximada, por lo que 4.00, puede ser en realidad, 3.999999974903, y al pasar a int se trunca la parte decimal quedando 3, eso debería poder solucionarse de la siguiente manera:

int(pow(2,j)+0.5)

Si tienes curiosidad:
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
http://en.wikipedia.org/wiki/Single_precision
« Last Edit: June 01, 2012, 04:57:23 am by chiva » Logged

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

Madrid
Offline Offline
Sr. Member
****
Karma: 5
Posts: 481
Life isn't about finding yourself, life is about creating yourself!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

La propuesta de @chiva es la mas eficiente y yo me quedaría con ella.

Como ya lo ha comentado jorgepl te estas complicando la vida y hay otras formas de obtener lo que quieres y sobre todo:

No se debe usar floating point en loops por temas de precisión , blablablabla.https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters

Aun así y con  finalidad didáctica y como curiosidad; usando tu código podrías incluir la librería math.h y hacerle un round a los float.
Logged

Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

Pages: [1]   Go Up
Jump to: