Textsize Oled Adafruit SSD1306 (128x64)

Bonjour à tous,
utilisant pour la première fois un écran, je me suis tourné vers celui-ci Monochrome 0.96 128x64 OLED Graphic Display - STEMMA QT : ID 326 : Adafruit Industries, Unique & fun DIY electronics and kits, câblé en I2C.
Tout fonctionne parfaitement avec l'arduino pro mini 5v/16mhz de chez sparkfun.

J'utilise la librairie par défaut d'Adafruit, et mon problème vient du fait que je ne peux mettre une valeur à virgule dans mon display.setTextSize(xx);.
Ce site confirme mes dires :

Finalement, setTextSize(size) multipliera l'échelle d'affichage du test par un facteur entier.

Comment puis-je faire pour utiliser un nombre décimal en tant que taille pour mon texte ?

J'ai essayé d'utiliser une autre librairie (MultiLCD - a library for displaying texts on different LCD/OLED - Displays - Arduino Forum), mais sans succès, rien ne s'affiche à l'écran j'ai certainement dû zapper quelque chose

merci pour votre aide

Salut,

Si la lib demande un integer et bien c'est tout simplement impossible de lui passer un nombre à virgule tel quel. Si tu veux le faire il faudra modifier la lib

merci pour ta réponse
Donc, comment puis-je modifier cette lib ?

en recherchant dans la lib "GFX" je trouve ceci ce rapportant à "setTextSize" :
Adafruit_GFX.cpp :

void Adafruit_GFX::setTextSize(uint8_t s) {
  textsize = (s > 0) ? s : 1;
}

Adafruit_GFX.h :

  void
    ...
    setTextSize(uint8_t s),
    ...

J'ai des connaissances autodidactes en langage web dont PHP(qui m'aide un peu dans compréhension du C++),... ce qui me permet de comprendre un peu le code arduino, mais une aide m'est quand même nécessaire :), ça ne doit pas être si compliqué d'autoriser les chiffres décimaux en plus des chiffres entiers...
Avez-vous une solution plus concrète ? Ou une personne ayant déjà eu ce problème ?
merci

Bonsoir,
Sans modif de la librairie, essaie ceci :
Récupérer la partie entiere
Récupérer la partie décimale
multiplier la partie decimale par 10, 100, 1000 (en fonction du nombre de décimale souhaité)
pour la transformer en entier
ensuite afficher partie entiere + point + partie entière décimale( si j'ose dire)

PhilAin:
Bonsoir,
Sans modif de la librairie, essaie ceci :
Récupérer la partie entiere
Récupérer la partie décimale
multiplier la partie decimale par 10, 100, 1000 (en fonction du nombre de décimale souhaité)
pour la transformer en entier
ensuite afficher partie entiere + point + partie entière décimale( si j'ose dire)

Houla, c'est quoi ces théories ?
Il faut que tu revois les types de variables et les opérateurs, tu verra que . n'est pas un opérateur et qu'on peut pas mettre de nombre à virgule dans un int !

pro_info:
merci pour ta réponse
Donc, comment puis-je modifier cette lib ?

en recherchant dans la lib "GFX" je trouve ceci ce rapportant à "setTextSize" :
Adafruit_GFX.cpp :

void Adafruit_GFX::setTextSize(uint8_t s) {

textsize = (s > 0) ? s : 1;
}



Adafruit_GFX.h :


void
    ...
    setTextSize(uint8_t s),
    ...




J'ai des connaissances autodidactes en langage web dont PHP(qui m'aide un peu dans compréhension du C++),... ce qui me permet de comprendre un peu le code arduino, mais une aide m'est quand même nécessaire :), ça ne doit pas être si compliqué d'autoriser les chiffres décimaux en plus des chiffres entiers...
Avez-vous une solution plus concrète ? Ou une personne ayant déjà eu ce problème ?
merci

La partie que tu montres n'est que la vérification que la variable s donnée est valide, si tu veux modifier la librairie pour pouvoir donner un nombre à virgule il faut que tu changes le type de la variable textsize, tu devrais trouver une déclaration du genre de

uint8_t textsize = 1;

Et il faudra que tu modifies tout les calculs effectués par la lib avec textsize en t'assurant que le nombre à virgule soit bien pris en compte

Je rappelle que 25.36 * 1 = 25 et 25.36 * 1.0 = 25.36 (à cause des conversions implicites)

ok, donc j'ai fait une nouvelle recherche concernant "textsize", voici ce que ça me donne :

il me faudrait remplacer en théorie les int par des float, mais par quoi dois-je remplacer les "uint8_t" & "int16_t" qui sont des dérivés de int ?
voici pour le premier résultat :

Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h):
  WIDTH(w), HEIGHT(h)
{
  _width    = WIDTH;
  _height   = HEIGHT;
  rotation  = 0;
  cursor_y  = cursor_x    = 0;
  textsize  = 1;
  textcolor = textbgcolor = 0xFFFF;
  wrap      = true;
}

le second :

#if ARDUINO >= 100
size_t Adafruit_GFX::write(uint8_t c) {
#else
void Adafruit_GFX::write(uint8_t c) {
#endif
  if (c == '\n') {
    cursor_y += textsize*8;
    cursor_x  = 0;
  } else if (c == '\r') {
    // skip em
  } else {
    drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
    cursor_x += textsize*6;
    if (wrap && (cursor_x > (_width - textsize*6))) {
      cursor_y += textsize*8;
      cursor_x = 0;
    }
  }
#if ARDUINO >= 100
  return 1;
#endif
}

la vérification de mon post précédent :

void Adafruit_GFX::setTextSize(uint8_t s) {
  textsize = (s > 0) ? s : 1;
}

dans le fichier Adafruit_GFX.h

  void
    drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
    drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
      uint16_t color),
    fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
    fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
      int16_t delta, uint16_t color),
    drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
      int16_t x2, int16_t y2, uint16_t color),
    fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
      int16_t x2, int16_t y2, uint16_t color),
    drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
      int16_t radius, uint16_t color),
    fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
      int16_t radius, uint16_t color),
    drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap,
      int16_t w, int16_t h, uint16_t color),
    drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color,
      uint16_t bg, uint8_t size),
    setCursor(int16_t x, int16_t y),
    setTextColor(uint16_t c),
    setTextColor(uint16_t c, uint16_t bg),
    setTextSize(uint8_t s),
    setTextWrap(boolean w),
    setRotation(uint8_t r);

puis ceci :

 protected:
  const int16_t
    WIDTH, HEIGHT;   // This is the 'raw' display w/h - never changes
  int16_t
    _width, _height, // Display w/h as modified by current rotation
    cursor_x, cursor_y;
  uint16_t
    textcolor, textbgcolor;
  uint8_t
    textsize,
    rotation;
  boolean
    wrap; // If set, 'wrap' text at right edge of display
};

Désoler d'avoir tout copier/coller comme ceci, mais pas mal de choses que je pense devoir modifier, ont l'air d'utiliser les uint8_t & int16_t, c'est dans le but de faciliter la tâche.
Vu la structure, je pense que les nombres décimaux seront plus faciles à mettre en place pour toutes les "fonctions" que pour une seule, notamment à la vue de ceci "Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): WIDTH(w), HEIGHT(h)" qui à l'air d'être utilisé pour les différentes options possibles sur le texte.

Dans le cas où ce serait plus simple, il faudrait mettre à part le "textsize" en le modifiant avec quelque chose de ce style d'après ce que j'ai compris :

Adafruit_GFX::Adafruit_GFX(float...... w, float...... h):
  WIDTH(w), HEIGHT(h)
{
  _width    = WIDTH;
  _height   = HEIGHT;
  textsize  = 1.0;
}

S'il vous vient une idée...
merci

Houla, c'est quoi ces théories ?
Il faut que tu revois les types de variables et les opérateurs, tu verra que . n'est pas un opérateur et qu'on peut pas mettre de nombre à virgule dans un int !

Je persiste dans ma théorie, on peut bien transformer l_a partie décimale_ d'un float en Int et l'afficher.

float pi=3.1411600112;
int partieEntiere;
float partieDecimale;
unsigned int afficheDecimale; 

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
partieEntiere=abs(pi);// recupere la valeur entiere
partieDecimale=(pi-partieEntiere)*100000;
// recupere la valeur decimale * par puissance de 10 pour le nombre de decimale
afficheDecimale=partieDecimale; // transforme le float en int
Serial.println(pi,DEC);
Serial.print(partieEntiere);Serial.print(",");Serial.println(afficheDecimale);
delay(2000);
}

et ça marche. A condition de ne pas le maxi autorisé pour un unsigned int. Ce ne devrais pas être trop difficile (?) de
créer une nouvelle fonction dans la librairie adéquate.

Je pense qu'avant de continuer il faudrait réfléchir avec un minimum d'esprit critique.
Pour moi, il y a 2 impossibilités majeures à la tenue de cette exigence.
L'afficheur
Utiliser une taille de caractère avec des décimales nécessite de faire de l'interpolation lors du tracé des caractères. Qui dit interpolation dit niveaux de couleurs or cet afficheur est monochrome. Le résultat va donc être complètement pourri.

La librairies utilise une bitmap
L'utilisation de bitmap ne se prête pas bien à la modification de la taille des caractères hormis en utilisant des facteurs entiers (et encore cela fini souvent en gros pâtés pas beau). Pour faire des polices de taille variable en continue il faut passer à des polices vectorielles.

PhilAin:
Je persiste dans ma théorie, on peut bien transformer l_a partie décimale_ d'un float en Int et l'afficher.

Sauf qu'il s'agit de modifier la taille du texte, pas d'afficher un nombre à virgule sur l'écran.

Sinon +1 avec fdufnews, je pensais que c'était une police vecto mais si c'est du bitmap ...

Mea-culpa, je n'avais pas vu que c'était pour une taille de texte.
Il va falloir :

  1. que j'apprenne à lire
  2. que je cours chez l'ophtalmo

