[résolu] Affichage de la capacité batterie sur écran oled

Bonjour à tous, je veux afficher la capacité d’une batterie plomb 24v sur un écran oled 0.96" 128*64.
Je sais déjà - mesurer la tension des batteries avec un pont diviseur de tension et des calculs.

  • définir un pourcentage selon une tension ( échelle de 10% en 10% )
  • afficher ce pourcentage sur l’écran oled.

Mais j’aimerais afficher la capacité en % dans un petit bitmap batterie comme ça (voir en lien).
Le problème c’est que j’aimerais me créer ce bitmap batterie et donc écrire dedans avec
display.println(“100%”);

Le code que j’ai créé permettant de réaliser toute la catégorie " je sais déjà " :

/*                                                    programme pour afficher et mesurer une tension max de 30VDC pour batteries
 *schema de montage pont diviseur de tension         VIN 30vdc        R1 = 10kOhm     R2 = 2KOhm    Vout = 5V quand Vin 30v
 * 
 * pour plus de précision mesurer avec précision les résistances r1 et r2 et calculer   Vout    sur digikey___calcul_pont_diviseur_de_tension faire 204,6 / ( VIN / Vout )
 * 
 * 
 * les valeurs de capacité selon tensions sont trouvées sur internet et à peu près vrai ( la capacité ne dépent pas que de la tension )  
 */

 
 
#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );



void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  
}

void loop(){
  
  float tension = analogRead(A0);  //définie la broche mesurant la tension
  tension = ( tension / 34.1 );   //calcule la tension réelle

  int restant;
  if ( tension >= 25.46 ) {
    restant = 100;
  }

  else if ( tension >= 25.24 ) {
    restant = 90;
  }

  else if ( tension >= 25 ) {
    restant = 80;
  }

  else if ( tension >= 24.74 ) {
    restant = 70;
  }

  else if ( tension >= 24.48 ) {
    restant = 60;
  }

  else if ( tension >= 24.20 ) {
    restant = 50;
  }

  else if ( tension >= 23.92 ) {
    restant = 40;
  }

  else if ( tension >= 23.63 ) {
    restant = 30;
  }

  else if ( tension >= 23.32 ) {
    restant = 20;
  }

  else if ( tension >= 23.02 ) {
    restant = 10;
  }
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(4, 0);
  display.print(restant);
  display.print(" % ");
  display.display();
  delay(500);
  display.clearDisplay();
}

Ah oui, j’utilise un afficheur OLED de 0.96’’ 128*64 en I2C ( adresse I2C trouvé avec scanner = 0x3C ) avec un driver intégré SSD1306 et mon code fonctionne parfaitement (celui que j’ai mis ).

La bibliothèque graphique que tu utilises contient certainement des fonctions pour tracer un rectangle, vide ou plein. Donc il te suffit de tracer deux rectangles côte à côte et d'écrire ton texte à l'intérieur. Si tu choisis la première icône, il faut en plus effacer la ligne commune aux deux rectangles, simplement en traçant une ligne de la couleur du fond. Le plus dur est de trouver les coordonnées des extrémités des rectangles pour que ça donne la bonne icône...

Je suis sûr que la bibliothèque a une fonction pour tracer des rectangles (gfx a fillRect). A ce propos, il semblerait que les afficheurs graphiques monochrome aient un mode XOR, qui est supporté par gfx.cpp dans son github: fillRect peut avoir comme argument INVERSE, spécifique au SSD1306)

Les exemples de demo spécifiques au 1306 activent ce mode.....(pour des rectangles et des triangles)

Dans ce cas, on n'a pas besoin de tracer les rectangles d'abord, puis le texte: on trace le texte d'abord, et les rectangles sont remplis avec le contraire (ça ne peut marcher que pour des ecrans monochromes) des pixels precedents (le texte, qui était auparavant blanc sur fond noir, disons, devient noir sur fond blanc) Cette astuce ne marche que pour des ecrans bicilores/monochromes (0 et 1)

C’est fini, j’ai réussi !!!
Merci pour vos réponses simples mais bien ( la preuve… ).

J’ai laissé la barre entre les deux carrés car finalement, je trouve ça plus “stylée”.

Mon code :

/*                                                    programme pour afficher et mesurer une tension max de 30VDC pour batteries
 *schema de montage pont diviseur de tension         VIN 30vdc        R1 = 10kOhm     R2 = 2KOhm    Vout = 5V quand Vin 30v
 * 
 * pour plus de précision mesurer avec précision les résistances r1 et r2 et calculer   Vout    sur digikey___calcul_pont_diviseur_de_tension faire 204,6 / ( VIN / Vout )
 * 
 * 
 * les valeurs de capacité selon tensions sont trouvées sur internet et à peu près vrai ( la capacité ne dépent pas que de la tension )  
 */

 
 
#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );



void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  
  
  
}

