Utilisation de byte et const byte avec l'erreur argument de type incompatible

Bonjour tout le monde,
Je rencontre un soucis dans l'utilisation d'une bibliothèque pour un écran ILI9341 que je veux adapter. A l'origine elle était prévue pour un Arduino et je veux l'utiliser avec un ESP32.

Il s'agit d'un fonction qui affiche des caractères à partir d'une fonte.
la fonte est définit comme ça :

`const byte SmallFont[] PROGMEM = {
  7, // ymax
  1, // descender
  ' ', //first char
  3, 0x00,0x00,0x00,                           // space
  1, 0xFA,                                     // !
  3, 0xC0,0x00,0xC0,                           // "
  5, 0x28,0xFE,0x28,0xFE,0x28,                 // #
  5, 0x24,0x52,0xFF,0x4A,0x24,                 // dollar
  6, 0x62,0x64,0x08,0x10,0x26,0x46,            // %
    ****

Une des fonctions de la librairie qui utilise "Font"

void DrawChar(uint8_t c, byte Font, uint16_t color) {
  word n, j, px;
  byte ymax, desc;
  unsigned long b,d;
  ymax = pgm_read_byte_near(Font);
  Font++;

Dans le programme elle est utilisée :
DrawChar(*c, SmallFont, color);

Dans le programme j'ai l'erreur
l'argument de type "const byte *" est incompatible avec le paramètre de type "byte"C/C++(167

Si je remplace les "byte Font" par "const byte Font" toutes mes erreurs sur l'incompatibilité de l'argument disparaisse mais j'ai une erreur sur la ligne "Font++" ce qui est compréhensible (on ne peux pas modifier une constante).

D'avance merci pour votre aide.

Plus d'infos:
J'utilise platformio sous w10.
Au cours de ma carrière j'ai développé beaucoup de programme en assembleur sur des microprocesseurs MOTOROLA et des mini style PDP11, MITRA15 ou SOLAR16-65.
Je suis débutant en C et C++ et autres, même si j'ai développé plusieurs "bricolage" avec des arduino.
Il s'agit de la librairie SimpleILI9341 adapté de la librairie TFT_ILI9341 elle même adapté de Adafruit_GFX
je suis un peu obligé d'utiliser cette librairie pour des soucis d'encombrement et de partage de bus SPI et autres tracasseries.

Dans un ESP32, on n'utilise pas PROGMEM. Tu peux stocker des valeurs dans la flash. La bibliothèque Preferences fait cela.

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/preferences.html

Un tuto ici :

Non pas besoin de Preferences dans ce cas là (on ne veut pas modifier la font plus tard)

Dans un ESP32 les const vont directement en flash, dans un segment non modifiable et comme la flash est mappée dans l'espace d'adressage il n'y a pas à s'embêter avec pgm_read_byte_near(), on peut directement lire dans le tableau

const byte SmallFont[] = {
  7, // ymax
  1, // descender
  ' ', //first char
  3, 0x00,0x00,0x00,                           // space
  1, 0xFA,                                     // !
  3, 0xC0,0x00,0xC0,                           // "
  5, 0x28,0xFE,0x28,0xFE,0x28,                 // #
  5, 0x24,0x52,0xFF,0x4A,0x24,                 // dollar
...
};

et la fonction devient

void DrawChar(uint8_t c, byte* Font, uint16_t color) { // attention * Font maintenant
  word n, j, px;
  byte ymax, desc;
  unsigned long b,d;
  ymax = *Font; // <=== au lieu de pgm_read_byte_near, on utilise simplement *
  Font++;
...

Merci pour vos conseils.
J'aimerais mieux comprendre les mécanismes en C

J'ai déclaré un tableau (SmallFont) de byte, ce tableau est une constante, donc non modifiable.

La fct DrawChar attends en 2ème paramètre un byte.

1er question : dans la ligne DrawChar(*c, SmallFont, color), que représente SmallFont, un pointeur ou tout le tableau (j'image un pointeur).

Est-ce que je dois lire mon erreur
l'argument de type "const byte " est incompatible avec le paramètre de type "byte"C/C++(167
comme
Dans la fct DrawChar on attend un byte et j'envoi un pointeur?
d'où ta modification byte
Font et ymax = *Font

Si j'applique tes modifications, j'avance mais j'ai un autre souci, à savoir l'erreur:
l'argument de type "const byte *" est incompatible avec le paramètre de type "byte *"C/C++(167)

Sur SmallFont dans le programme sur la ligne :
DrawChar(*c, SmallFont, color);
Et là il indique que const byte * est incompatible avec byte *

en fait pas vraiment si vous aviez

et que la fonction était appelée par

le second argument n'était pas un byte mais l'adresse en mémoire flash du tableau.

pouvez vous donner un lien sur cette bibliothèque que vous voulez modifier ?


quand dans une fonction le paramètre de type pointeur est de type non const ça veut dire que la fonction se réserve le droit de modifier le contenu pointé. Vous ne pouvez donc pas passer un contenu non modifiable.

Si la fonction ne modifie pas le contenu pointé, alors la fonction devrait avoir le mot clé const dans sa signature.

si vous avez void fonction(char * pointeur) alors vous n'avez pas le droit d'appeler fonction("coucou"); car "coucou" est de type const char *. Il faut donc définir la fonction comme void fonction(const char * pointeur) et là le compilateur sait que la fonction ne modifie pas le contenu pointé et on peut passer sans souci soit un const char * ou un char *.

en C ou C++ le nom d'un tableau est aussi un pointeur sur le premier élément du tableau

si vous avez byte tableau[10]; alors tableau est de type byte *, un pointeur sur un octet et sa valeur est l'adresse du premier élément du tableau (on ne connait plus sa taille une fois que l'on passe par le pointeur)

merci pour votre réponse,
voici l'adresse
https://content.instructables.com/F80/OBXC/JJT6TALL/F80OBXCJJT6TALL.zip
ou je met le fichier en pièce jointe
SimpleILI9341.zip (223,5 Ko)

J'ai mis en commentaire la ligne
//#include <avr/pgmspace.h>
qui est spécifique à l'Arduino si j'ai bien compris

En complément
j'ai également éliminer tout traitement qui accédaient aux registres de l'Arduino pour ne travailler qu'avec la librairie spi

Cette librairie compile avec un arduino sous ArduinoIDE et me pose les mêmes soucis sous PlatFormio

dans le fichier joint je vois

void DrawChar(uint8_t c, word Font, uint16_t color);
void DrawString(char * s, word Font, uint16_t color);

➜ ce n'est pas ce que vous annonciez

un word, c'est 2 octets, ce qui suffit sur un petit arduino pour donner l'adresse mémoire flash (c'est un pointeur converti en nombre)

donc partout ou vous avez word et qui correspond à une adresse PROGMEM, mettez un uint8_t * à la place et partout où vous aviez l'accès au contenu par pgm_read_byte_near(toto) vous remplacez cela par un déréférencement ➜ *toto

spécifique aux AVR comme la UNO, MEGA, Nano originelle par exemple. Il y a des Arduinos à base d'autre processeurs où cela ne serait pas utile non plus

Merci pour vos infos qui me sont précieux.
Effectivement excuser de l'erreur, je me suis mélangé dans tous mes essais.
Je fais les modifications et je reviens vers vous

Encore merci
PS: un word sur ESP32 est-ce 2 octets ou 4?

J'avance.
J'ai fait vos modifications qui ont l'air de satisfaire le compilateur.
J'ai le même type d'erreur sur

static void swap(uint16_t *a, uint16_t *b) {
  uint16_t c;
  c = *a;
  *a = *b;
  *b = c;
}
void DrawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
  int16_t a, b, y, last;

  // Sort coordinates by Y order (y2 >= y1 >= y0)
  if (y0 > y1) {
    swap(y0, y1); swap(x0, x1);
  }

Erreur sur les variable y0, y1, x0, x1
type "uint16_t" est incompatible avec le paramètre de type "uint16_t *"

Que je corrige avec

void DrawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
  int16_t a, b, y, last;

  // Sort coordinates by Y order (y2 >= y1 >= y0)
  if (y0 > y1) {
    swap(&y0, &y1); swap(&x0, &x1);
  }

Est-ce correcte?

word n'est pas un type standard de C++ mais il est déclaré par arduino dans Arduino.h

comme un alias pour unsigned int

sur AVR c'est 16 bits, sur un arduino 32 bits c'est 32.

et il suffit de compiler cela pour savoir

void setup() {
  Serial.begin(115200);
  Serial.println(sizeof(word));
}

void loop() {}

le code d'origine serait faux s'il est écrit comme cela. La fonction swap attend des pointeurs donc DrawTriangle n'appelle pas correctement swap.

vous êtes sûr de vous que c'est le code d'origine? je ne le vois pas dans votre zip

sinon oui, votre correction est juste, vous passez bien les pointeurs;

Sauf erreur de ma part
dans SimpleILI9341.cpp ligne 1116 et suivante

J'ai également mis
uint16_t a, b, y, last;
au lieu de
int16_t a, b, y, last;

J'ai l'impression que l'ide Arduino est plus permissif que PIO

ah oui j'avais cherché swap que dans le .h

oui il faut une cohérence des types. utilisez des unsigned si vous êtes sûr que les coordonnées ne seront jamais négatives

Ok, Merci pour tous vos conseils.
Je risque de revenir vers vous dans quelques jours.

Bonjour, me voici de retour.
Devant la difficulté pour adapter cette librairie j'ai changé mon fusil d'épaule.
Je suis partie sur une librairie, TFT_eSPI de Bodmer, qui fonctionne sur l'ESP32.
Les exemples fournis avec la librairie fonctionnent.
Je pense faire une interface entre les fonctions utilisées dans le programme et la librairie TFT_eSPI

J'ai adapté certaines fonctions avec succès mais je rencontre le soucis suivant:


je ne comprend pas l'avertissement en ligne 73.
Pour tester j'ai recopier dans les lignes 74 à 76 le contenue de la fonction et je n'ai pas d'avertissement.

Pouvez-vous m'aider à comprendre cette avertissement.

D'avance merci.

Ne postez pas d'image d'un texte... c'est pénible.

votre fonction DrawCharColumn() est mal écrite : elle attend un char * là où vous avez mis "Test setup" qui est un const char *

Comme votre fonction ne modifie pas le texte, vous devez mettre const char * pour ce paramètre (pointeur vers du texte constant au sein de la fonction)

void DrawCharColumn(uint16_t x0, uint16_t y0, const char * str, uint16_t color) {
  ...

Merci pour votre réponse.

Pour l'image j'ai pensé que c'était le plus simple pour afficher l'erreur en même temps.

J'ai apporté les modifs suivantes:

void DrawCharColumn(uint16_t x0, uint16_t y0,const char* str, uint16_t color) {
  int y;
  //char* c;
  //c = str;
  tft.setCursor(x0, y0);
  tft.setTextColor(color);  tft.setTextSize(3);
  tft.println(str);
}

Donc l'avertissement concernait le texte "test setup" et pas la couleur.