C et tableau, enum etc..
Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 30 sur 52

C et tableau, enum etc..



  1. #1
    hary

    C et tableau, enum etc..


    ------

    Bonjour

    Pour programmer un uC, je voudrais faire un genre de tableau qui me donne l'état de charge d'une batterie auto en fonction de sa tension.

    UBat > 14400 //tension batterie en mV chargé
    UBat > 12600 bon
    UBat > 12200 moyen
    UBat < 12100 mauvais

    Je pensais utiliser un tableau et enum, mais je ne sais pas comment m'y prendre.
    J'ai bien vu des exemples mais je n'arrive absolument pas à transposer pour mon cas ! Je suis débutant en programmation.

    Ensuite en fonction de l'état de la batterie et d'autres paramètres, je souhaite faire une machine d'état avec switch case.

    Pourriez vous m'aiguiller. A moins qu'une autre solution plus adaptée soit préférable.

    -----

  2. #2
    inviteb9f49292

    Re : C et tableau, enum etc..

    Tu veux un tableau pour quoi ? Pour stocker les valeurs de tensions limites ?
    Si je comprends bien ton problème, tu dois convertir une tension en mV en un niveau de charge représenté par une "enum".
    1°) il faut donc déclarer ton enum, montre nous ce que tu as fais.
    2°) il te faut la conversion, une solution étant une fonction prennant en entrée la tension en mV et qui retourne l'enum correspondante, je ne vois pas vraiment où peux se situer la dificulté algorithmique là-dedans, montre nous ce que tu as en tête (au moins en pseudo-code)

    La fonction du 2 peux certainement utiliser un tableau, mais ce n'est pas obligatoire (ni même la 1ère solution qui me viendrait à l'esprit). Je te propose d'insérer l'utilisation d'un tableau dans la conversion une fois que tu auras les idées plus claires pour les points 1 et 2 ci-dessus.

  3. #3
    hary

    Re : C et tableau, enum etc..

    Je vois que ma première réponse n'est pas partie !

    Je vais donc essayer de reformuler.

    Grosso modo, c'est une régulation pour l'installation solaire de ma cabane d'été qui est alimentée par panneaux photovoltaique.

    J'ai un système assez simple (90W de panneaux, 150Ah de batteries 12V; Un onduleur DC12/AC220V, une pompe à eau de 90W /220V et un frigo 135W/220V).

    Le frigo est prioritaire lorsque le thermostat en fait la demande. Le thermostat est "hacké", il ne commande plus le moteur. Il envoie l'info au uC et en fonction de l'état de charge de la batterie autorise ou non l'alimentation de la prise frigo.

    La pompe fonctionne uniquement quand la batterie est chargée, cad, que sa tension est passée au dessus de 14.4V

    J'aurais donc voulu déclarer des états de batteries en fonction de sa tension.

    chargé U > 14.4V
    Bon U > 12.6V
    moyen >12.2V
    déchargé <12.1V

    et ensuite utiliser ces états pour commander mes appareils.

    Si batterie "chargé" et ensuite si batterie "bon" => autoriser la pompe
    Si batterie "moyen" && demande du thermostat du frigo => couper pompe (si besoin) et autoriser frigo

    Il faut en plus gérer la commande du convertisseur/onduleur, mais pour ça, je pense pouvoir m'en sortir.
    J'ai déja fait ce types de petits programmes, mais je vois bien que je m'y prends assez mal, mes programmes sont lourds, deviennent incompréhensibles, et quand je souhaite changer un seuil (voltage), je doit intervenir partout dans le programme.
    Je pense qu'il me faut déclarer des seuils (chargé, bon, moyen, déchargé) et faire comme une machine d'état.

    Est ce assez clair. Je suis désolé mais je suis absolument débutant en programmation et peine avec tout. (découpage du processus, algorithme, codage....
    Merci de votre aide.

  4. #4
    inviteb9f49292

    Re : C et tableau, enum etc..

    J'ai déja fait ce types de petits programmes, mais je vois bien que je m'y prends assez mal, mes programmes sont lourds, deviennent incompréhensibles, et quand je souhaite changer un seuil (voltage), je doit intervenir partout dans le programme.
    C'est, je pense, symptomatique d'un manque d'expérience dans la conception de tes programmes, avant même les problèmes de maitrise de la syntaxe (C ou autre langage)... Malheureusement, a part l'expérience je ne vois pas vraiment de recette miracle pour ce problème. Mais tu as déjà l'avantage de remarquer ce problème chez toi, il y a donc de l'espoir...

    Pour ce problème précis, je ferais un truc dans ce genre:
    Code:
    #define BATTERY_LEVEL_FULL_mV      14400
    #define BATTERY_LEVEL_HIGH_mV      12600
    #define BATTERY_LEVEL_MIDDLE_mV 12200
    #define BATTERY_LEVEL_LOW_mV      12100
    
    enum battery_level_t {
        BATTERY_LEVEL_CRITICAL,
        BATTERY_LEVEL_LOW,
        BATTERY_LEVEL_MIDDLE,
        BATTERY_LEVEL_HIGH,
        BATTERY_LEVEL_FULL
    };
    
    enum battery_level_t mV_to_battery_level (int mV) {
        if (mV > BATTERY_LEVEL_FULL_mV) {
            return BATTERY_LEVEL_FULL;
        }
        if (mV > BATTERY_LEVEL_HIGH_mV) {
            return BATTERY_LEVEL_HIGH;
        }
        if (mV > BATTERY_LEVEL_MIDDLE_mV) {
            return BATTERY_LEVEL_MIDDLE;
        }
         if (mV > BATTERY_LEVEL_LOW_mV) {
            return BATTERY_LEVEL_LOW;
        }
        return BATTERY_LEVEL_CRITICAL;
    }
    Ainsi lorsque tu veux changer un seuil, tu modifies le "#define" et tu recompiles, ce qui sous entends que tu utilises le symbol de partout dans ton code, jamais la valeur explicite...

    C'est une première mise en pratique de la conception: une fonctionnalité (associer une mesure en mV à un état de batterie) correspond à une entité logicielle (ici matérialisée par une enum et une fonction). Cette entité ne doit faire que ça, et tout les sous-ensembles de ton programme qui ont besoin de cette fonctionnalité appellent cette entité.

  5. A voir en vidéo sur Futura
  6. #5
    hary

    Re : C et tableau, enum etc..

    Tu as parfaitement raison sur mon manque d'expérience.
    Je ne cherche qu'à au moins écrire quelque chose d'assez propre avec au moins de pas trop mauvais principes de base.

    concernant ta réponse, j'ai l'impression que dans le 2èmem enum tu fais 2 chose en même temps et je n'arrive pas à décripter ce qui se passe.

    Est il possible de détailler les étapes ?

    enum battery_level_t mV_to_battery_level (int mV)
    Je comprends que tu fais un genre de fonction avec comme paramètre (mV) qui sera ma mesure faite par mon uC et son ADC.
    Ce qui me perturbe c'est qu'il n'y a pas de "_" entre le "t" et le"mV"

    Est ce 1 seul "truc" ou 2 "truc" ?
    "battery_level_t mV_to_battery_level"

    Désolé pour ces questions sans doute très mal formulée.

  7. #6
    hary

    Re : C et tableau, enum etc..

    Je vois que tu as utilisé que des "if".

    J'aurais fais quelque chose du style :
    if
    else if
    else if
    else


    serait ce une erreur ?
    est ce différent ou identique ?

  8. #7
    hary

    Re : C et tableau, enum etc..

    J'ai intégré ce que tu m'a préparé.
    Voici ce que ça donne.


    Code:
    #define  ThermostatFrigo 8
    #define EtatThermostatFrigo !digitalRead (ThermostatFrigo)
    /*void EtatThermostatFrigo () {
     valeur = !digitalRead (ThermostatFrigo);
     if (!ancienneValeur && valeur){
     }
     ancienneValeur = valeur;
     delay(20);
     }*/
    #define UPont A0 //meusure de tension au pont diviseur
    
    #define Relai1 7
    #define Pompe Relai1
    #define PompeOn digitalWrite (Pompe, 0)
    #define PompeOff digitalWrite (Pompe, 1)
    #define EtatFrigo digitalRead (Frigo)
    
    #define Relai2 6
    #define Frigo Relai2
    #define FrigoOn digitalWrite (Frigo, 0)
    #define FrigoOff digitalWrite (Frigo, 1)
    #define EtatPompe digitalRead(Pompe)
    
    #define Relai3 5
    #define Onduleur Relai3
    #define OnduleurOn digitalWrite (Onduleur, 0)
    #define OnduleurOff digitalWrite (Onduleur, 1)
    
    int R1 = 217000; //resistance 1 du pont diviseur de tension
    int R2 = 100000; //resistance 2 du pont diviseur de tension
    
    
    
    #define BATTERY_LEVEL_FULL_mV      14400
    #define BATTERY_LEVEL_HIGH_mV      12600
    #define BATTERY_LEVEL_MIDDLE_mV 12200
    #define BATTERY_LEVEL_LOW_mV      12100
    
    enum battery_level_t {
      BATTERY_LEVEL_CRITICAL,
      BATTERY_LEVEL_LOW,
      BATTERY_LEVEL_MIDDLE,
      BATTERY_LEVEL_HIGH,
      BATTERY_LEVEL_FULL
    };
    
    enum int battery_level_t mV_to_battery_level (int mV) {
      if (mV > BATTERY_LEVEL_FULL_mV) {
        return BATTERY_LEVEL_FULL;
      }
      if (mV > BATTERY_LEVEL_HIGH_mV) {
        return BATTERY_LEVEL_HIGH;
      }
      if (mV > BATTERY_LEVEL_MIDDLE_mV) {
        return BATTERY_LEVEL_MIDDLE;
      }
      if (mV > BATTERY_LEVEL_LOW_mV) {
        return BATTERY_LEVEL_LOW;
      }
      return BATTERY_LEVEL_CRITICAL;
    }
    
    
    
    long readVcc() {
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      ADMUX = _BV(MUX5) | _BV(MUX0) ;
    #else
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #endif  
    
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA,ADSC)); // measuring
    
      uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
      uint8_t high = ADCH; // unlocks both
    
      long result = (high<<8) | low;
    
      result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
      return result; // Vcc in millivolts
    }
    
    int mV () {
      long result = (analogRead (UPont)) * readVcc() /1024 * (R1 + R2)/R2 * 1000;
      return result; // UBat en millivolts
    }
    
    
    
    void setup() {
      pinMode (ThermostatFrigo, 0);
      digitalWrite (ThermostatFrigo, 1); //Resistance Pull_Up On
      pinMode (Pompe, 1);
      pinMode (Frigo, 1);
      pinMode (Onduleur, 1);
      pinMode (UPont, 0);
      PORTD |= (1<<Onduleur) | (1<<Pompe) | (1<<Frigo); //Relais ouverts a 1 (fonctionnement des appareil à l'arrêt pour 1)
    }
    
    void loop() {
      if (EtatThermostatFrigo && BATTERY_LEVEL_MIDDLE ) {
        PompeOff;
        OnduleurOn;
        delay(2000)//tempo pour que l'onduleur dse stabilise
          FrigoOn;
      }
      if (!EtatThermostatFrigo) {
        FrigoOff;
      }
      if (BATTERY_LEVEL_FULL) {
        OnduleurOn;
        delay(1000);
        PompeOn; 
        delay(5000);
      }
      if (! BATTERY_LEVEL_HIGH) {
        PompeOff;
      }
    
      val = millis();
      if (!EtatPompe && !EtatFrigo )//plus de 1 minute
      {
        val = millis();
        if (tempo > 60000)
          OnduleurOff;
    
      }
      val = millis();
    }

    C'est de l'Arduino, mais je pense que c'est compréhensible pour un programmeur en C
    Dernière modification par hary ; 13/06/2014 à 19h27.

  9. #8
    inviteb9f49292

    Re : C et tableau, enum etc..

    Tu as parfaitement raison sur mon manque d'expérience.
    Je ne cherche qu'à au moins écrire quelque chose d'assez propre avec au moins de pas trop mauvais principes de base.
    Excellent réflexe! On peut très bien être un programmeur du dimanche et faire les choses bien !

    concernant ta réponse, j'ai l'impression que dans le 2èmem enum tu fais 2 chose en même temps et je n'arrive pas à décripter ce qui se passe.

    Est il possible de détailler les étapes ?
    Détaillons...
    Quelques remarques sur le style: je n'utilise (quasiment) jamais de typedef devant mes struct et autres enum, ainsi chaque déclaration devra être précédé du mot clef "enum", "struct" ... ce qui documente. Les types que je défini sont toujours suffixé par "_t". Mes constantes sont toujours en lettres capitales, et lorsqu'il y a des unitées physiques, je la rajoute à la fin du symbol.

    Dans un premier temps (les "#define"), j'ai juste définis des constantes symboliques, qui seront plus facile à manipuler partout dans le code que leur valeur en dure, avec l'avantage (déjà discuté précédement) de ne remplacer qu'à cette endroit la valeur pour pouvoir la répercuter dans tout ton programme moyennant une recompilation. Ils sont suffixés "_mV" car ce sont des valeurs en millivolt et je voulais éviter d'utiliser du flottant (uC), mais ça ne change pas grand chose au propos si tu définis tes constantes flottantes.

    Puis les enum, rien de spécial à déclarer.

    J'utilise volontairement des noms très proches entre les constantes symbolique et les enum puisqu'elles "recouvrent" le même concept. De plus les enum reprennent le nom du type (en majuscule puisque ce sont des constantes) dans un but "documentaire" (TOTO_MACHIN sera vraissemblablement du type enum toto_t).

    Tout ça ce sont mes conventions, bâties en lisant ce que faisaient les autres, forgées par mon expérience de terrain, et agrémentées de mes préférences personnelles. Le code suivant fait la même chose, mais je le trouve moins clair:
    Code:
    #define QUATORZE_VIRGULE_QUATRE 14.4
    #define DOUZE_VIRGULE_SIX 12.6
    #define DOUZE_VIRGULE_DEUX 12.2
    #define DOUZE_VIRGULE_UN 12.1
    
    enum battery_level {
        critical,
        low,
        middle,
        high,
        full
    };
    La dernière étape est juste une fonction qui prend un entier en argument que j'ai nommé mV pour "documenté" que la fonction attends en entrée un niveau en mV, mais il pourrait tout aussi bien s'appeller "x" ou "niveau_lu_depuis_le_CAN"
    ça ne change pas grand chose.

    Est ce 1 seul "truc" ou 2 "truc" ?
    "battery_level_t mV_to_battery_level"
    Cette fonction retourne une valeur d'enum définie ci-dessus, c'est donc bien deux trucs. Je suppose que ce qui te perturbe est le fait que la fonction retourne une enum, c'est tout à fait légal, en C n'importe quel type "intégral" (je crois que c'est le terme pour les types de bases) peut être un retour de fonction. la signature d'une fonction est bien de la forme suivante:
    Code:
    type_de_retour nom_de_la_fonction (type_arg_1 arg1, type_arg_2 arg2, ...);
    Bon j'aurais pu la nommer "convert_mV_to_battery_lev el" ça aurait été peut-être moins perturbant, et ça ferais peut-être moins mal au yeux (et ce n'est pas négligeable)...

    Je vois que tu as utilisé que des "if".

    J'aurais fais quelque chose du style :
    if
    else if
    else if
    else


    serait ce une erreur ?
    est ce différent ou identique ?
    Ca ne changerait rien puisque le "return" dans le "if" court-circuite le code en-dessous, que ce soit un else ou autre chose. C'est une autre de mes conventions: limiter au maximum le nb d'indentation, un "else" en moins c'est une indentation de moins...

    J'espère que c'est plus clair, sinon n'hésite pas à poser toutes les questions qui te passe par la tête, tant pis si elle sont mal formulées...

  10. #9
    hary

    Re : C et tableau, enum etc..

    Tu dis :
    la signature d'une fonction est bien de la forme suivante:


    type_de_retour nom_de_la_fonction (type_arg_1 arg1, type_arg_2 arg2, ...);
    Alors ici :
    Code:
    enum int battery_level_t mV_to_battery_level (int mV) {
    Le nom de la fonction est : "battery_level_t mV_to_battery_level" ou plutot "battery_level_tmV_to_battery_ level" ou "battery_level_t_mV_to_battery_level"
    Car sinon ça passe pas la compil.
    Dernière modification par hary ; 13/06/2014 à 20h11.

  11. #10
    inviteb9f49292

    Re : C et tableau, enum etc..

    Le nom de la fonction est : "battery_level_t mV_to_battery_level" ou plutot "battery_level_tmV_to_batt ery_ level" ou "battery_level_t_mV_to_battery _level"
    Car sinon ça passe pas la compil.
    Pourquoi veux tu ajouter ou enlever des espaces? Le nom de ma fonction est "mV_to_battery_level", OK le type de retour est en deux mots clefs "enum" (réservé par le C) _ET_ "battery_level_t" (que j'ai choisi pour nommé mon type d'énumération).

    Alors ici :
    Code:

    enum int battery_level_t mV_to_battery_level (int mV) {
    .
    Et ce qui ne passe pas à la compil est certainement le "int" que tu as ajouté entre "enum" et le nom de mon enum.

    Repotasse un peu tes bases de C, il faut que tu sois à l'aise avec les enum et autres struct, se sont les outils qui te seront indispensables pour organiser ton code. La "bible" K&R doit pouvoir se trouver d'occaz assez facilement (même en français), il faut prendre la dernière version (la V2 je crois) et faire les exos. Ce n'est peut être plus la meilleur référence pour apprendre le C, mais faute de mieux... Il y avait le site du zéro, je crois qu'il a changé de nom et je ne connais que de nom.

    Je jette un oeil à ton code et je reviens.

  12. #11
    inviteb9f49292

    Re : C et tableau, enum etc..

    Code:
    #define Relai1 7
    #define Pompe Relai1
    Ce n'est pas dramatique mais un seul #define suffirait
    Code:
    #define RELAI_POMPE 7
    Code:
    int R1 = 217000; //resistance 1 du pont diviseur de tension
    int R2 = 100000; //resistance 2 du pont diviseur de tension
    
    // ... et une 50aine de lignes plus tard
    
    long result = (analogRead (UPont)) * readVcc() /1024 * (R1 + R2)/R2 * 1000;
      return result; // UBat en millivolts
    }
    Déclare tes variables au plus proche de leur utilisation, donc ici _DANS_ la fonction (réduire le "scope" des variables).
    pour ce cas précis des #define suffise
    Le nom de la fonction n'est pas suffisant, le nom d'une fonction doit refléter ce qu'elle fait exactement (c'est souvent un verbe), "adc_convert" par exemple. Si tu veux préciser l'unité comme je te le
    suggérais pourquoi pas mais alors je trouve plus important sur les "contenants de valeurs", dans ton cas "R1_mOhm" et "result_mV"
    Tu utilises un long, c'est bien tu as pensé au débordement, saut que ta fonction retourne un "int", donc s'il devait y avoir un débordement il apparaitra à ce moment là.

    Code:
    if (EtatThermostatFrigo && BATTERY_LEVEL_MIDDLE )
    ouch! le "&&" est un test logique, et tout ce qui est différent de 0 c'est 1, de plus je ne comprends pas l'utilisation que tu fais de l'enum...

    en pseudo-code ça donnerait:
    Code:
    int x = lecture_CAN (tension_batterie);
    long u_mV = convertir_CAN_mV (x);
    enum battery_level_t etat_batterie = mV_to_battery_level (u_mV);
    switch (etat_batterie) {
        case BATTERY_LEVEL_CRITICAL:
        // Ton code
        break;
    
        case BATTERY_LEVEL_LOW:
        // ton code
        break;
    
        // ...
    }
    On sent la volonté de faire des sous-fonctions c'est bien, pousse le bouchon plus loin, fais toi des petites bibliothèques: tu utilises souvent les convertisseurs AN, fais un fichier "can.c" avec les fonctions de configurations, de lecture, de conversion... dont tu as besoin, et un fichier "can.h" avec uniquement les signatures des fonctions et les symboles dont tu as besoins à l'extérieur de "can.c". Tous les symboles, fonctions, ... doivent commencer par can ou CAN (par exemple "int can_read (int id_can);" ou "#define CAN_NB 8")... En réutilisant ces bibliothèques projets après projets tu les corrigera.

  13. #12
    hary

    Re : C et tableau, enum etc..

    en réponse au message de 21h41.

    Oui en effet, le fait que le type de l'enum soit en 2 parties me perturbe.
    Donc concernant le 2ème le type est :
    enum battery_level_t
    et le nom de la fonction :
    mV_to_battery_level (int mV)

    concernant la 1ère enum; le type est il :
    enum battery_level_t

    Concernant le potassage du C et le site du ZERO qui maintenant s'appelle OpenClassRoom, j'ai bien suivi le cours de NEBRA je crois
    http://fr.openclassrooms.com/informa...rogrammer-en-c
    Mais je dois avouer que l'approche sans pouvoir commander des Leds et des relais ne me passionne pas.

  14. #13
    hary

    Re : C et tableau, enum etc..

    Citation Envoyé par lou_ibmix_xi Voir le message
    Code:
    #define Relai1 7
    #define Pompe Relai1
    Ce n'est pas dramatique mais un seul #define suffirait
    Code:
    #define RELAI_POMPE 7
    Oui mais il faut réécrire RELAI_POMPE qui est plus long que Pompe et j'avais entendu dire que le programmeur était fainéant, ce que j'avais bien retenu !

    Citation Envoyé par lou_ibmix_xi Voir le message
    Code:
    int R1 = 217000; //resistance 1 du pont diviseur de tension
    int R2 = 100000; //resistance 2 du pont diviseur de tension
    
    // ... et une 50aine de lignes plus tard
    
    long result = (analogRead (UPont)) * readVcc() /1024 * (R1 + R2)/R2 * 1000;
      return result; // UBat en millivolts
    }
    Déclare tes variables au plus proche de leur utilisation, donc ici _DANS_ la fonction (réduire le "scope" des variables).
    pour ce cas précis des #define suffise
    J'ai peur que ça devienne alors une variable locale et que ça pose problème si je l'utilise ailleurs par la suite.

    Citation Envoyé par lou_ibmix_xi Voir le message
    Le nom de la fonction n'est pas suffisant, le nom d'une fonction doit refléter ce qu'elle fait exactement (c'est souvent un verbe), "adc_convert" par exemple. Si tu veux préciser l'unité comme je te le
    suggérais pourquoi pas mais alors je trouve plus important sur les "contenants de valeurs", dans ton cas "R1_mOhm" et "result_mV"
    Tu utilises un long, c'est bien tu as pensé au débordement, saut que ta fonction retourne un "int", donc s'il devait y avoir un débordement il apparaitra à ce moment là.
    Oui ce que j'ai écrit n'est pas cohérent !

    Pour la suite, je dois décortiquer un peu plus.
    Pour les sous-fonctions, c'est ce que l'on a inculqué au dernier cours que j'ai fait, alors j'essaie de faire bien.
    Tu auras compris, ce n'est pas moi qui a écrit la fonction ReadVcc().
    Pour les .h et .c, toute cette organisation me dépasse franchement pour le moment ! La façon de les préparer pour qu'elles soient "parlantes", universelles....
    Je pourrais faire un truc du genre pour détecter des flancs montant, descendant, du debouncing ? des timers etc je suppose. Mais je ne me sens pas assez de maitrise et de méthode pour ça à présent.

  15. #14
    hary

    Re : C et tableau, enum etc..

    J'ai revu en suivant tes observations
    Maintenant, je me demande si une machine d'état est le plus judicieux car j'ai de la difficulté à faire ce que je souhaite.
    Mais, ça me pique les yeux maintenant et je suis absent le WE.
    Bon WE et à lundi si tu veux bien !
    Et merci.


    Code:
    #define  ThermostatFrigo 8
    #define EtatThermostatFrigo !digitalRead (ThermostatFrigo)
    /*void EtatThermostatFrigo () {
     valeur = !digitalRead (ThermostatFrigo);
     if (!ancienneValeur && valeur){
     }
     ancienneValeur = valeur;
     delay(20);
     }*/
    #define UPont A0 //meusure de tension au pont diviseur
    
    #define Relai1 7
    #define Pompe Relai1
    #define PompeOn digitalWrite (Pompe, 0)
    #define PompeOff digitalWrite (Pompe, 1)
    #define EtatFrigo digitalRead (Frigo)
    
    #define Relai2 6
    #define Frigo Relai2
    #define FrigoOn digitalWrite (Frigo, 0)
    #define FrigoOff digitalWrite (Frigo, 1)
    #define EtatPompe digitalRead(Pompe)
    
    #define Relai3 5
    #define Onduleur Relai3
    #define OnduleurOn digitalWrite (Onduleur, 0)
    #define OnduleurOff digitalWrite (Onduleur, 1)
    
    #define BATTERY_LEVEL_FULL_mV      14400
    #define BATTERY_LEVEL_HIGH_mV      12600
    #define BATTERY_LEVEL_MIDDLE_mV   12200
    #define BATTERY_LEVEL_LOW_mV      12100
    
    enum battery_level_t {
      BATTERY_LEVEL_CRITICAL,
      BATTERY_LEVEL_LOW,
      BATTERY_LEVEL_MIDDLE,
      BATTERY_LEVEL_HIGH,
      BATTERY_LEVEL_FULL
    };
    
    enum battery_level_t mV_to_battery_level (int mV) {
      if (mV > BATTERY_LEVEL_FULL_mV) {
        return BATTERY_LEVEL_FULL;
      }
      if (mV > BATTERY_LEVEL_HIGH_mV) {
        return BATTERY_LEVEL_HIGH;
      }
      if (mV > BATTERY_LEVEL_MIDDLE_mV) {
        return BATTERY_LEVEL_MIDDLE;
      }
      if (mV > BATTERY_LEVEL_LOW_mV) {
        return BATTERY_LEVEL_LOW;
      }
      return BATTERY_LEVEL_CRITICAL;
    }
    
    
    
    long readVcc() {
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      ADMUX = _BV(MUX5) | _BV(MUX0) ;
    #else
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #endif  
    
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA,ADSC)); // measuring
    
      uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
      uint8_t high = ADCH; // unlocks both
    
      long result = (high<<8) | low;
    
      result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
      return result; // Vcc in millivolts
    }
    
    unsigned int calcul_tension_batterie_mV () {  //tout déclaré en int car les valeurs manipulées < 65536
    #define R1_kOhm 217    //resistance du pont diviseur en kOhm
    #define R2_kOhom 100    //resistance du pont diviseur en kOhm
      uint16_t result = (analogRead (UPont)) * readVcc() /1024 * (R1 + R2)/R2 * 1000; //j'ai utilisé "uint16_t" qui d'apres ce que j'ai compris est équivalent a "unsigned int". je ne comprends pas pourquoi ça n'est pas colorisé dans l'éditeur ?
      return result; // UBat en millivolts
    }
    
    
    
    void setup() {
      pinMode (ThermostatFrigo, 0);
      digitalWrite (ThermostatFrigo, 1); //Resistance Pull_Up On
      pinMode (Pompe, 1);
      pinMode (Frigo, 1);
      pinMode (Onduleur, 1);
      pinMode (UPont, 0);
      PORTD |= (1<<Onduleur) | (1<<Pompe) | (1<<Frigo); //Relais ouverts a 1 (fonctionnement des appareil à l'arrêt pour 1)
    }
    
    void loop() {
      //int x = analogRead (UPont);
      //long u_mV = x * readVcc() /1024 * (R1 + R2)/R2 * 1000;
      long u_mV = calcul_tension_batterie_mV ();
      enum battery_level_t etat_batterie = mV_to_battery_level (u_mV);
    
      switch (etat_batterie) {
      case BATTERY_LEVEL_CRITICAL:
        // Ton code
        break;
    
      case BATTERY_LEVEL_LOW:
        // ton code
        break;
    
      case BATTERY_LEVEL_MIDDLE:
        if (EtatThermostatFrigo){
          OnduleurOn;
          delay(5000);
          FrigoOn;
        }
        break;
    
      case BATTERY_LEVEL_HIGH:
        //PompeOff; ne fait pas ce que je veux ! Il me faut un hysteresis
        //OnduleurOff;
        break
    
        case BATTERY_LEVEL_FULL:
        OnduleurOn;
        PompeOn;
        break;
      }

  16. #15
    inviteb9f49292

    Re : C et tableau, enum etc..

    Oui mais il faut réécrire RELAI_POMPE qui est plus long que Pompe et j'avais entendu dire que le programmeur était fainéant, ce que j'avais bien retenu !
    C'est un bon argument mal utilisé.
    1°) n'importe quel éditeur (notepad++, vim, ...) offre la complétion, le copier-coller... bref choisi un outils d'édition avec lequel tu es efficace
    2°) quand on écrit du code, on doit passer plus de temps à réfléchir qu'à écrire, ce n'est pas de la dactylographie...
    3°) c'est souvent plus compliquer de lire du code que de l'écrire, il vaut mieux faciliter la vie au lecteur... Surtout que ce sera bien souvent toi, parce que tu es flemmard et que tu veux réutiliser le code du CAN que tu as écris il y a 6 mois

    J'ai peur que ça devienne alors une variable locale et que ça pose problème si je l'utilise ailleurs par la suite.
    Le but et de diviser le problème en sous-problèmes (fonctions) avec des interfaces claires: le problème de la conversion du CAN en mV (et donc les valeurs de R1 et R2) ne doivent intéresser que la fonction de conversion, au pire la bibliothèque du can (souvent pour régler la valeur). Autrement dit tu dois "cacher la complexité" du can dans la bibliothèque. Des variables globales, ce sont des dépendances que tu introduis, et donc un code qui se transforme en un plat de nouilles, dès que tu touches la valeur de R1, la liaison série ne marche plus...

    Pour les .h et .c, toute cette organisation me dépasse franchement pour le moment ! La façon de les préparer pour qu'elles soient "parlantes", universelles....
    Je pourrais faire un truc du genre pour détecter des flancs montant, descendant, du debouncing ? des timers etc je suppose. Mais je ne me sens pas assez de maitrise et de méthode pour ça à présent.
    C'est un passage "obligatoire", puisque c'est la première manière d'organiser le code!

    Concernant le potassage du C et le site du ZERO qui maintenant s'appelle OpenClassRoom, j'ai bien suivi le cours de NEBRA je crois
    http://fr.openclassrooms.com/informa...rogrammer-en-c
    Mais je dois avouer que l'approche sans pouvoir commander des Leds et des relais ne me passionne pas.
    Le C n'est pas forcément le mieux pour commencer, même si pour bricoler les micro-controleurs ça devient vite quasi obligatoire... Tu as l'arduino qui a priori est pas mal je pense, ou alors si tu te fiches de l'aspect pédagogique et que tu veux justes du "résultat" rapide mais efficace, peut-être raspberry pi

  17. #16
    hary

    Re : C et tableau, enum etc..

    Bon, je vois que j'ai pas mal de chose à faire évoluer.

    De toute façon, je suis déjà sous Arduino (platine, IDE et langage).
    Et je sens bien qu'il faut migrer, d'autres discutions m'y pousse aussi.
    Utiliser AVR Studio par exemple et me détacher du langage Arduino qui cache plein de chose.

    Mais pour démarrer, ça m'a beaucoup aidé et stimulé je dois dire.
    Mais je suis encore très dépendant de fonction Arduino.
    J'ai vu que l'on peut intégrer les fonctions Arduino à un autre outil de développement comme AVR Studio par exemple, mais la prise en main de tout ces outils est assez lourde pour le débutant et en plus du reste.

    Il faut dire que le principe Arduino est assez chouette. Tu branches, tu upload, et ça clignote !
    Avec toutes ses limitations bien sur, mais à la base, c'est du C, il est donc prévu de s'en libérer.
    C'est pour ça que j'ai choisi cette solution !

    Je viens de suivre un cours (MOOC) de 6 semaines sur la découverte des uC, mais il fallait tout absorber en bloc.
    La connaissance du uC, le langage de programmation, l'utilisation d'outil ...etc, j'y ai passé vraiment beaucoup de temps, parfois 10-12 heures par jour, et ça me faisait me lever à 6 heures du matin quand une question me taraudait !

    Après tout ce temps investit, pas question de lâcher le morceau. Il y a plus de 10 ans, j'ai tenté les PICs et BIGONOFF qui s'est soldé par un abandon, mais la marche était grande.
    Avec Arduino, n'importe qui peut explorer la chose pour 10€.
    En plus maintenant, j'ai accès à internet et tout ses forums. Une valeur inestimable !

  18. #17
    bisou10

    Re : C et tableau, enum etc..

    Je te laisse en main avec notre ami lou_ibmix_xi

    Par contre, concernant la gestion du MPPT, tu comptes le faire en soft, ou tu as déjà toute la chaine panneau -> accu qui est fonctionnelle ?

  19. #18
    hary

    Re : C et tableau, enum etc..

    Bisou10, pour l'instant, j'ai un régulateur PWM du commerce.

    Pour la suite, quand je me serais fait les dents avec ce premier exercice, je verrai pour y intégrer 1 MPPT avec le but principal de travailler en "haute tension" sur le réseau panneau pour charger en 12V. (Pour limiter les pertes en ligne entre panneau et batterie)

  20. #19
    hary

    Re : C et tableau, enum etc..

    Je voudrai faire quelque chose comme ceci.

    Nom : EtatSorti en fonction Batterie.png