fdufnews:
Je pense qu'avant de continuer il faudrait réfléchir avec un minimum d'esprit critique.
Pour moi, il y a 2 impossibilités majeures à la tenue de cette exigence.
L'afficheur
Utiliser une taille de caractère avec des décimales nécessite de faire de l'interpolation lors du tracé des caractères. Qui dit interpolation dit niveaux de couleurs or cet afficheur est monochrome. Le résultat va donc être complètement pourri.

La librairies utilise une bitmap
L'utilisation de bitmap ne se prête pas bien à la modification de la taille des caractères hormis en utilisant des facteurs entiers (et encore cela fini souvent en gros pâtés pas beau). Pour faire des polices de taille variable en continue il faut passer à des polices vectorielles.

Le résultat serait pourri même avec une valeur de 1.5 ? avec une valeur de 1, le résultat est parfait, juste trop petit et idem avec le 2 qui est juste trop gros.

Et comment peut-on passer à des polices vectorielles ?
y'a t'il moyen de s'inspirer du travail de cette personne ?

https://github.com/stanleyhuangyc/MultiLCD/blob/master/MultiLCD/fonts.cpp MultiLCD/MultiLCD/MultiLCD.h at master · stanleyhuangyc/MultiLCD · GitHub

edit, dans la partie GFX, je viens de voir ceci :
glcdfont.c
un extrait :

#ifndef FONT5X7_H
#define FONT5X7_H

#ifdef __AVR__
 #include <avr/io.h>
 #include <avr/pgmspace.h>
#else
 #define PROGMEM
#endif
 
// Standard ASCII 5x7 font

static const unsigned char font[] PROGMEM = {
        0x00, 0x00, 0x00, 0x00, 0x00,
	0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
	0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
	0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
	0x18, 0x3C, 0x7E, 0x3C, 0x18,
	0x1C, 0x57, 0x7D, 0x57, 0x1C,
	0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
	0x00, 0x18, 0x3C, 0x18, 0x00,
	0xFF, 0xE7, 0xC3, 0xE7, 0xFF,

pro_info:
Le résultat serait pourri même avec une valeur de 1.5 ? avec une valeur de 1, le résultat est parfait, juste trop petit et idem avec le 2 qui est juste trop gros.

Le problème du 1,5 c'est que tu ne peux pas allumer un demi point. Donc habituellement on utilise un algorithme d'interpolation qui trace en niveau de gris. Et là tu tombes dans la première impossibilité que j'ai exposée

pro_info:
Et comment peut-on passer à des polices vectorielles ?

Là c'est un gros travail. Il faut créer les polices et tout le programme de tracé.

pro_info:
edit, dans la partie GFX, je viens de voir ceci :

Rien ne t'empêche de créer des polices de taille différente que celle proposée par la librairie. Ce serait sans doute le plus simple. Cela dit c'est aussi un travail assez fastidieux mais possible.

ok donc le plus simple est de demander si quelqu'un connait une autre librairie prenant en charge cet écran.
Cet écran est apparemment basé sur SSD1306 drivers, Est-ce qu'une librairie compatible existe ?
Il me semblait que celle proposé dans mon premier post l'était, c'est peut être le cas, j'ai peut être mal initialisé l'écran...

Tu peux trouver une autre librairie compatible, mais la librairie adafruit est éprouvée et fonctionne bien. Je pense qu'il serait plus sûr de modifier les tables de police et les fonctions associées à l'écriture de texte pour prendre en charge une police un peu plus grande.

Concernant l'autre librairie que tu as essayée, elle supporte effectivement ton afficheur mais il semblerait que d'autres personnes aient rencontrées des problèmes si j'en crois la suite du fil que tu cites car la librairie imposerait une interconnexion particulière. Maintenant cette autre librairie ne fournit pas une police de caractère plus grande. Elle a la même taille que celle de la librairie Adafruit donc il ne faut pas t'attendre à un miracle.

Edit: ne pas perdre de vue que police plus grande = plus de mémoire flash occupée.

fdufnews:
Tu peux trouver une autre librairie compatible, mais la librairie adafruit est éprouvée et fonctionne bien. Je pense qu'il serait plus sûr de modifier les tables de police et les fonctions associées à l'écriture de texte pour prendre en charge une police un peu plus grande.

Je n'ai pas les compétences actuellement pour faire ceci...
Cependant, j'ai trouvé ce site Better Fonts for the SSD1306 qui pourrait peut être répondre à mes besoins, le gihub : py-gaugette/gaugette/fonts at master · guyc/py-gaugette · GitHub

Je vais tenter de bidouiller sans grand conviction, si entre temps quelqu'un a une autre idée n'hésitez surtout pas !
merci pour votre aide

pro_info:
Cependant, j'ai trouvé ce site Better Fonts for the SSD1306 qui pourrait peut être répondre à mes besoins, le gihub : py-gaugette/gaugette/fonts at master · guyc/py-gaugette · GitHub

J'ai regardé vite fait, peut être une bonne piste.