Déclaration de string.

Bonjour,
je veux afficher un message sur un lcd et j'ai regrouper les messages dans des structures.
Sauf que si je déclare de cette façon char Str4[ ] = "arduino"; le lcd bug.

Mais fonctionne très bien comme ça char Str5[8] = "arduino"; et comme ça char Str6[15] = "arduino";

Pourtant d'après le référentiel les 3 sont correct !

Bonjour,

C'est plus qu'étonnant. Donnes ton code.

Bonjour,

voila mes fichiers

main.ino

#include "Controleur.h"
#include "Lcd.h"

#define LED_GREEN 2
#define LED_RED 3

unsigned long oldMillisValue = millis();

bool greenLedState = true;
bool redLedState   = false;

void setup() {

    Serial.begin(9600);
    pinMode(LED_GREEN, OUTPUT);
    pinMode(LED_RED, OUTPUT);

    initLcd();

    initKey();
}

void loop() {
    blinkLed(LED_GREEN, greenLedState);
    if (millis() - oldMillisValue > 300) {
        greenLedState = !greenLedState;
        blinkLed(LED_GREEN, greenLedState);
        oldMillisValue = millis();
    }

    // I am on home page and hold OK
    if (!getMenuLevel() && holdOK()) {
        // Display menu on first line
        upMenuLevel();
        lcdPrint();
    }
}

void blinkLed(byte blinkLed, bool status) {
    if (status)
        digitalWrite(blinkLed, HIGH);
    else
        digitalWrite(blinkLed, LOW);
}

Contoleur.h

#ifndef Controleur_h
#define Controleur_h

void initKey();

bool anyKeyPressed();

bool holdOK();
bool holdUP();

bool pushUP();
bool pushOK();
bool pushDOWN();
bool pushKey();

#endif

Contoleur.cpp

#include "Controleur.h"

#include <Bounce2.h>

#define TOTAL_KEY 3

#define UP_PIN 13
#define OK_PIN 12
#define DOWN_PIN 11

#define UP 0
#define OK 1
#define DOWN 2

#define HOLD_TIME 3000

unsigned long previousMillis = millis();
bool setPreviousMillis       = false;

bool keyHolding = false;

const uint8_t BUTTON[TOTAL_KEY] = {UP_PIN, OK_PIN, DOWN_PIN};

Bounce *key = new Bounce[TOTAL_KEY];

void initKey() {
    for (uint8_t i; i < TOTAL_KEY; i++) {
        key[i].attach(BUTTON[i], INPUT_PULLUP);
        key[i].interval(5);
    }
}

bool anyKeyPressed() {
    bool value = false;
    for (uint8_t i; i < TOTAL_KEY; i++) {
        key[i].update();
        // false because key is pullup and the value is 0 if I push
        if (!key[i].read()) value = true;
    }
    return value;
}

bool holdOK() {
    return holdKey(OK);
}

bool holdUP() {
    return holdKey(UP);
}

bool holdKey(byte pressed) {
    key[pressed].update();

    // Set reference time if I presse key to determine holding time
    if (key[pressed].fell() && !setPreviousMillis) {
        previousMillis    = millis();
        setPreviousMillis = true;
        // return true only one time (not if I continue to press same key)
    } else if (!keyHolding && !key[pressed].read()) {
        if (millis() - previousMillis > HOLD_TIME) {
            keyHolding = true;
        }
        // If I continue to hold same key return false
    } else if (keyHolding) {
        // reste to false value only if i relasing key
        if (key[pressed].rose()) {
            setPreviousMillis = false;
            keyHolding        = false;
        } else
            return false;
    }
    return keyHolding;
}

bool pushKey(byte pressed) {
    key[pressed].update();
    if (key[pressed].fell())
        return true;
    else
        return false;
}

bool pushUP() {
    return pushKey(UP);
}

bool pushOK() {
    return pushKey(OK);
}

bool pushDOWN() {
    return pushKey(DOWN);
}

Lcd.h

/*
    SDA to pin A4
    SCL to pin A5
*/

#ifndef Lcd_h
#define Lcd_h

#include <stdint.h>

void initLcd();

uint8_t getMenuLevel();
void upMenuLevel();
void downMenuLevel();

uint8_t getMenuItemLevel();
void nextItem();
void prevItem();

void creatCharset();
void lcdPrint();
void printHomePage();
void printMainMenu();
void printSetUp();

#endif

Lcd.cpp

#include "Lcd.h"

#include "Controleur.h"
#include "DisplayItem.h"
#include "Temperature.h"

#include <LiquidCrystal_I2C.h>

#define LCD_ADRESSE 0x27
#define LCD_COLUMN 16
#define LCD_LINE 2

#define UP 1
#define DOWN 2
#define OK 3
#define CANCEL 4
#define SELECTED 5

static uint8_t _menuLevel;
static uint8_t _menuItemLevel;

static LiquidCrystal_I2C lcd(LCD_ADRESSE, LCD_COLUMN, LCD_LINE);

void initLcd() {
    lcd.init();
    creatCharset();
    lcd.backlight();
    lcd.home();
    lcd.printstr("INIT OK");
    delay(1000);
    _menuLevel     = 0;
    _menuItemLevel = 0;
    lcdPrint();
}

uint8_t getMenuLevel() {
    return _menuLevel;
}

uint8_t getMenuItemLevel() {
    return _menuItemLevel;
}

void upMenuLevel() {
    _menuLevel++;
}
void downMenuLevel() {
    _menuLevel--;
}

