Vamos a programar #98½ - Ver el rendimiento del PC usando arduino y C#.

 Hola de nuevo a todos, el día de hoy vamos a ver cómo es posible crear una barra de progreso en una pantalla LCD.



En el post anterior vimos cómo es posible usar arduino para monitorear el uso del CPU y la memoria RAM. Usando el programa, era posible visualizar el porcentaje en dos barras de progreso. Si bien todo el programa funcionaba, no lo hacia del todo bien, ya que el procedimiento que se encargaba de hacerlo tenia un par de cosas que le hacían falta y que no consideré hasta que escribí el poste anterior.

Algunas personas me mandaron sus soluciones, y de hecho de eso se trata el blog, no solo de enseñar, si no de aprender todos juntos. Por eso en el post del día de hoy, veremos paso a paso cómo corregir esa situación.

Para empezar vamos a entender cómo es que la barra funciona, en el post anterior, vimos cómo es que se crea cada parte, ahora veamos la lógica. Si hacemos memoria, el código de la barra es el que sigue

void DrawProgressBar(uint8_t Value, uint8_t XLocation, uint8_t YLocation){
    
    uint8_t Progress = map(Value , 1 , 100 , 0 , 20);
    
    lcd.setCursor(XLocation , YLocation);
    
    for (uint8_t i = 0; i < 20; i++)
    {
        if (i == 0)
        {
            if (Progress == 0)
                lcd.write(0);
            else
                lcd.write(1);
        }
            
        else if (i == 19)
        {
            if (Progress == 20)
                lcd.write(3);
            else
                lcd.write(2);
        }
        else
        {
            if (Progress <= i)
                lcd.write(4);
            else
                lcd.write(5);
        }
            
    }
}

Para ver cual es el error, bastará con asignarle algunos valores diferentes de los que trae. La función recibe tres parámetros, el primero es el valor que se quiere representar y debe de ser un valor entre 0 y 100 (o un porcentaje), el segundo es el valor en el cual se posicionara en el eje X y finalmente, el tercero sirve para indica cual será su ubicación en el eje Y. Pero que pasa si usamos otros valores cómo 0 y 3 (solo para las ubicaciones) o 10 y 3. Bueno tendremos algo cómo lo que sigue:

La razón por la que ocurre es que no podemos simplemente poner código y esperar a que funcione, en algunos de los post previos, vimos a grandes rasgos cómo es que funciona la pantalla y el resultado anterior es debido a que primera línea, continua en la tercera y la segunda continua en la cuarta, entonces si escribimos la barra con su tamaño "completo" al llegar al linte se la primera o segunda línea, esta continuara en la tercera o cuarta.

Para poder resolver el problema, vamos a tomar en cuenta cuales son las cosas que tenemos. Para empezar, hay que considerar el tamaño de la pantalla, cómo es algo que no cambia (para cada caso individual), una vez que tenemos identificado el tamaño, lo podemos asignar a unas constantes, para eso, justo antes de crear el objeto de pantalla "lcd" definimos a "SCREEN_SIZE_X" que será el tamaño de la pantalla en el eje X y que en mi caso es 20, también definimos "SCREEN_SIZE_Y" que será el tamaño de la pantalla y que en mi caso es 4. Para el caso de una pantalla de 16x2, bastara con asignar a "SCREEN_SIZE_X" con 16 y a "SCREEN_SIZE_Y" con 2. Cuando creamos el objeto "LiquidCrystal_I2C", pasamos el primer parámetro "0x27" que es la dirección por la cual se comunicará (y puede cambiar pero por ahora cómo es el único dispositivo I2C conectado), luego se pasa el parámetro del tamaño en X de la pantalla, seguido por el del eje Y.




Ahora que tenemos identificado el tamaño de la pantalla, podemos hacer los cálculos de manera mas sencilla en el procedimiento "DrawProgressBar", la barra esta pensada para que se dibuje desde la ubicación del parámetro "XLocation" hasta el final de la pantalla, entonces si ahora que tenemos el tamaño de la pantalla, para determinar el tamaño de la barra, bastará con restar el tamaño de la pantalla menos la ubicación en el eje X, el resultado de está operación lo podemos asignar a una variable y así en lugar de iterar de uno a un número fijo, lo haremos solo hasta lo que debe de ser la longitud de la barra. Así podemos hacer un código cómo el que sigue solo para la barra y las definiciones del tamaño.
//Para las pantallas de 16 x 2, basta con reemplazar el 20 por 16  y el 4 por 2
#define SCREEN_SIZE_X 20
#define SCREEN_SIZE_Y 4

//SCL - A5
//SDA - A4
LiquidCrystal_I2C lcd(0x27 , SCREEN_SIZE_X , SCREEN_SIZE_Y);

//{..............}
//Barra de progreso
void DrawProgressBar(uint8_t Value, uint8_t XLocation, uint8_t YLocation){
    
    uint8_t BarSize = SCREEN_SIZE_X - XLocation;
    
    uint8_t Progress = map(Value , 1 , 100 , 0 , BarSize);
    
    lcd.setCursor(XLocation , YLocation);   

    
    for (uint8_t i = 0; i < BarSize; i++)
    {
        if (i == 0)
        {
            if (Progress == 0)
                lcd.write(0);
            else
                lcd.write(1);
        }
            
        else if (i == BarSize - 1)
        {
            if (Progress == BarSize)
                lcd.write(3);
            else
                lcd.write(2);
        }
        else
        {
            if (Progress <= i)
                lcd.write(4);
            else
                lcd.write(5);
        }
            
    }
}

Ahora si miramos la imagen anterior, para poder usar una barra similar, bastará con usar "100 , 11 , 1" cómo parámetros. Hay que resaltar que el tamaño de la barra debe de ser mínimo de tres por lo que la posición máxima en X es 17, cualquier número más allá de el, hará que la barra no se muestre correctamente.

Y bien, por ahora es todo, el vínculo actualizado como de costumbre lo puedes descargar de mi dropbox, para que lo modifiques a tu gusto (si por ejemplo quieres cambiar el tamaño sin que pegue en la orilla).

Los leo luego.

No hay comentarios.