problema sumando bytes

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:

#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

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

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)

#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

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 :slight_smile:

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.

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:

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()

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?

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...

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:

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 :slight_smile:

El mio no muestra nada en la parte del PC.

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

piratadelestrecho:
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.

chiva:
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?

piratadelestrecho:
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.

@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:

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.

yopero:
... No se debe usar floating point en loops por temas de precisión , blablablabla.

Uff y si te puede causar problemas esto! Hace poco estuvimos instalando unos Sistemas APS y nada más no quedaban las simulaciones precisamente por un problema de éstos.... Parece básico pero a veces lo pasamos por alto.