void loop(){


   //partie bitmap affiché continuellement
  display.display();
  display.drawRect( 101,  0,  27,  11,  WHITE);  //changer les x et y ( la position)              ligne 1
  display.drawRect( 96,  3,  5,  5,  WHITE);  //si ligne 1 changé de position, faire 2 premieres valeurs -3 et les recopier
  display.display();


  
 float tension = analogRead(A0);  //définie la broche mesurant la tension
  tension = ( tension / 34.1 );   //calcule la tension réelle

  int restant;
  if ( tension >= 25.46 ) {
    restant = 100;
  }

  else if ( tension >= 25.24 ) {
    restant = 90;
  }

  else if ( tension >= 25 ) {
    restant = 80;
  }

  else if ( tension >= 24.74 ) {
    restant = 70;
  }

  else if ( tension >= 24.48 ) {
    restant = 60;
  }

  else if ( tension >= 24.20 ) {
    restant = 50;
  }

  else if ( tension >= 23.92 ) {
    restant = 40;
  }

  else if ( tension >= 23.63 ) {
    restant = 30;
  }

  else if ( tension >= 23.32 ) {
    restant = 20;
  }

  else if ( tension >= 23.02 ) {
    restant = 10;
  }
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(103, 2);
  display.print(restant);
  display.print("%");
  display.display();



  
  

  
 
  
}

Mais j’ai un problème (enfin je pense car je n’ai pas testé avec une batterie qui se décharge donc qui passe d’une valeur à une autre ), c’est que l’écran ne se réactualise jamais ( enfin je pense ), j’aimerais qu’il se réactualise toutes les “je choisirais le temps car je ne sais pas encore” mais que ce ne soit que la valeur qui se réactualise et non l’icône batterie. Est-ce possible ???

Je voudrais aussi que la réactualisation ne se voit presque pas, je sais pas si c’est possible avec un écran oled comme j’ai et une arduino.

Si la réactualisation n’est pas assez rapide, pourrais-je réactualiser l’écran que quand on passe d’un pourcentage à un autre ?

Pour actualiser l'affichage du texte, tu as deux solutions. Celle qui marche : tu affiches un rectangle plein (fillRectangle) de la couleur du fond à l'endroit où s'affiche ton texte. Puis tu écris le nouveau texte. Celle qui marche peut-être : tu affiches un texte fait uniquement d'espaces à l'endroit du texte puis tu affiches le nouveau texte.

??? Désolé mais je n'ai pas compris

Sinon, est-ce possible de faire

delay(1000);
display.clear();

mais de "clear" juste le texte et non tout l'affichage

Non je ne pense pas

Pourrais-tu (lesept) me rééxpliquer

lesept: Pour actualiser l'affichage du texte, tu as deux solutions. Celle qui marche : tu affiches un rectangle plein (fillRectangle) de la couleur du fond à l'endroit où s'affiche ton texte. Puis tu écris le nouveau texte. Celle qui marche peut-être : tu affiches un texte fait uniquement d'espaces à l'endroit du texte puis tu affiches le nouveau texte.

???

Le texte que tu veux actualiser est compris à l'intérieur d'un rectangle, a priori de la couleur du fond de l'écran. Pour effacer ce texte, tu traces un nouveau rectangle de la couleur du fond à cet endroit précis, puis tu écris le nouveau texte au même endroit

D’accord, maintenant c’est bon et la réactualisation ne se voit pas à “l’œil nu”. En fait il a fallu que je fasse comme tu disais mais le mettre juste avant l’écriture des données pour que le temps de tous les calculs ne soient pas pris en compte ( tous les else if ).

Le code final avec actualisation toutes les 750 ms ( à changer si on veux mais de toute façon ça ne se voit pas; seul bémol, il faut attendre 750ms au début du programme pour voir apparaître la valeur mais cela ne me gène pas.

/*                                                    programme pour afficher et mesurer une tension max de 30VDC pour batteries
 *schema de montage pont diviseur de tension         VIN 30vdc        R1 = 10kOhm     R2 = 2KOhm    Vout = 5V quand Vin 30v
 * 
 * pour plus de précision mesurer avec précision les résistances r1 et r2 et calculer   Vout    sur digikey___calcul_pont_diviseur_de_tension faire 204,6 / ( VIN / Vout )
 * 
 * 
 * les valeurs de capacité selon tensions sont trouvées sur internet et à peu près vrai ( la capacité ne dépent pas que de la tension )  
 */

 
 
#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );



void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  
  
  
}