Affichages : 306
Taille : 7,2 Ko

    Mais comment s'y prendre pour l'organiser proprement ?
    En plus il me faudrait des petites tempo à certains endroits !

  21. #20
    inviteb9f49292

    Re : C et tableau, enum etc..

    Mets toi à la place du programme...
    Comment/par quoi est cadencé le programme?
    je suppose que tu mesures la tension de batterie toutes les n secondes, puis tu prends une une action appropriée sur une série d'équipements, et on recommence, on a donc une idée de la tronche du programme:
    Code:
    tant que continuer programme
        mesurer tension batterie
        pour chaque équipements
            action en fonction de l'équipement et de la tension batterie
        fin pour
        attendre n secondes
    fin tant que
    On a déjà vu comment mesurer la tension batterie (grâce à la bibliothèque can), et comment transformer le niveau en mV en un symbole compréhensible par la suite du programme (l'enum).
    Pour la suite je ne comprends pas trop ce que tu entends par démarrage et fonctionnement, mais ça sent la structure modélisant l'équipement, avec au moins une sortie (le numéros de relais pour couper l'équipement), une entrée (le contact sec pour savoir si l'équipement est en fonctionnement), et les deux seuils
    Code:
    struct equipement_t {
        int contact;
        int relais;
        enum niveau_bat_t inhibe;
        enum niveau_bat_t coupe;
    };
    enfin l'action à effectuer sur l'equipement en fonction du niveau de batterie, si j'ai compris ton besoin:
    Code:
    void action (struct equipement_t* equip, enum niveau_bat_t niveau) {
        if (niveau < equip->coupe) {
            equip->relais = 0; // couper l'equipement
        } else if ((niveau < equip->inhibe) && (equip->contact == 0)) {
            // l'equipement ne fonctionne pas, l'empecher de démarre
            equip->relais = 0; // couper l'equipement
        }
    Voilà une voie possible...

  22. #21
    hary

    Re : C et tableau, enum etc..

    lou_ibmix_xi, je te remercie de ta sollicitude mais tu me noyes !

    Je ne peux pas exploiter ni le code ni les explications que tu me donnes. (ce n'est pas un reproche, c'est juste pour expliquer)

    Pour commencer, oui en effet, je surveille la tension batterie en "continu" et prends des décision en fonction de celle-ci.
    J’agis aussi en fonction de l'état du thermostat du frigo. ( "polling")

    Je vois que tu as sans doute ajouté "attendre n secondes" puisque j'ai parlé de tempo.

    Il y a 2 points pour ces tempos.
    D'abord avant de lancer ou arrêter un appareil électrique (frigo ou pompe) je dois pour la mise en route :
    1) mettre en route L'onduleur
    2)attendre que la tension se stabilise
    3) démarrer l'appareil.

    Ensuite quand un appareil démarre, l'appel de puissance de démarrage va faire chuter fortement la tension de la batterie pendant quelques secondes. Surtout le frigo qui absorbe 10 à 11 fois sa puissance nominale au démarrage.
    Durant cette période, la tension supposée indiquer le niveau de charge de la batterie est "pipé" et on ne doit pas tenir compte des états batteries CRITICAL, LOW, MIDDLE, ou HIGH pour commander les appareils.
    Pour l'arrêt, je doit :
    1) arrêter l'appareil,
    2) attendre,
    3) éteindre l'onduleur.

    Le tableau du message précédant indique, si, en fonction de l'état de la batterie un appareil est autorisé à démarrer et autorisé à fonctionner.
    Je ne sais si c'est la meilleure approche mais si je ne fais pas ça, l'appareil en question va sans arrêt démarrer puis arrêter ,démarrer puis arrêter encore et encore !
    En effet, à FULL j'autorise la pompe à démarrer. Elle puise dans la batterie et fait chuter sa tension dont l'état passe à HIGH.
    Le démarrage et le fonctionnement doivent donc être différencié. C'est un genre d'hystérésis.

    Pour le reste de ton code, je devrai y revenir demain.

  23. #22
    inviteb9f49292

    Re : C et tableau, enum etc..

    Je ne peux pas exploiter ni le code ni les explications que tu me donnes. (ce n'est pas un reproche, c'est juste pour expliquer)
    Il m'en faut plus pour me vexer...
    Il n'y a pas vraiment de code à exploiter dans mon précédent poste, c'est plus une "recette" pour concevoir ton programme.

    Pour commencer, oui en effet, je surveille la tension batterie en "continu" et prends des décision en fonction de celle-ci.
    J’agis aussi en fonction de l'état du thermostat du frigo. ( "polling")
    Il faut que tu choissises ce qui cadence ton programme, ce qui va définir le contenue de la boucle principale, je choisirai perso de cadencer ce type de programme sur la lecture de tension batterie, mais ce n'est peut-être pas le plus adapté à ton problème, il est peut-être plus opportun de "boucler" sur les états des équipements ou autre... Et peut-être que les deux solutions sont adaptées alors à toi d'estimer la quelle est la plus "pratique" à coder...

    D'abord avant de lancer ou arrêter un appareil électrique (frigo ou pompe) je dois pour la mise en route :
    1) mettre en route L'onduleur
    2)attendre que la tension se stabilise
    3) démarrer l'appareil.

    Ensuite quand un appareil démarre, l'appel de puissance de démarrage va faire chuter fortement la tension de la batterie pendant quelques secondes. Surtout le frigo qui absorbe 10 à 11 fois sa puissance nominale au démarrage.
    Durant cette période, la tension supposée indiquer le niveau de charge de la batterie est "pipé" et on ne doit pas tenir compte des états batteries CRITICAL, LOW, MIDDLE, ou HIGH pour commander les appareils.
    On est en plein dans la conception: si cet algo est général à tous les équipements il faut l'encapsuler dans une fonction que tu appeleras pour chaque équipement à mettre en marche, avec vraissemblalement en argument d'entrée une structure équipement pour connaître le relais à fermer (contenu dans ta structure), et la condition de sortie qui va bien (attendre que la tension batterie soit stable), puisque tu es bloqué dans la fonction tant que la tension batterie n'est pas stabilisée, la fonction étant dans la boucle principale, la boucle principale est bloquée, tu ne fais donc pas de mesure sur la tension batterie qui n'est pas encore stabilisée...

    Essaye d'écrire en pseudo code, et de plus en plus détaillé, comment tu vois ton programme, pour chaque sous-fonctions identifiées liste les paramètres nécessaires, et regroupe les par "entité fonctionnelle" (le relais et le contact sec d'unéquipement -> structure equipement_t)

  24. #23
    hary

    Re : C et tableau, enum etc..

    Bon, j'ai revu la chose et suis reparti d'un truc basic, comme j'avais l'habitude de faire.

    Une fois que ceci marchera, je pourrai avec ton aide, le faire évoluer, le sophistiquer et faire les choses proprement.

    Pour l'instant, j'ai des valeur aberrante pour "u_mV" ( ça monte très haut, ça varie sans raison) et je n'arrive pas à comprendre pourquoi.
    Comme le calcul de u_mV faisait intervenir des divisions, j'ai mit float a la place de int, mais idem.
    Code:
    #define DEBUG
    
    #define Led13 13
    #define UPont A0 //meusure de tension au pont diviseur
    
    #define Relai1 7
    #define Pompe Relai1
    #define PompeOn digitalWrite (Pompe, 0)
    #define PompeOff digitalWrite (Pompe, 1)
    #define EtatPompe !digitalRead (Pompe)
    
    #define Relai2 6
    #define Frigo Relai2
    #define FrigoOn digitalWrite (Frigo, 0)
    #define FrigoOff digitalWrite (Frigo, 1)
    #define EtatFrigo !digitalRead(Pompe)
    
    #define Relai3 5
    #define Onduleur Relai3
    #define OnduleurOn digitalWrite (Onduleur, 0)
    #define OnduleurOff digitalWrite (Onduleur, 1)
    #define EtatOnduleur !digitalRead(Onduleur)
    
    long readVcc() {
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      ADMUX = _BV(MUX5) | _BV(MUX0) ;
    #else
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #endif  
    
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA,ADSC)); // measuring
    
      uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
      uint8_t high = ADCH; // unlocks both
    
      long result = (high<<8) | low;
    
      result = 1121280L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 (Ref 1.1V = 1.095V)
      return result; // Vcc in millivolts
    }
    
    int calcul_tension_batterie_mV () {  //tout déclaré en int car les valeurs manipulées < 65536
    const int R1_kOhm = 217 ;  //resistance du pont diviseur en kOhm
    const int R2_kOhm = 100 ;    //resistance du pont diviseur en kOhm
    int Vcc = readVcc();
    int UPONT = analogRead (UPont);
    unsigned int result = (UPONT) * Vcc /1024 * (R1_kOhm + R2_kOhm)/R2_kOhm * 1000; //j'ai utilisé "uint16_t" qui d'apres ce que j'ai compris est équivalent a "unsigned int". je ne comprends pas pourquoi ça n'est pas colorisé dans l'éditeur ?
     // int result = (UPONT) * Vcc * 3;
      return result; // UBat en millivolts
    }
    void blinkL13()
    {
    digitalWrite(Led13, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);               // wait for a second
      digitalWrite(Led13, LOW);    // turn the LED off by making the voltage LOW
      delay(1000); 
    }
    void AllumeFrigo()
    {
      PompeOff;
      if (~EtatOnduleur)
      {
        OnduleurOn;
        delay(2000);
      }
      FrigoOn;
      //delay(10000);
    }
    
    void EteintFrigo()
    {
      FrigoOff;
      if (~EtatPompe)
      {
        delay(500);
        OnduleurOff;
      }
    }
      void AllumePompe()
      {
        if (~EtatOnduleur)
        {
          OnduleurOn;
          delay(1000);
        }
        PompeOn;
        delay(5000);
      }
    
      void EteintPompe()
      {
        PompeOff;
        if (~EtatFrigo)
        {
          delay(500);
          OnduleurOff;
        }
      }
    
    
    
    
    
      void setup() {
       #ifdef DEBUG
       Serial.begin(9600);
       #endif
        pinMode (Pompe, 1);
        pinMode (Frigo, 1);
        pinMode (Onduleur, 1);
        pinMode (UPont, 0);
        PORTD |= (1<<Onduleur) | (1<<Pompe) | (1<<Frigo); //Relais ouverts a 1 (fonctionnement des appareil à l'arrêt pour 1)
      } 
    
    
    void loop() {
    long u_mV = calcul_tension_batterie_mV ();
      #ifdef DEBUG
    int  Vcc = readVcc();
    int tension_de_pont = (analogRead (UPont)) * readVcc() /1024;
    
      Serial.print("Vcc = ");
      Serial.print(Vcc);
      Serial.print("   tension_de_pont = ");
      Serial.print(tension_de_pont);
      Serial.print("   u_mV = ");
      Serial.print(u_mV);
      Serial.print("   Onduleur = ");
      Serial.print(EtatOnduleur);
      Serial.print("   Frigo = ");
      Serial.print(EtatFrigo);
      Serial.print("   Pompe = ");
      Serial.println(EtatPompe);
      #endif
      
      blinkL13();
    
      
      if (u_mV > 12600)
      {
        AllumeFrigo();
      }
      if (u_mV < 12000)
      {
        EteintFrigo();
      }
      if (u_mV > 14400)
      {
        AllumePompe();
      }
      if (u_mV < 12600)
      {
        EteintPompe();
      }
    }

  25. #24
    inviteb9f49292

    Re : C et tableau, enum etc..

    Je ne sais pas si ça fonctionne mais en tout cas le code ressemble à quelque chose, tu as pigés le truc je pense.
    Pour pousser le bouchon dans la conception, tes fonctions allumeXXX et eteindYYY appliquent les mêmes algorithmes (allumer éteindre) sur des entités différentes (frigo, pompe), tu aurais intérêt à encapsuler ces différents paramètres dans une structure, et appeler les mêmes fonctions sur différentes instances de ta structure. Dis autrement, transformer ton "AllumePompe()" en "Allume(pompe)".
    C'était l'objet de la "struct equipement_t" de mon précédent poste.
    Un des intérêts de faire ça: le jour ou tu ajoutes un équipement, tu instancies juste ta structure avec des nouveaux paramètres et tu ne changes rien d'autre du code.

  26. #25
    hary

    Re : C et tableau, enum etc..

    Bonjour

    Je reviens de WE où j'utilise le système et disons que pour un premier jet, on peut dire que c'est encourageant.

    J'ai eut des soucis au niveau de mes seuils de tension, mais pour le reste ça fonctionnait plus ou moins comme je le souhaitais !

    Je dois améliorer le système en ajoutant un petit écran LCD et quelques boutons pour pouvoir me donner la possibilité de changer mes tensions au travers d'un menu. (Sans avoir à reprogrammer avec la nécessité d'avoir un PC sous la main).

    Pour tes derniers conseils, je réfléchi et reviens ensuite.

    Je me suis aussi procuré nu livre pour approfondir le C. Malheureusement, les exercices ne sont pas orienté sur les uC et donc pas super motivant pour moi en tout cas. Faire un jeu en 2D ne me stimule guère ! Par contre, gérer des fenêtres pour des projets future... pourquoi pas, mais on verra en temps utile.

    J'ai aussi tenté d’éviter les variables globales, et je dois dire ça m'a foutu un sacré bazars ! Il faudra que je comprenne comment on fait bien et fonctionnel qu'avec des variables locales !

  27. #26
    Jack
    Modérateur

    Re : C et tableau, enum etc..


  28. #27
    hary

    Re : C et tableau, enum etc..

    Je voulais rajouter au concernant les variables locales.

    Le soucis c'est quand on veut vérifier la valeur que prenne ces variables dans le déroulement du programme.

    Si par exemple j'ai une variable intermédiaire dans une fonction et que je veux la controler, je ne sais plus l'afficher dans une procédure de DEBUG si elle est locale !

  29. #28
    inviteb9f49292

    Re : C et tableau, enum etc..

    J'ai aussi tenté d’éviter les variables globales, et je dois dire ça m'a foutu un sacré bazars ! Il faudra que je comprenne comment on fait bien et fonctionnel qu'avec des variables locales!
    Il faut séparer ton problème en sous fonctions, chacune ayant "accès" aux variables dont elles ont besoin en les passant en arguments de la fonction. Ton programme principale ne fait "que distribuer les variables" entre les sous fonctions. Et même le main n'a pas forcément accès à toutes les variables... Tes constantes R1 et R2 du pont diviseur par exemple ne le concerne pas (sauf éventuellement pour pouvoir accéder aux valeurs pour les changer sans recompiler).

    Si par exemple j'ai une variable intermédiaire dans une fonction et que je veux la controler, je ne sais plus l'afficher dans une procédure de DEBUG si elle est locale !
    Le besoin doit guider la conception: tu as besoin d'une fonction te permettant d'afficher ou pas des info, tu peux faire un "printf" débrayable par un 1er argument (en général en "préprocesseur"):
    Code:
    int fonction (int verbosite, ...) {
        if (verbosite) {
             printf ("blah\n");
        }
        ...
    Je me suis aussi procuré nu livre pour approfondir le C. Malheureusement, les exercices ne sont pas orienté sur les uC et donc pas super motivant pour moi en tout cas. Faire un jeu en 2D ne me stimule guère ! Par contre, gérer des fenêtres pour des projets future... pourquoi pas, mais on verra en temps utile.
    Je sors ma casquette de professionnel (je fais du développement embarqué). Je trouve qu'il n'y pas de différence fondamentale entre l'informatique embarquée et le reste... si ce n'est les outils que tu vas utilisés... Tu ne te serviras raisonnablement du C que pour de l'embarqué ou du système (système d'exploitation et leur outils, interpréteurs et autres machines virtuelles), et aujourd'hui tu peux faire de l'embarqué avec du "haut niveau" genre python + raspberry pi sous linux... En revanche tu dois organiser tes programmes dans tous les cas.
    Potasses quand même les exos, en les faisant ces notions fondamentales et bien d'autres (pointeurs etc...) te seront plus familières, tu seras mieux "armé" pour concevoir tes programmes.

  30. #29
    hary

    Re : C et tableau, enum etc..

    Concernant cette fonction

    Code:
    int calcul_tension_batterie_mV () {  //tout déclaré en int car les valeurs manipulées < 65536
    const int R1_kOhm = 217 ;  //resistance du pont diviseur en kOhm
    const int R2_kOhm = 100 ;    //resistance du pont diviseur en kOhm
    int Vcc = readVcc();
    int UPONT = analogRead (UPont);
    long result = (UPONT) * Vcc /1024 * (R1_kOhm + R2_kOhm)/R2_kOhm * 1000; 
      //int result = (UPONT) * Vcc * 3;
      return result; // UBat en millivolts
    }
    J'ai du la remplacer par

    Code:
    //  int calcul_tension_batterie_mV () {  
      const int R1_kOhm = 217 ;  //resistance du pont diviseur en kOhm
      const int R2_kOhm = 86 ;    //resistance du pont diviseur en kOhm 86
      long Vcc = readVcc();
      int UPONT = analogRead (A0);
      float tension_de_pont = UPONT * Vcc /1024;
      float u_mV = tension_de_pont * (R1_kOhm + R2_kOhm)/R2_kOhm;
    directement dans le main() car sinon "u_mV" me donnait des valeurs aberrantes.

    J'ai fait tout un tas de bidouille pour arriver à un résultat cohérent. J'ai remplacé des int par de float ou long.

    je ne vois pas de différences entre long et float qui apparemment sont tous les 2 pour les nombres à virgule ?
    Et j'ai l'impression que le type float est un peu exagéré pour ce que je fait ?

  31. #30
    hary

    Re : C et tableau, enum etc..

    Concernant les exos du livre de C, c'est juste que je préfèrerais faire clignoter des LEDs, lire des capteurs ....

    Heureusement, je viens de terminer un MOOC sur les uC et le C et ce qui m'a plu tout de suite c'est de pouvoir paramétrer des registres et commander les ports avec des masques et des opérations bits à bits !
    Surtout ça me manquait pour pouvoir comprendre d'autre programmes déja fait par d'autres !

    Avec mon Arduino, j'étais un peu bloqué au clan... Arduino! Mais il faut dire que c'est une bon tremplin d'accès je pense.

    Pour l'instant j'ai un peu de mal à saisir l'intérêt de l'embarqué avec OS. A la base, je pensais que l'embarqué étais du sans OS !
    Pour moi, l'adjonction d'un OS ne facilita pas la chose. Je ne suis pas plus à l'aise sous LINUX !

Page 1 sur 2 1 DernièreDernière

Discussions similaires

  1. [PHP] tri d'un tableau et création d'un nouveau tableau
    Par invite8c013b57 dans le forum Programmation et langages, Algorithmique
    Réponses: 2
    Dernier message: 10/02/2014, 23h05
  2. enum vs const vs #define [C embarqué]
    Par invitea0ff9272 dans le forum Électronique
    Réponses: 11
    Dernier message: 04/10/2013, 14h58
  3. Alimentation d'un tableau divisionnaire depuis tableau principal
    Par invite76b29755 dans le forum Bricolage et décoration
    Réponses: 2
    Dernier message: 19/09/2013, 18h22
  4. Ai-je le droit de faire "enum{ VARIABLE = ((unsigned int )( X))};"?
    Par invitee13c535c dans le forum Électronique
    Réponses: 1
    Dernier message: 30/04/2012, 11h42
  5. [Language C] - Aide sur "typedef enum"
    Par invite3c35244f dans le forum Électronique
    Réponses: 5
    Dernier message: 17/11/2009, 11h48