progress bar richiamare caratteri specialic

ciao ragazzi, volevo sapere come si richiamano i caratteri speciali appena creati, e come posso fare per costruire una progression bar…
la libreria che uso e questa:

dovrebbe essere uguale alla liquidcrystal i2c solo che corretta in modo da non avere problemi nella compilazione…

sono riuscito ad estrapolare questo spezzone di codice qua e la:

//Include the SPI/IIC Library
#include <Wire.h> // Import the arduino Wire (I2C) library used by the next library to controll the LCD
#include <PCF8574_HD44780_I2C.h>// Import the I2C LCD control library

/* Initialise the LiquidCrystal library. The default address is 0x27 and this is a 20 character, 4 line display. Change the values to '16, 2' if you have the smaller version */
PCF8574_HD44780_I2C lcd(0x27,20,4); // Create the LCD object

int B=0;
void setup ()
{
  
   Serial.begin(9600); // Open a serial connection
   delay(100); // Wait 100 milli seconds
   Serial.println("Serial started"); // Print "serial started" to the console then move to a new line
   /* Initialise the LCD */
   Serial.println("Attempting to Initalise LCD..."); // Print whats happening to the serial monitor
   delay(100); // Wait 100 milli seconds
   lcd.init(); // Call the special I2C LCD initalisation function
   Serial.println("LCD Initalised!"); // Update the serial monitor
   lcd.backlight(); // Turn on the LCD backlight
  
    /* LCD Progress Bar Characters, create your custom bars */
   uint8_t bar0[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
   uint8_t bar1[8] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
   uint8_t bar2[8] = { 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 };
   uint8_t bar3[8] = { 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C };
   uint8_t bar4[8] = { 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E };
   uint8_t bar5[8] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
  
   /* Now create those custom characters and store them in the LCD's memory */
   lcd.createChar(0, bar0);
   lcd.createChar(1, bar1);
   lcd.createChar(2, bar2);
   lcd.createChar(3, bar3);
   lcd.createChar(4, bar4);
   lcd.createChar(5, bar5);
    lcd.createChar(5, bar5);
    lcd.setCursor (0,0);
    
}

void loop ()
{
   
  
 
}

volevo sapere come posso costruire la progression bar e richiamare i vari caratteri…
praticamente il mio progetto consiste : a seconda di un pin di imput di arduino scrivere il valore al display e fare un progression bar come scala, cioe piu è grande il valore, piu si riempie…

ma questa liberia l'hai provata ?

http://playground.arduino.cc/Code/LcdBarGraph

questa libreria penso che funzioni per i display collegati normalmente e non per quelli che comunica con arduino tramite protocollo i2c

Primo: perchè 2 volte la creazione del 5 ??

...
lcd.createChar(5, bar5);
lcd.createChar(5, bar5);
lcd.setCursor (0,0);
...

Secondo: crei i caratteri e poi ? Non li usi. Devi usarli con lcd.write(3); con valori da 0 a 5

avevo sbagliato, doveva essere un 6...
ok, comunque adesso ho capito come richiamarli... :slight_smile:
adesso però non so da dove partire per fare l algoritmo di gestione della bar graph... cioe falla diventare piu grande e piu piccola a seconda del valore...
qualche idea?

Si, usa istruzione map()
Dal valore di un analogico ad esempio (0-1023) al valore 0-6 Il valore 0-6 ottenuto diventa quello che passi a lcd.write(0-6)

ma facendo cosi non si riempie solo un singolo quadrato della riga? io vorrei riempire proprio un intera riga... non il singolo quadrato...

Lcd 16x2 ? Allora map() tra 0-1023 e 0-15
dovrai quindi stampare tanti write quanto la map riporta
A questo punto però che cosa sono quei 0-6 caratteri ridisegnati ?

EDIT: quei caratteri sono una carattere 5x8 riempito di un pixel alla volta da sx a dx (quindi quello pieno di 0 serva a nulla)
La map allora dovrebbe essere 0-155 ovvero tutti i singoli pixel 0-75
esempio 37 => stampi int(37/5)=7 caratteri pieni (quelli con 0x1F) e poi 1 carattere con 2 pixel pieni (37-7
5=2) quindi quello pieno di 0x18
esempio 75 => stampi 15 caratteri pieni

non ho capito tanto... :frowning: che caratteri dovrei usare?
inoltre non ho capito che ragionamento hai fatto...

Quei caratteri disegnati, in pratica riempiono la griglia 5x8 di un carattere
Se hai 16 caratteri su una riga, ed ogni carattere occupa 5 pixel in orizzontale, vuol dire che ci sono 16*5 pixel, quindi 80 pixel.
In altezza sono 8 pixel ma non ci interessa.
Da bar 1 a bar 5 il disegno occupa una colonna sola, poi 2 colonne, etc.

Se devi fare una barra di 4 caratteri stamperai 4 del carattere pieno (il bar 5)
Se devi fare una barra di 5 caratteri e poi un carattere con 3 colonne piene e due vuote ? Indovina

quindi mi conviene usare un if per ogni quadrato pieno?

No, un for per riempire di quadrati pieni, fino al necessario -1 poi ultimo char devi vedere quale stampare.

int val=analogRead(A0);   // 0-1023
int quanti= map(val, 0, 1023, 0, 80);
int pieni= int(quanti/5)-1;
int i;
for(i=0;i<=pieni;i++)    // stampa pieni
{ lcd.setCursor(i,0); lcd.write(5);
}
int ultimo=quanti-(pieni+1)*5;   // es. quanti 43=> pieni=7 ultimo=3
lcd.setCursor(i,0); lcd.write(ultimo);

Non l’ho provato.

Forse voleva usare un solo carattere, stampando su una posizione fissa uno solo dei caratteri creati, a seconda del valore raggiunto.

paulus1969:
Forse voleva usare un solo carattere, stampando su una posizione fissa uno solo dei caratteri creati, a seconda del valore raggiunto.

Ma qui dice no a 1 singolo char

marcobiondo13:
ma facendo cosi non si riempie solo un singolo quadrato della riga? io vorrei riempire proprio un intera riga... non il singolo quadrato...

Ops...

Mi sono lasciato trarre in inganno da quei caratteri.

Questo l’ho provato con un potenziometro su A0 (e un led in PWM su pin 6). Non è perfetto, flicchera un pò

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x26, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // on 16x2

const uint8_t bars[][8] = { 
  { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } ,
  { 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 } ,
  { 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C } ,
  { 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E } ,
  { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F } }; 

// pin A0=potenziometro su analogico    
// pin 6=led pilotato in PWM
int i,oldquanti,pieni,quanti;

void setup()
{ delay(1000);
  Serial.begin(9600);
  Serial.println("go.");
  lcd.begin(16,2);               // initialize the lcd 
  for(int i=0; i<=4; i++ )
  { lcd.createChar ( i, (uint8_t *)bars[i] );
  }
  lcd.home();                   // go home
  lcd.print("Hello, ARDUINO ");  
  oldquanti=0;
}  

void loop()
{ int val=analogRead(A0);
  analogWrite(6,map(val,0,1023,0,255));
  quanti=map(val, 0, 1023, 0, 80);
  if(oldquanti!=quanti) 
  { oldquanti=quanti;
    pieni=int(quanti/5)-1;
    lcd.setCursor(0,1); 
    lcd.print("                ");
    for(i=0;i<=pieni;i++)    // stampa pieni
    { lcd.setCursor(i,1); lcd.write(4); 
    }
    int ultimo=quanti-(pieni+1)*5;   // es. quanti 43=> pieni=7 ultimo=3
    lcd.setCursor(i,1); lcd.write(ultimo);  
  }
}

allora non so perche ma con il tuo programma il display rimane illuminato ma vuoto, c e da dire pero che ho messo la mia libreria visto che la <LiquidCrystal_I2C.h> io non sono mai riuscito a farla andare…

//Include the SPI/IIC Library
#include <Wire.h> // Import the arduino Wire (I2C) library used by the next library to controll the LCD
#include <PCF8574_HD44780_I2C.h>// Import the I2C LCD control library

/* Initialise the LiquidCrystal library. The default address is 0x27 and this is a 20 character, 4 line display. Change the values to '16, 2' if you have the smaller version */
PCF8574_HD44780_I2C lcd(0x27,20,4); // Create the LCD object


const uint8_t bars[][8] = { 
  { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } ,
  { 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 } ,
  { 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C } ,
  { 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E } ,
  { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F } }; 

// Setup function (Run once at the start)
void setup()
{
   Serial.begin(9600); // Open a serial connection
   delay(100); // Wait 100 milli seconds
   Serial.println("Serial started"); // Print "serial started" to the console then move to a new line
   /* Initialise the LCD */
   Serial.println("Attempting to Initalise LCD..."); // Print whats happening to the serial monitor
   delay(100); // Wait 100 milli seconds
   lcd.init(); // Call the special I2C LCD initalisation function
   Serial.println("LCD Initalised!"); // Update the serial monitor
   lcd.backlight(); // Turn on the LCD backlight
   
   

}
void loop (){
lcd.write (1);
}

cosi invece funziona, anche se l unica istruzione che ho provato è lcd.write (1)… e mi riempie all infinito il display di una sola linetta… come è giusto che sia…

Prendi il mio e poi:

  1. cambia la include .h
  2. cambia la dichiarazione del lcd
  3. al posto di lcd.begin metti lcd.init
  4. al posto di lcd.home metti lcd.backlight

Dovrebbe bastare questo per fare le modifiche. Ovviamente per avere una barra variabile devi avere un input (analogico) variabile. A me è sembrato comodo un potenziometro.