void loop(){


   //partie bitmap affiché continuellement
  display.display();
  display.drawRect( 101,  0,  27,  11,  WHITE);  //changer les x et y ( la position)              ligne 1
  display.drawRect( 96,  3,  5,  5,  WHITE);  //si ligne 1 changé de position, faire 2 premieres valeurs -3 et les recopier
  display.display();


  
 float tension = analogRead(A0);  //définie la broche mesurant la tension
  tension = ( tension / 34.1 );   //calcule la tension réelle

  int restant;
  if ( tension >= 25.46 ) {
    restant = 100;
  }

  else if ( tension >= 25.24 ) {
    restant = 90;
  }

  else if ( tension >= 25 ) {
    restant = 80;
  }

  else if ( tension >= 24.74 ) {
    restant = 70;
  }

  else if ( tension >= 24.48 ) {
    restant = 60;
  }

  else if ( tension >= 24.20 ) {
    restant = 50;
  }

  else if ( tension >= 23.92 ) {
    restant = 40;
  }

  else if ( tension >= 23.63 ) {
    restant = 30;
  }

  else if ( tension >= 23.32 ) {
    restant = 20;
  }

  else if ( tension >= 23.02 ) {
    restant = 10;
  }
  
  delay(750);
  display.fillRect( 102,  1,  25,  9,  BLACK);
  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(103, 2);
  display.print(restant);
  display.print("%");
  display.display();


}

Mets un splash screen au démarrage, ça fera patienter pendant les 750 ms si début

Qu’est ce qu’un splash screen ? qu’est ce qu’il faut ajouter ??

En jargon informatique, un splash screen (traduction littérale : écran d’éclaboussure ; en français, on devrait dire page de garde, fenêtre d’attente ou écran de lancement) est la toute première fenêtre affichée par un logiciel.

Cette fenêtre incite l’utilisateur à patienter pendant le chargement et l’installation d’un logiciel tout en lui apportant diverses informations comme le nom du logiciel, le nom de l’éditeur, le logo de l’éditeur ou du logiciel, les droits d’auteur associés au logiciel, la version et l’état du chargement du logiciel.

(wikipedia)

En gros, tu dessines un petit truc ou tu affiches un titre sur l’écran pour faire patienter l’utilisateur, pendant que ton microprocesseur travaille en arrière plan.

D’accord j’ai compris, en gros je peut-mettre un truc dans setup et voila ( un peu le style comme le logo d’adafruit ?? )

Mais le problème c’est que c’est un delay juste avant l’écriture que j’ai placé là pour ne pas voir le temps de réactualisation ( car si je mets ça après, ça doit faire tous les calculs de tension et de restant ).

Après, personnellement ça ne me gène pas donc je ne pense pas changer le code du coup

Pour info tout le code est en open-source ( normal ) et j’invite les gens qui le modifie à le partager sur le forum.
Et j’ai rajouté un truc dans le titre : [résolu] !!!

Merci beaucoup pour toutes vos réponses.

/*                                                    programme pour afficher et mesurer une tension max de 30VDC pour batteries
 *schema de montage pont diviseur de tension         VIN 30vdc        R1 = 10kOhm     R2 = 2KOhm    Vout = 5V quand Vin 30v
 * 
 * pour plus de précision mesurer avec précision les résistances r1 et r2 et calculer   Vout    sur digikey___calcul_pont_diviseur_de_tension faire 204,6 / ( VIN / Vout )
 * 
 * 
 * les valeurs de capacité selon tensions sont trouvées sur internet et à peu près vrai ( la capacité ne dépent pas que de la tension )  
 */

 
 
#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

#define OLED_RESET 4
Adafruit_SSD1306 display( OLED_RESET );



void setup () {
  display.begin( SSD1306_SWITCHCAPVCC, 0x3C );
  display.clearDisplay();
  
  
  
}

void loop(){


   //partie bitmap affiché continuellement
  display.display();
  display.drawRect( 101,  0,  27,  11,  WHITE);  //changer les x et y ( la position)              ligne 1
  display.drawRect( 96,  3,  5,  5,  WHITE);  //si ligne 1 changé de position, faire 2 premieres valeurs -3 et les recopier
  display.display();


  
 float tension = analogRead(A0);  //définie la broche mesurant la tension
  tension = ( tension / 34.1 );   //calcule la tension réelle

  int restant;
  if ( tension >= 25.46 ) {
    restant = 100;
  }

  else if ( tension >= 25.24 ) {
    restant = 90;
  }

  else if ( tension >= 25 ) {
    restant = 80;
  }

  else if ( tension >= 24.74 ) {
    restant = 70;
  }

  else if ( tension >= 24.48 ) {
    restant = 60;
  }

  else if ( tension >= 24.20 ) {
    restant = 50;
  }

  else if ( tension >= 23.92 ) {
    restant = 40;
  }

  else if ( tension >= 23.63 ) {
    restant = 30;
  }

  else if ( tension >= 23.32 ) {
    restant = 20;
  }

  else if ( tension >= 23.02 ) {
    restant = 10;
  }
  
  delay(750);
  display.fillRect( 102,  1,  25,  9,  BLACK);
  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(103, 2);
  display.print(restant);
  display.print("%");
  display.display();


}