void nextItem() {
    _menuItemLevel++;
}
void prevItem() {
    _menuItemLevel--;
}

void creatCharset() {
    lcd.createChar(1, charter.up);
    lcd.createChar(2, charter.down);
    lcd.createChar(3, charter.ok);
    lcd.createChar(4, charter.cancel);
    lcd.createChar(5, charter.selected);
}

void lcdPrint() {
    switch (_menuLevel) {
        case 1:
            printMainMenu();
            break;
        case 2:
            printSetUp();
            break;
        default:
            printHomePage();
            break;
    }
}

void printHomePage() {
    lcd.clear();
    lcd.home();
    lcd.printstr("IN = ");
    lcd.print(getTemperature());
    lcd.setCursor(0, 1);
    lcd.printstr("Limit = ");
    lcd.print(secureTemperatureLimit);
}

void printMainMenu() {
    switch (_menuItemLevel) {
        case 1: {
            lcd.clear();
            lcd.home();
            lcd.write(SELECTED);
            lcd.printstr(item.setTemp);
            lcd.setCursor(0, 1);
            lcd.printstr(item.setBacklight);
        } break;

        case 2: {
            lcd.clear();
            lcd.home();
            lcd.printstr(item.setTemp);
            lcd.setCursor(0, 1);
            lcd.write(SELECTED);
            lcd.printstr(item.setBacklight);
        } break;

        default: {
            Serial.print("Item menu =");
            Serial.println(item.menu);
            lcd.clear();
            lcd.home();
            lcd.print(item.menu);
            lcd.setCursor(0, 1);
            lcd.write(SELECTED);
            lcd.print(item.setTemp);
        } break;
    }
}

void printSetUp() {
    switch (_menuItemLevel) {
        case 1: {
            lcd.clear();
            lcd.home();
        } break;

        default:
            break;
    }
}

Puis le fameux DisplayItem.h

#ifndef DISPLAYITEM_H
#define DISPLAYITEM_H

struct menuItemLabels {
    const char menu[]         = "menu";
    const char setTemp[]      = "Set Temperature";
    const char setBacklight[] = "Set Backlight";
    const char temp[]         = "Temperature";
    const char backlight[]    = "Backlight";
} item;

struct specialChar {
    uint8_t up[8] = {
        0b00100, 0b01110, 0b00100, 0b00100, 0b00100, 0b00000, 0b00000, 0b00000};
    uint8_t down[8] = {
        0b00000, 0b00000, 0b00000, 0b00100, 0b00100, 0b00100, 0b01110, 0b00100};
    uint8_t ok[8] = {
        0b00000, 0b00010, 0b00010, 0b00010, 0b01010, 0b11110, 0b01000, 0b00000};
    uint8_t cancel[8] = {
        0b00000, 0b00000, 0b10001, 0b01010, 0b00100, 0b01010, 0b10001, 0b00000};
    uint8_t selected[8] = {
        0b00000, 0b00000, 0b00000, 0b00100, 0b11110, 0b00100, 0b00000, 0b00000};
} charter;

#endif

Comme quoi le problème était très mal posé.

Cela m'étonnerait que ton code fasse "bugger" ton LCD. Personnellement j'obtiens carrément des erreurs de compilation.

initializer-string for array of chars is too long [-fpermissive]
     const char menu[]         = "menu";

Si tu ne veux pas donner de taille à tes chaînes passe par des pointeurs :

struct menuItemLabels {
    const char *menu         = "menu";
    const char *setTemp      = "Set Temperature";
    const char *setBacklight = "Set Backlight";
    const char *temp         = "Temperature";
    const char *backlight    = "Backlight";
} item;

Ceci est préférable :

Dans DisplayItem.h :

struct menuItemLabels {
    const char *menu;
    const char *setTemp;
    const char *setBacklight;
    const char *temp;
    const char *backlight;
};

Dans lcd.cpp

struct menuItemLabels item =
{
    "menu", "Set Temperature", "Set Backlight", "Temperature", "Backlight"
};

Il est déconseillé de déclarer des variables dans un .h, cela peut provoquer des doubles définitions si tu inclus ton .h dans plusieurs .cpp ou .ino

Idem pour ta structure specialChar.
Définit ta structure dans le .h, puis déclare ta variable charter dans un .cpp

@+

Merci :slight_smile:

J'ai laissé exprès l'erreur, mais après j'avoue que je ne me souviens pas d'avoir eu une erreur de compilation. J'avais simplement des bugs d'affichage.

J'ai bien compris que cela venait d'un problème que la variable était mal déclarer, mais je ne comprends toujours pas la raison !

Le message d'erreur dit que ma chaîne de caractère est trop longue. Pourtant menu devrait s'adapter à la taille de ma valeur? Puis la déclaration même si elle est dans le .h elle respecte ce qui est écrit dans le référentiel !

Merci pour le conseil sur les déclarations aussi :slight_smile:

En C/C++ une structure doit avoir une taille fixe connue par le compilateur, c'est pour ça qu'un champ ne peut pas avoir de longueur variable.
La solution est d'utiliser des pointeurs comme le préconise hbachetti.

Oui je me souviens que j'avais ouvert le même sujet, mais je n’avais pas compris clairement le principe (même si ton message m'avait aidé).
Du coup, j'ai fait des tests pour comprendre, et je n’ai pas fait le lien que cela pouvait venir de la structure hier

Là je crois que c'est bien rentrer

Merci