IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

ESP32 & ILI1941 : affichage N° Bouton


Sujet :

Arduino

  1. #21
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Citation Envoyé par edgarjacobs Voir le message
    Je parcours ton code pour essayer de t'aider pour le bargraphe, et je rencontre ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Calcul_vBat(){
        int cmpt = 8;
        int vBatOld = 0 ; 
        do {
           cmpt--;
           valeurBrute  = analogRead(vbatPin); // tension échantillonnée brute
           vBatOld = valeurBrute;
        } while((abs(valeurBrute-vBatOld) > DELTA) && (cmpt > 0));
    Le résultat de abs(valeurBrute-vBatOld) > DELTA (qui vaut 32) sera toujours faux puisque valeurBrute==vBatOld, et donc le do....while() ne sert à rien.
    Bonjour , edgarjacobs

    j'ai corrigé effectivement ma fonction Calcul_VBat pour une meilleure stabilité de la mesure
    toujours partant pour mon bargrah ?

  2. #22
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 646
    Points : 1 643
    Points
    1 643
    Par défaut
    Hello,

    Je vais tenter de t'aider. Poste ton dernier code stp.

    Une question: quelle est la borne supérieure pour le bargraph ? Car il faut pouvoir le normer, or 147%, c'est assez particuler.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  3. #23
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Salut edgarjacobs

    merci par avance pour le coup de main
    voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
     
    // E_V20240611a //
     
     
    /************************************************************
              ESP32 WROOM LOW POWER DEVKIT
              uPesy
                       ------------------
                       |1             32| GPIO23
       T_IRQ   GPIO36  |2             31| GPIO22
       T_OUT   GPIO39  |3             30| GPIO1
               GPIO34  |4             29| GPIO3
                   NC  |5             28| GPIO21 LED
       T_DIN   GPIO32  |6             27| GPIO19   
       T_CS    GPI033  |7             26| GPIO18    
       T_CLK   GPIO25  |8             25| GPIO5 
               GPIO26  |9             24| GPIO17
               GPIO27  |10            23| GPIO16 SDO(MISO)
         SCK   GPIO14  |11            22| GPIO4  TTP223
       RESET   GPIO12  |12            21| GPIO0
     SDI(MOSI) GPIO13  |13            20| GPIO2  D/C
                       |14            19| GPIO15 CS
                       |15            18| 3V3 VCC
                  GND  |16     |----| 17| GND
                       \-------|    |---/
                               |----| 
    **************************************************************/
     
    #include <SPIFFS.h>
    #include <SPI.h>
    #include <TFT_eSPI.h>
    #include <XPT2046_Touchscreen.h> // https : //github. com/PaulStoffregen/XPT2046_Touchscreen
    #include <esp_now.h>
    #include <WiFi.h>
    #include <EEPROM.h>
     
    TFT_eSPI tft = TFT_eSPI();
     
    // Touchscreen pins
    #define XPT2046_IRQ 36   // T_IRQ
    #define XPT2046_MOSI 32  // T_DIN
    #define XPT2046_MISO 39  // T_OUT
    #define XPT2046_CLK 25   // T_CLK
    #define XPT2046_CS 33    // T_CS
     
    #define FM9 &FreeMono9pt7b
     
     
    #define DELTA 32
    // Bargraff
    #define BACKCOLOR 0x18E3
    //#define BARCOLOR 0x0620
    #define BARCOLOR 0x03EF
     
    #define SCALECOLOR 0xFFFF
    // Interruption TPP223
    const gpio_num_t vbatPin   = GPIO_NUM_35;
     
    SPIClass touchscreenSPI = SPIClass(VSPI);
    XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
     
    #define SCREEN_WIDTH 320
    #define SCREEN_HEIGHT 240
    #define FONT_SIZE 2
     
    // definition des boutons
    #define BUTTON_WIDTH  80
    #define BUTTON_HEIGHT 60
    #define BUTTON_MARGIN 10
     
    // Structure pour représenter un bouton *************
    struct Button {
      int value;
      int x, y;
      bool state;
    };
     
    RTC_DATA_ATTR int bootCount = 0;
    RTC_DATA_ATTR Button buttons[9]; // 9 boutons
    //RTC_DATA_ATTR float vBat = 0;
    RTC_DATA_ATTR int progress = 0;
    float vBat = 0;
     
     
    /*****************************************************************/
     
    /*Imprimer les informations de l'écran tactile concernant X, Y et la pression (Z) sur le moniteur série*/
    void printTouchToSerial(int touchX, int touchY, int touchZ) {
      Serial.print("X = ");
      Serial.print(touchX);
      Serial.print(" | Y = ");
      Serial.print(touchY);
      Serial.print(" | Pression = ");
      Serial.print(touchZ);
      Serial.println();
    }
    /*****************************************************************/
     
    /*** Structure Fichier Config.txt ********************************/
    const size_t tailleMaxNom = 16;     // y compris le caractère nul final
    struct ClientPC {
      char nom[tailleMaxNom];            // le nom du client PC
      uint8_t adresse[6];               // les 6 octets de son adresse
    };
    const size_t nbMaxClients = 20;     // nombre maximum de clients
    ClientPC clients[nbMaxClients];
    size_t nbClientsPC = 0;            // le nombre de clients lu dans le fichier de config
     
    /*****************************************************************/
     
    // ***** Structure du récepteur *************************************
    struct struct_message {
      char a[32]; // ex PC1
      bool b;     // Etat = 0 ou 1
    };
    // Créer une struct_message appelée myData
    struct_message myData;
     
    //........... Etat enoi ********************************************
    esp_now_peer_info_t peerInfo;
     
    void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
      Serial.print("\r\nÉtat de l'envoi du dernier paquet:\t");
      Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Succès" : "Échec");
    }
    //*********************************************************************
     
    // Init ESP Now with fallback
    void InitESPNow() {
      WiFi.disconnect();
      if (esp_now_init() == ESP_OK) {
        Serial.println("ESPNow Init Succès");
      }
      else {
        Serial.println("Échec de l'initialisation de ESPNow");
        // Retry InitESPNow, add a counte and then restart?
        // InitESPNow();
        // or Simply Restart
        ESP.restart();
      }
    }
     
    unsigned long currentTime=0;
    unsigned long previousTime=0;
    int touchX, touchY, touchZ , i;
    int LastPercent = 0;
    int valeurBrute ;
    int vBatOld = 0 ; 
    int k;
     
    //************************************************
    // SETUP
    //************************************************
    void setup()
    {
      Serial.begin(115200);
      pinMode(35, INPUT);
      Calcul_vBat();
     
      //Incrémente le numéro de démarrage et l'imprime à chaque redémarrage
      ++bootCount;
      Serial.println("Boot number: " + String(bootCount));
     
      // Lire le fichier Config.txt 
      if (!SPIFFS.begin(true)) {
        Serial.println("Une erreur s'est produite lors du montage de SPIFFS");
        return;
      }
      File fichierConfig = SPIFFS.open("/config.txt", FILE_READ);
      if (!fichierConfig) {
        Serial.println("Impossible d'ouvrir le fichier en lecture");
        return;
      }
      char bufferLigne[100]; // Buffer pour stocker chaque ligne
      char format[64]; // pour bâtir dynamiquement le format en tenant compte de la longueur max du nom (reco de Kernighan et Pike dans "The Practice of Programming")
      snprintf(format, sizeof format, "%%%ds %%hhx %%hhx %%hhx %%hhx %%hhx %%hhx", tailleMaxNom - 1); // lire une chaine de taille max tailleMaxNom - 1 suivie de 6 octets en hexa
      nbClientsPC = 0;
      while (fichierConfig.available() && nbClientsPC < nbMaxClients) {   // tant qu'on peut lire quelque chose et qu'on a de la place pour stocker
        memset(bufferLigne, '\0', sizeof bufferLigne); // Effacer le buffer
        fichierConfig.readBytesUntil('\n', bufferLigne, sizeof bufferLigne); // Lire la ligne dans le buffer
        memset(clients[nbClientsPC].nom, '\0', sizeof clients[nbClientsPC].nom); // on efface le nom pour être tranquille
        int nbChampsLus = sscanf(bufferLigne, format,
                                 clients[nbClientsPC].nom,
                                 &clients[nbClientsPC].adresse[0], &clients[nbClientsPC].adresse[1],
                                 &clients[nbClientsPC].adresse[2], &clients[nbClientsPC].adresse[3],
                                 &clients[nbClientsPC].adresse[4], &clients[nbClientsPC].adresse[5]);
     
        if (nbChampsLus == 7) {
          // la lecture des 7 champs (le nom et 8 octets sous forme hexadécimale) s'est bien passée
          nbClientsPC++;
        } else {
          // on arrête de lire là
          break;
        }
      }
      fichierConfig.close();
     
      // Affichage des adresses lues depuis le fichier
      for (size_t i = 0; i < nbClientsPC; i++) {
        Serial.printf("%3zu %-*s : ", i + 1, tailleMaxNom - 1, clients[i].nom); // l'index sur 3 caractères, le nom sur tailleMaxNom - 1 cadrée à gauche
        for (int j = 0; j < 6; j++) Serial.printf("0x%02X ", clients[i].adresse[j]);
        Serial.println();
      }
     
      // Set device as a Wi-Fi Station
      WiFi.mode(WIFI_STA);
     
      // Init ESP-NOW
      InitESPNow();
      if (esp_now_init() != ESP_OK) {
        Serial.println("Erreur d'initialisation de l'ESP-NOW");
      }
      esp_now_register_send_cb(OnDataSent);
      for (size_t i = 0; i < nbClientsPC; i++) {   // Enregistrer les  devices
        peerInfo.channel = 0;
        peerInfo.encrypt = false;
        memcpy(peerInfo.peer_addr, clients[i].adresse, 6);
        if (esp_now_add_peer(&peerInfo) != ESP_OK) {
          Serial.printf("Échec de l'ajout de %s\n", clients[i].nom);
          return;
        }
      }
     
      // Démarrer le SPI pour l'écran tactile et initialiser l'écran tactile
      touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
      touchscreen.begin(touchscreenSPI);
      touchscreen.setRotation(3);
      tft.init();
      tft.setRotation(1);
      tft.fillScreen(TFT_BLACK);
     
      // Graph Batterie
      Affich_vBat(); // Afficage du niveau Batterie
     
      // Initialisation des positions des boutons
      int buttonX = 20;
      int buttonY = 20;
      for ( int i = 0; i < 9; ++i)
      {
        buttons[i].x = buttonX;
        buttons[i].y = buttonY;
        buttons[i].value=i;
     
        // Affichage des boutons
        drawButton(&buttons[i]);
        buttonX += BUTTON_WIDTH + BUTTON_MARGIN;
        if (buttonX + BUTTON_WIDTH > tft.width()) {
          buttonX = 20;
          buttonY += BUTTON_HEIGHT + BUTTON_MARGIN;
        }
      }
     
      //Imprimer la raison du réveil de l'ESP32
      //print_wakeup_reason();
      esp_sleep_enable_ext0_wakeup(GPIO_NUM_4,1); //1 = High, 0 = Low
     
    }
     
    //************************************************
    // LOOP
    //************************************************
    void loop()
    {
        currentTime=millis();
    	  // Vérifie si l'écran tactile a été touché et imprime les informations X, Y et la pression (Z) sur l'écran TFT et le moniteur série.
    	if (touchscreen.tirqTouched() && touchscreen.touched())
    	{
    		previousTime=currentTime;  
    		// Obtenir des points pour l'écran tactile
    		TS_Point p = touchscreen.getPoint();
    		// Calibrer les points de l'écran tactile avec la fonction de carte à la bonne largeur et à la bonne hauteur
    		touchX = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
    		touchY = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
    		touchZ = p.z;
    		printTouchToSerial(touchX, touchY, touchZ);
     
    		for (int i = 0; i < 9; ++i)
    		{
    		  if (touchX >= buttons[i].x && touchX <= buttons[i].x + BUTTON_WIDTH &&
    			  touchY >= buttons[i].y && touchY <= buttons[i].y + BUTTON_HEIGHT)
    		  {
    				// Si un bouton est touché, inverse son état et met à jour l'affichage
            Serial.println();
    				if( i < 8 )
    				{
    					buttons[i].state = !buttons[i].state;
    					drawButton(&buttons[i]);
     
    					/*******************************************************/
    					if (buttons[i].state == 1) {
    					  Serial.print("Btn "); Serial.print(i + 1); Serial.println(" enfoncé");
    					  snprintf(myData.a, sizeof myData.a, "PC%02d=> ON", i + 1);
    					  myData.b =  true;
    					  esp_err_t result = esp_now_send(clients[i].adresse, (uint8_t *)&myData, sizeof(myData));
    					  if (result == ESP_OK) {
    						Serial.print("PC"); Serial.print(i + 1); Serial.println(" Envoyé avec succès");
    						//etat[i] = 1;
    					  } else {
    						Serial.print("Erreur d'envoi des données PC"); Serial.print(i + 1);
    					  }
    					}
    					/*******************************************************/ 
    					if (buttons[i].state == 0)
    					{
    					  Serial.print("Btn "); Serial.print(i + 1); Serial.println(" relaché");
    					  snprintf(myData.a, sizeof myData.a, "PC%02d=> OFF", i + 1);
    					  myData.b =  false;
    					  esp_err_t result = esp_now_send(clients[i].adresse, (uint8_t *)&myData, sizeof(myData));
    					  if (result == ESP_OK) {
    						Serial.print("PC"); Serial.print(i + 1); Serial.println(" Envoyé avec succès");
    						//etat[i] = 0;
    					  } else {
    						Serial.print("Erreur d'envoi des données PC"); Serial.print(i + 1);
    					  }
    					}
    				} 	
    				if (i ==8)
    				{   
    			        i = 0;
    					for (i = 0; i < 8; ++i)
    					{
                            Serial.println();
    						if (buttons[i].state == 1)
    						{
    						    buttons[i].state = 0;
    							   drawButton(&buttons[i]); 
                      Serial.print("Btn "); Serial.print(i + 1); Serial.println(" relaché");
    					        snprintf(myData.a, sizeof myData.a, "PC%02d=> OFF", i + 1);
    					        myData.b =  false;
    					        esp_err_t result = esp_now_send(clients[i].adresse, (uint8_t *)&myData, sizeof(myData));
    					        if (result == ESP_OK)
    							    {
    						       Serial.print("PC"); Serial.print(i + 1); Serial.println(" Envoyé avec succès");
    						       //etat[i] = 0;
    					        } else {
    						       Serial.print("Erreur d'envoi des données PC"); Serial.print(i + 1);
    					        }					
    						}	
    					}
    				}	
    		    }
    		  //break;
    		  delay(200);
    		}
    	}
     
    	if((currentTime-previousTime)>10000){  
    	  //Go to sleep now
          Serial.println("Je vais m'endormir maintenant");
            delay(1000);
            esp_deep_sleep_start();  
    	}
     
    }
     
     
    void drawButton(struct Button *btn) {
        tft.setTextFont(2);
        tft.setTextSize(3);
        tft.setCursor(btn->x+30, btn->y+7);
        if(btn->value!=8) {
            uint16_t color = btn->state ? TFT_RED : TFT_GREEN;
            tft.fillRoundRect(btn->x, btn->y, BUTTON_WIDTH, BUTTON_HEIGHT, 10, color);
            tft.drawRoundRect(btn->x, btn->y, BUTTON_WIDTH, BUTTON_HEIGHT, 10, TFT_YELLOW);
            tft.drawCircle(btn->x+40, btn->y+30,28,TFT_BLACK);
            tft.setTextColor(TFT_BLACK, color);
            tft.print(btn->value+1);
        }
        else {
           tft.fillRoundRect(btn->x, btn->y, BUTTON_WIDTH, BUTTON_HEIGHT, 10, TFT_CYAN);
           tft.drawRoundRect(btn->x, btn->y, BUTTON_WIDTH, BUTTON_HEIGHT, 10, TFT_YELLOW);
           tft.setTextColor(TFT_BLACK, TFT_CYAN);
           tft.print("#");
        }
    }
     
    /*******************************************************/
    void print_wakeup_reason(){
      esp_sleep_wakeup_cause_t wakeup_reason;
      wakeup_reason = esp_sleep_get_wakeup_cause();
      switch(wakeup_reason)
      {
        case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Réveil causé par un signal externe utilisant RTC_IO"); break;
        case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Réveil provoqué par un signal externe utilisant RTC_CNTL"); break;
        case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Réveil provoqué par la minuterie"); break;
        case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
        case ESP_SLEEP_WAKEUP_ULP : Serial.println("Réveil causé par le programme ULP"); break;
        default : Serial.printf("Le réveil n'a pas été causé par un sommeil profond : %d\n",wakeup_reason); break;
      }
    }
     
    /*******************************************************/
     
    void Calcul_vBat() {
       for(int cmpt = 8; cmpt > 0; --cmpt) {
          vBatOld = valeurBrute;    // vBatOld peut (doit ?) être une variable locale 
          valeurBrute = analogRead(vbatPin);
          delay(100);
          if((abs(valeurBrute-vBatOld) <= DELTA)&& (cmpt > 3)) break;
       }
       vBat = 1.40*(valeurBrute/4095.0)*3.3; // carte uPesy Vbat Brute = 3804 pour 100%
       progress = ((vBat-3.2)*100);
    }
     
    /*******************************************************/   
    void Affich_vBat() 
    {
      // Niveau batterie ************************************************
        Serial.print(" Valeur Brute = "); Serial.println(valeurBrute);
        Serial.print(" Vbat = "); Serial.print(vBat,2);Serial.println(" Volts"); 
        Serial.print(" % = "); Serial.println(progress);
        tft.setCursor(290,1);
        tft.setTextFont(1);
        tft.setTextSize(1);
        tft.setTextColor(TFT_YELLOW, TFT_BLACK);
        tft.print(progress);tft.println("%");
     
        tft.drawRoundRect(300, 20, 10, 200,10,TFT_YELLOW);
    }
    à la ligne 418
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      tft.drawRoundRect(300, 20, 10, 200,10,TFT_YELLOW);
    j'ai dessiné un rectangle à partir du pixel 300,20 sur une longueur ( vers le bas !) de 200 et largeur de 10
    ce bargraph doit pouvoir afficher 0-100% de la variable (progress)
    je vais donc tronquer cette mesure à 100% max
    en effet avec la particularité de cette carte, la valeur indique 141% lorsque je suis alimenté via l'USB

  4. #24
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 646
    Points : 1 643
    Points
    1 643
    Par défaut
    Re,-

    Dans un premier temps, ne sachant pas tester et n'ayant pas l'habitude des rectangles à coins arrondis, j'ai écrit un code qui utilise un rectangle classique (*). Mais il est probable, s'il fonctionne, qu'il fonctionnera également avec des coins arrondis (je te conseille des arrondis de 5 pas plus, la largeur du rectangle étant de 10). Teste et dis-moi ce que ça donne. Change évidement les couleurs à ta meilleure convenance.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    void DisplayBarGraph(void);
     
    void Affich_vBat(void) {
        Serial.print(" Valeur Brute = "); Serial.println(valeurBrute);
        Serial.print(" Vbat = "); Serial.print(vBat,2);Serial.println(" Volts");
        Serial.print(" % = "); Serial.println(progress);
     
        DisplayBarGraph();
    }
     
    #define BAR_BACKGROUND_COLOR    0xabcd
    #define BAR_FOREGROUND_COLOR    0xdcba
     
    void DisplayBarGraph(void) {
        tft.setCursor(290,1);
        tft.setTextFont(1);
        tft.setTextSize(1);
        tft.setTextColor(TFT_YELLOW, TFT_BLACK);
        tft.print(progress); tft.println("%");
        tft.drawRect(300, 20, 10, 200, TFT_YELLOW);
        tft.fillRect(300, 20, 10, 200, BAR_BACKGROUND_COLOR);
        int h=200*(progress/100.);      // 100% pour le maximum                         
        int y_bar=20+200-h;
        tft.fillRect(300, y_bar, 10, h, BAR_FOREGROUND_COLOR);
    }
    (*) et pour ma facilité de visualisation de la chose.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  5. #25
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Salut edgarjacobs

    Un grand merci pour le coup de main qui a l'air de fonctionner super
    j'ai fait 2 supports distincts

    Image 1 : upessy ESP32 WROOM LOW POWER DEVKIT + TFT 2.8" ( avec tes couleurs bargraph )
    Image 2 : ESP32-2432S028R ( avec mes couleurs bargraph )

    bien cordialement
    pascal
    Images attachées Images attachées   

  6. #26
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 646
    Points : 1 643
    Points
    1 643
    Par défaut
    Hello Cobra38,

    Content que ça fonctionne.
    Pour les couleurs, je n'avais pas la moindre idée de ce que ça allait donner avec celles que j'avais mises dans les #define. Il fallait simplement qu'elles soient différentes.
    J'ai repensé au problème du 143% qui serait le maximum. Et la solution est très simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #define BAR_BACKGROUND_COLOR    0xabcd
    #define BAR_FOREGROUND_COLOR    0xdcba
    #define MAXPC                   100.        // ne pas oublier le point décimal !
     
    void DisplayBarGraph(void) {
        tft.setCursor(290,1);
        tft.setTextFont(1);
        tft.setTextSize(1);
        tft.setTextColor(TFT_YELLOW, TFT_BLACK);
        tft.print(100*(int)(progress/MAXPC));    // <-----------
        tft.println("%");
        tft.drawRoundRect(300, 20, 10, 200, 5, TFT_YELLOW);
        tft.fillRoundRect(300, 20, 10, 200, 5, BAR_BACKGROUND_COLOR);
        int h=200*(progress/MAXPC);             // <-----------
        int y=20+200-h;
        tft.fillRect(300, y, 10, h, BAR_FOREGROUND_COLOR);
    }
    Il suffit de changer la valeur de MAXPC en 143. si 143% de charge correspond à "full charged".
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  7. #27
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Salut edgarjacobs

    J'ai repensé au problème du 143% qui serait le maximum. Et la solution est très simple:
    sauf que çà ne semble pas fonctionner comme espérer

    en effet si je fais çà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    #define MAXPC                   100.        // ne pas oublier le point décimal !
     
     
    /*******************************************************/
    void DisplayBarGraph(void) {
        tft.setCursor(295,1);
        tft.setTextFont(1);
        tft.setTextSize(1);
        tft.setTextColor(TFT_YELLOW, TFT_BLACK);
        //tft.print(progress); tft.println("%");
        tft.print(100*(int)(progress/MAXPC));
        tft.println("%");
        tft.drawRoundRect(300, 20, 10, 200,5,TFT_YELLOW);
        tft.fillRoundRect(300, 20, 10, 200,5,BAR_BACKGROUND_COLOR);
        int h=200*((int)(progress/MAXPC));             // <-----------     // 100% pour le maximum    
        //int h=200*(progress/100.);                     
        int y_bar=20+200-h;
        tft.fillRoundRect(300, y_bar, 10, h,5, BAR_FOREGROUND_COLOR);
        tft.drawRoundRect(300, 20, 10, 200,5,TFT_YELLOW);
    }
    j'ai en branchant la carte via l'USB
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    13:57:37.693 ->  Valeur Brute = 4095
    13:57:37.693 ->  Vbat = 4.52 Volts // mais valeur de tension lue à  la batterie 4,10v
    13:57:37.693 ->  % = 132
    valeur en % sur écran = 100%
    si je débranche l'USB => Batterie
    valeur en % sur écran = 0%

    /****************************************
    Si je programme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    /*******************************************************/
    void DisplayBarGraph(void) {
        tft.setCursor(295,1);
        tft.setTextFont(1);
        tft.setTextSize(1);
        tft.setTextColor(TFT_YELLOW, TFT_BLACK);
        tft.print(progress); tft.println("%");
        //tft.print(100*(int)(progress/MAXPC));
        tft.println("%");
        tft.drawRoundRect(300, 20, 10, 200,5,TFT_YELLOW);
        tft.fillRoundRect(300, 20, 10, 200,5,BAR_BACKGROUND_COLOR);
        //int h=200*((int)(progress/MAXPC));             // <-----------     // 100% pour le maximum    
        int h=200*(progress/100.);                     
        int y_bar=20+200-h;
        tft.fillRoundRect(300, y_bar, 10, h,5, BAR_FOREGROUND_COLOR);
        tft.drawRoundRect(300, 20, 10, 200,5,TFT_YELLOW);
    }
    Alors :
    j'ai avec USB = 132% et le bargraph idem
    et sans USB , je lis 79% et le bargraph idem

    pourquoi 79% alors la logique voudrait que je lise 90% (4,10v sur un voltmètre ) çà je n'ai pas trouvé (?)

    EDIT : après plusieurs investigations , il se trouve que j'ai deux valeurs de mesure de batterie
    L'une en veille qui donne à mon sens la vraie tension batterie = 4,10v (Voltmètre) , celle qui sert de référence à la charge
    L'autre au moment du réveil qui tombe à 3,66v lorsque l'affichage est actif

    L'idéal serait donc de mettre au réveil la valeur de 4,10v pour l'afficher ensuite sur le bargraph

  8. #28
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    J'ai lu en diagonale.
    Je ne comprends pas pourquoi tu as 4.1v en sommeil et 3.66v en fonctionnement. Cela fait un sacré voltage drop.

    Le mieux c'est que 100% = 100% de la charge maximal de la batterie.

  9. #29
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Salut _Froggy_

    Je ne comprends pas pourquoi tu as 4.1v en sommeil et 3.66v en fonctionnement. Cela fait un sacré voltage drop.
    Tout d'abord ces mesures sont faites en // de la batterie au voltmètre

    1) Lorsque l'ESP32 est "Deep Sleep" et qu'il est branché avec l'USB => je mesure 4,18v ( tension de charge max de l'accu)
    2) Si je débranche l'USB mais je reste en "Deep Sleep" => je mesure 4,10v (?)
    3) Si je réveille l'ESP32 ( avec la touche) mais sans USB => je mesure à une tension de 3,66v mini qui dure environ 5s ( le temps programmé )

    Pour afficher le bargraph , je dois donc réveiller l'ESP32 ce qui logique et affiche env 70% sans USB
    tandis qu'avec l'USB raccordé => j'affiche au bargraph 132% (4,52v)

    La vraie mesure de la batterie devrait être en toute logique 4,10v soit 97% mais il est clair je ne pourrais jamais l'afficher
    il faudrait que je puisse sauvegarder la tension batterie juste avant d'afficher le bargraph à l'écran
    or je n'ai pas réussi et j'ai du au final supprimer l'affichage du bargrah

  10. #30
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Hey !

    Le module que tu as, c'est un module tout en un ? Batterie + ESP + ecran ? Ou tu as batterie sur la carte ESP32 et l'écran est sur la breadboard alimenté directement sur le Vcc/Gnd de la carte ?
    Pour avoir la tension de la batterie, il faudrait la mesurer avant le réveil de l'écran, sauf que la valeur sera fausse si avec l'écran allumé tu perds quasiment 1v. J'avais testé Vmin pour qu'un ESP fonctionne et de mémoire c'est <2v. Mettons 2v, si tu perds 1v à l'allumage, ton écran ne s'allumera plus (2.7v d'après la doc du XPT2046) mais ton ESP sera toujours fonctionnel avec une batterie à 50% de charge.

    A mon sens, il faudrait revoir le montage, avec une telle chute de tension, j'ai peur que ton montage ne tienne pas dans la durée.

    Par ailleurs, j'ai regardé ton code et tu ne calcules v_bat que dans ton setup(), donc uniquement au démarrage de l'ESP. Il devrait se trouver dans la loop() en première instruction, puisqu'au réveil l'ESP va relancer la loop().
    Globalement, et en lisant en diagonal, pour un fonctionnement sur batterie, il faut ultra optimisé la consommation. Je n'ai plus utilisé d'ESP depuis un certain temps et pas en ultra low consommation, néanmoins il faudrait désactiver l'AGC (ou les AGC) et réactiver si besoin, le WiFi (et le réactiver que si besoin), mettre la clock du CPU au plus bas (non visible dans le code), etc etc

  11. #31
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Salut _Froggy_

    Le module que tu as, c'est un module tout en un ? Batterie + ESP + ecran ? Ou tu as batterie sur la carte ESP32 et l'écran est sur la breadboard alimenté directement sur le Vcc/Gnd de la carte ?
    le montage que j'ai fait , est le suivant

    uPesy ESP32 WROOM LOW POWER DEVKIT + Ecran TFT 2.8" + TTP223 ( réveil) , la batterie 3.7V 2000mAh est branchée directement sur la carte , elle intègre le chargeur

    La consommation en Deep Sleep est d'env 15 µA , je n'ai pas pu le mesurer mais ce qui est certains c'est que j'ai alimenté le module durant des jours sans allumer l'écran, au final je n'avais perdu que 0,01 v sur la batterie
    (j'ai par ailleurs un autre montage avec le même µC aussi en "Deep Sleep" qui lui est actif depuis + 6 mois et il est encore à 70% de batterie)
    Donc je peux légitiment penser que le constructeur a raison ...

    Par ailleurs, j'ai regardé ton code et tu ne calcules v_bat que dans ton setup(), donc uniquement au démarrage de l'ESP. Il devrait se trouver dans la loop() en première instruction, puisqu'au réveil l'ESP va relancer la loop().
    oui , effectivement , je n'y ai pas pensé
    peut-être qu'en le mettant dans la boucle LOOP je pourrais l'activer que lorsque je réveille l'ESP32 à voir donc ..

    Globalement, et en lisant en diagonal, pour un fonctionnement sur batterie, il faut ultra optimisé la consommation. Je n'ai plus utilisé d'ESP depuis un certain temps et pas en ultra low consommation, néanmoins il faudrait désactiver l'AGC (ou les AGC) et réactiver si besoin, le WiFi (et le réactiver que si besoin), mettre la clock du CPU au plus bas (non visible dans le code), etc etc
    Le constructeur m'indique ceci en mode Deep Sleep , l'ensemble de l'ESP32 semble donc bien éteint à l'exception bien sûr de la surveillance des GPIO et la memoire pour garder les informations essentielles
    le but étant d'allumer 8 lampes à distance , j'utilise ESPNow qui ne fait pas d'appel au WiFi de façon traditionnel

    Si tu souhaites d'autres infos , dis le moi ..
    Images attachées Images attachées  

  12. #32
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    L'écran TFT est directement alimenté par Vcc de la carte ESP ? Le régulateur de la carte ESP est donné pour > 500mA, donc si ta batterie est bien du 4.2v 2000mAh, tu ne devrais pas avoir de chute de tension.
    Au niveau de la consommation, je parlais surtout quand le module fonctionne. Si cela reste allumer 5s, par exemple tu n'as besoin de l'ADC que lors du calcul de VBAT. Tu peux integrer la remise en route de l'ADC dans ta fonction et l'eteindre après avoir relevé la valeur.

    Pour v_bat, dans ta version actuelle, il te donne la valeur au moment du démarrage de l'ESP puis ne change jamais. Donc si tu le branches en USB + batterie pour charger, que tu débranches l'USB, l'ESP ne redémarre pas. Donc la valeur correspond à celle au démarrage en USB ou lors de la dernière modification du programme (donc en USB).

  13. #33
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 791
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 791
    Points : 5 610
    Points
    5 610
    Par défaut
    Citation Envoyé par _Froggy_ Voir le message
    Par ailleurs, j'ai regardé ton code et tu ne calcules v_bat que dans ton setup(), donc uniquement au démarrage de l'ESP. Il devrait se trouver dans la loop() en première instruction, puisqu'au réveil l'ESP va relancer la loop().
    l'ESP32 reboot complètement en sortant de deep sleep donc le setup() est exécuté à nouveau

  14. #34
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 412
    Points : 4 474
    Points
    4 474
    Par défaut
    Bonjour,

    Lorsque l'USB est branché, la batterie est en charge. La tension à ses bornes n'est donc pas représentative de l'état de charge.

    Sur beaucoup d'appareils, le mode en charge est représenté par un éclair et l'état de charge - s'il est indiqué - se fait pendant une brève interruption de la charge pour éviter de confondre charge et chargeur. Mais, même dans ce cas là, la mesure est approximative (température de batterie supérieure à la normale, condensateurs de filtrage chargés à bloc etc.).

    La solution la plus simple serait donc de ne pas faire de mesure si la batterie est en charge (i.e. branchée en USB). En effet, faire une mesure supposerait alors un circuit (simple mais supplémentaire) qui coupe le 5 V de l'USB, attend quelques dizaines de ms, fait la mesure et rétablit l'alimentation.

    Par ailleurs, les mesures de tension à vide, ou quasiment à vide, ne représentent pas la charge. C'est pourquoi on ne peut savoir l'état de charge d'une pile (ou d'un accu) avec un multimètre en V= car sa résistance d'entrée est tellement forte qu'une pile en fin de vie montrera fièrement ses 1.5V, mais s'effondrera lamentablement si elle doit débiter dans, par exemple, 100k (15 uA quand même ).
    Aussi la mesure du multimètre en veille profonde n'apporte aucune information sur la charge de la batterie. Sauf si la valeur mesurée reste très faible : il est temps de changer de batterie

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  15. #35
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par Jay M Voir le message
    l'ESP32 reboot complètement en sortant de deep sleep donc le setup() est exécuté à nouveau
    Je ne me souvenais plus de cela.

    Ce qui fait qu'on ne peut pas avoir vbat sans l'écran (enfin, il faut tester en débranchant l'écran ou rajouter un mosfet).

  16. #36
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 819
    Points : 235
    Points
    235
    Par défaut
    Bonjour à tous ,

    Merci encore de vous pencher sur mon petit problème qui, semble-t-il, dépasse mes compétences en matière de batterie
    c'est mon gros point noir au milieu de beaucoup d'autres j'avoue
    j'ai donc pris l'option à regret de ne pas afficher vbat car non significatif de l'état de la batterie
    j'avais pensé aussi à un moyen externe à savoir un élément comme par ex :
    https://fr.aliexpress.com/item/10050...Cquery_from%3A

    mais trop encombrant au final

    je vous mets une photo du proto fini mais je dois encore faire les 7 modules externes
    Si vous avez d'autres suggestions , je suis preneur


    merci encore
    pascal
    Images attachées Images attachées  

  17. #37
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Le problème à mon sens n'est pas l'affichage ou le calcul de vbat mais le montage électronique. Si tu mesures 3.66v en fonctionnement, il y a un problème de montage (ou la batterie est un fake et tu n'a pas les mAh annoncé, ce qui dans le cas d'aliexpress/amazon est un classique), c'est pour cela qu'il serait intéressant que tu montres le montage électronique. Sur le papier, tu devrais avoir minimum 4v en fonctionnement.

  18. #38
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 412
    Points : 4 474
    Points
    4 474
    Par défaut
    Bonjour Froggy,

    Citation Envoyé par _Froggy_ Voir le message
    Le problème à mon sens n'est pas l'affichage ou le calcul de vbat mais le montage électronique. Si tu mesures 3.66v en fonctionnement, il y a un problème de montage (ou la batterie est un fake et tu n'a pas les mAh annoncé, ce qui dans le cas d'aliexpress/amazon est un classique), c'est pour cela qu'il serait intéressant que tu montres le montage électronique. Sur le papier, tu devrais avoir minimum 4v en fonctionnement.
    En pratique, de 3.6V à 3.7V sont des valeurs typiques de fonctionnement des batteries au lithium.

    Les valeurs supérieures résultent, soit de la mesure d'une batterie en charge (la tension d'un chargeur doit nécessairement être supérieure à celle nominale de la batterie), soit une mesure sans débit (par exemple avec un multimètre moderne comme déjà expliqué).

    Par ailleurs, il semble y avoir une confusion entre tension et capacité. Deux bonnes batteries de capacités différentes peuvent avoir la même tension nominale (qui n'est liée qu'à la valeur du couple électrolytique). Bien sûr la plus faible s'essoufflera avant l'autre.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  19. #39
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Je suis d'accord, pour moi il faudrait le montage avec les références. J'ai souvenir avoir vu un projet avec une batterie de 4v

  20. #40
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 412
    Points : 4 474
    Points
    4 474
    Par défaut
    Bonjour _Froggy_,

    Citation Envoyé par _Froggy_ Voir le message
    ...il faudrait le montage avec les références. J'ai souvenir avoir vu un projet avec une batterie de 4v
    A partir du schéma de la carte, on trouve le modèle et donc la doc du constructeur uPesy :
    "Via une batterie externe ( ) : On connecte une batterie Lithium-ion/LiPo de 3.7V sur le connecteur JST PH 2.0. Si l’on branche l’USB en même temps, la carte recharge la batterie. Ce mode d’alimentation est optimisé pour la consommation de courant : la consommation sera < 15µA en Deep Sleep."

    Le sujet de l'instabilité des mesures de tensions avaient déjà été rencontrées sur cette carte et reconnue par la société. Elle est bien due à un pont diviseur présentant une trop forte impédance équivalente. Pour moi, la solution à tenter serait de mettre en parallèle du condensateur de 100 nF un autre condensateur de 1 uF et d'espacer les mesures d'au moins 800 ms (il faut que la capacité équivalent de 1.1 µF atteigne sa tension nominale). Cela permet d'avoir une impédance dynamique beaucoup plus faible pendant la mesure. C'est contraignant mais avec un peu de chances, une seule mesure suffirait.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

Discussions similaires

  1. Réponses: 3
    Dernier message: 31/01/2007, 10h45
  2. Réponses: 1
    Dernier message: 11/09/2006, 20h07
  3. Actualiser l'affichage de boutons
    Par pouillou dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 07/05/2006, 18h09
  4. Affichage des boutons d'un TDBNavigator
    Par AlexB59 dans le forum Bases de données
    Réponses: 4
    Dernier message: 29/12/2005, 22h28
  5. affichage automatique bouton et zone de liste
    Par mathilde50 dans le forum IHM
    Réponses: 4
    Dernier message: 16/11/2004, 16h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo