Affichage de la température sur un 4x7 segments
Répondre à la discussion
Affichage des résultats 1 à 29 sur 29

Affichage de la température sur un 4x7 segments



  1. #1
    inviteb6b75063

    Affichage de la température sur un 4x7 segments


    ------

    Bonjour la communauté de futura-sciences
    Je parcours ce forum depuis longtemps mais je n'avais jamais oser m'inscrire, voilà qui est fait
    A mon tour de poser des questions et aussi d'aider à répondre a celle des autres

    Je suis débutant dans la programmation de PIC, j'utilise actuellement un pic16F88 avec un JDM.
    Je programme sur WinXP (vieux PC avec RS232) avec MikroC et WinPIC800.
    Mon petit projet était le suivant : Afficher la température (avec un capteur DS18B20) sur un 4x7 segments.

    Mon problème est le suivant : je dois balayer en permanence le 4x7 segments mais aussi récupérer la température grâce a la liaison serie (One-Wire) du capteur. Celui ci requière un délais pour parfaire sa conversion. J'ai essayé plusieurs chose avec l'interruption TRM0 : 1.Mettre l'affichage dans l'interruption 2. Mettre l'affichage en dehors de l'interruption
    Dans le cas n°1, ça bug complet, le refresh de la température se fait aléatoirement. Dans le cas n°2, le PIC n'est pas assez rapide pour traiter la récupération du la température (sans parler des 300ms d'attente) sans perturber l'affichage.
    Je ne sais comment faire un programme propre, qui fonctionne avec les bon délais etc.

    Je met le schéma du petite montage + le code

    Merci d'avance pour votre aide



    Code:
    unsigned int temp;
    signed long tempinC;
    unsigned short C_Neg=0;
    unsigned int i;
    int  num[5] = {10,10,10,10,10};
    
    
    
    void interrupt() {
         for(i=1;i<5;i++)
     {
        PORTA = (0b00000001 << i);
        switch(num[i]){
                     case 0 : PORTB = 0xC0; break;
                     case 1 : PORTB = 0xF9; break;
                     case 2 : PORTB = 0xA4; break;
                     case 3 : PORTB = 0xB0; break;
                     case 4 : PORTB = 0x99; break;
                     case 5 : PORTB = 0x92; break;
                     case 6 : PORTB = 0x82; break;
                     case 7 : PORTB = 0xF8; break;
                     case 8 : PORTB = 0x80; break;
                     case 9 : PORTB = 0x90; break;
                     case 10 : PORTB = 0xFF; break;
                     case 11 : PORTB = 0xBF; break;
        }
        delay_ms(6);
      }
         INTCON.TMR0IF  = 0;            // On reset le drapeau TMR0IF, on set a 1 le TMR0IE
    }
    
    
    
    
    void DS18B20()
    {
        Ow_Reset(&PORTA, 0);
        Ow_Write(&PORTA, 0, 0xCC);
        Ow_Write(&PORTA, 0, 0x44);
        delay_ms(300);
        Ow_Reset(&PORTA, 0);
        Ow_Write(&PORTA, 0, 0xCC);
        Ow_Write(&PORTA, 0, 0xBE);
        temp = Ow_Read(&PORTA, 0)/*LS_BYTE*/ + (Ow_Read(&PORTA, 0) << 8)/*MS_BYTE*/;
    }
    
    
    void Convert_Temperature() {
    
        if (temp & 0x8000)    // Si negatif
        {
          num[1] = 11;
          temp = ~temp + 1;   //  complément a 2;
        }
        else
        {
           C_Neg = 0;
           num[1] = 10;
        }
        
        tempinC = temp*6.25;
    
        num[2] =  (tempinC/1000)%10;
        num[3] = (tempinC/100)%10 ;
        num[4] = (tempinC/10)%10 ;
    
    
    }
    
    void main() {
         OSCCON = 0b01100110;       // Clock interne a 4Mhz (110)
                                   /* REGISTRE OSCCON OSCILLATOR CONTROL REGISTER
                                   bit 7
                                   bit 6 à bit 4 Frequence de la clock interne
                                                 111 = 8Mhz ;   110 = 4Mhz
                                   bit 3
                                   bit 2
                                   bit 1 à 0   Choix de la clock, ici Clock Interne (10)    */
     /********************************************DEBUT INITIALISATION INTERRUPTION*****************************************************/
          OPTION_REG = 0x83;         // 10000100
                                   /* REGISTRE OPTION_REG
                                     bit 7 RBPU Pull_UP PORT B  Desactivés à 1
                                     bit 6 INTEDG
                                     bit 5 T0CS  TMR0 Clock Source => à 0 sur la clock interne
                                                                      à 1 sur transition RA4/T0CKI/C2OUT
                                     bit 4 T0SE  TMR0 Edge => Utile si T0CS à 1
                                                              à 1 incrementation du timer high to low
                                                              à 0 incrementation du timer low to high
                                     bit 3 PSA    Prescalar assigné a WDT (1) ou Timer0 (0)
                                     bit 2 Prescalar
                                     bit 1 Prescalar
                                     bit 0 Prescalar     */
                                     
        INTCON = 0xA0;             //10100000
                                   /* REGISTRE INTCON
                                   bit 7 GIE  activer interruptions  (set : 1)
                                   bit 6 PEIE
                                   bit 5 TMR0IE activer interruption TMR0     (set : 1)
                                   bit 4 INT0IE
                                   bit 3 RBIE
                                   bit 2 TMR0IF  "drapeau" => a 1 quand overflow  (reset : 0)
                                   bit 1 INT0IF
                                   bit 0 RBIF           */
        /*********************************************FIN INITIALISATION INTERRUPTION******************************************************/
        ANSEL = 0x00;
        TRISA = 0x01;
        TRISB = 0x00;
        PORTA = 0x00;
        PORTB = 0x00;
    
    
       do {
                     DS18B20();
                     Convert_Temperature();
                     delay_ms(1000);
      } while (1);
    }

    -----
    Images attachées Images attachées  

  2. #2
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    oui gérer du one wire par soft c'est délicat.
    sur mon site (clique sur gcortex) j'ai mis des tutoriels one wire.
    Il y en a un qui propose d'utiliser l'uart pour alléger le soft.

    PS : faut oser de brancher l'afficheur direct sur le pic.
    Au minimum 8 résistances et 4 transistors

  3. #3
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    J'ai visité votre site et télécharger le zip sur le one wire.
    Je ne vois pas de programme utilisant l'UART
    Si c'est trop compliqué, pensez-vous qu'il existe une autre solution pour parvenir au même résultat ?
    (je suis novice, je n'ai jamais utilisé l'UART)
    (quatre 7segments séparés avec des registres a décalage ?)

    La question que je me posais en rapport (ou non) avec le "bug" qui se créer : si ma fonction d'interruption est plus longue que le temps entre deux interruptions, que se passe t-il ? Le PIC ne traite plus le main() ? Une espèce de "file d'attente" se créer ?

    PS : D'accord, je sors les transistors

  4. #4
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    dans le doc2579 à partir de la page 3. C'est un périphérique qui gère une liaison asynchrone avec RX et TX et tu peux mettre les 2 signaux ensemble pour faire du one wire.

    Pendant que c'est fait de façon matérielle, tu as plus de temps pour gérer les afficheurs.

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

    Re : Affichage de la température sur un 4x7 segments

    Je suis en train de lire mais je crois que ça dépasse largement mes capacités.
    Si je comprend bien, je peux faire cela grâce au PIC, c'est une séquence de code a part qui s’exécute indépendamment ou presque du reste ?
    J'ai cherché sur internet, mais je ne trouve pas d'explication qui répondent a mes questions. Auriez-vous un site/pdf expliquant cela ? Je vais potasser celui de Bigonoff

    Merci de votre aide

  7. #6
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    Si ton truc marche c'est que tu as les capacités : Moi je n'aurais pas su en faire autant
    Dans la doc de ton pic, tu as normalement un chapitre pour chaque périphérique.

  8. #7
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Bonsoir,

    Pour le DS18B20 en mode 12 bits il faut attendre 750 ms avant de lire le résultat.
    Un petit test, pour voir, consiste à bloquer les IT pendant l'envoi des commandes et la lecture du résultat du DS18B20.
    Code:
    void DS18B20()
    {
        INTCON.GIE =0;
        Ow_Reset(&PORTA, 0);
        Ow_Write(&PORTA, 0, 0xCC);
        Ow_Write(&PORTA, 0, 0x44);
        INTCON.GIE=1;
        delay_ms(750);
        INTCON.GIE =0;
        Ow_Reset(&PORTA, 0);
        Ow_Write(&PORTA, 0, 0xCC);
        Ow_Write(&PORTA, 0, 0xBE);
        temp = Ow_Read(&PORTA, 0)/*LS_BYTE*/ + (Ow_Read(&PORTA, 0) << 8)/*MS_BYTE*/;
        INTCON.GIE =1;
    }
    A+

  9. #8
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Je ne comprend pas pourquoi vous voulez bloquer les interruptions pendant la séquence de communication avec le capteur.
    Si l'overflow ne créer plus d'interruption alors le 4*7segments ne sera plus balayé.
    Je n'ai pas trouvé de réponse pour ma dernière question dans le post #3

    Je ne sais pas si c'est une bonne idée de mettre l'affichage dans l'interruption mais je ne vois pas comment faire autrement...

    La doc conseil 750ms (max) mais chez moi le capteur accepte a tout les coup du 300ms.

  10. #9
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Bonsoir,
    Pourquoi bloquer le IT pendant les échanges avec le DS18B20 : pour éviter si une IT arrive en pleine séquence de lecture (par ex) entraîne une perte de données, donc une valeur
    erronée.
    Il n'y a pas de risque de ne plus rafraîchir les afficheurs, juste un peu de retard.
    Très bien si cela fonctionne avec 300 ms, mais si dans 1 an vous changer de capteur et que celui ci répond en 350 ms, plus rien ne fonctionne et trouver l'erreur risque de ne pas être
    simple.

    A+

  11. #10
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Je comprend bien le but de la manip, et elle marche mais :
    Le problème c'est que les fonctions OneWire mettent du temps a se traiter (normal) et que même sans le delais de 750ms, le 4*7segments est perturbé. Si on arrête l'IT pendant cette sequence => on arrête donc d'afficher pendant 750ms + le temps de traiter la séquence. Ce n'est pas ce que je voudrais ici, je voudrais que le 7seg soit comme dans tout les systèmes : "fixe".

  12. #11
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Bonsoir,

    pendant la tempo de 750 ms les IT ne sont pas bloquées, il faut bloquer avant et après (voir le bout de code dans mon premier message).

    A+

  13. #12
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Excusez moi je n'ai pas vu Je vais essayer ça, merci beaucoup
    Il reste a voir combien de temps la séquence de communication met, voir si ça a le temps de perturber l'afficheur.
    Je creuse la solution de gcortex au cas où ça ne serait pas le cas.

    Avez-vous une idée sur la réponse a la question posé en #3, ça me trottine dans la tête
    Je la remet :

    La question que je me posais en rapport (ou non) avec le "bug" qui se créer : si ma fonction d'interruption est plus longue que le temps entre deux interruptions, que se passe t-il ? Le PIC ne traite plus le main() ? Une espèce de "file d'attente" se créer ?

  14. #13
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Bonsoir,

    Mettre la gestion de l'affichage dans l'IT semble la meilleure solution.
    Quel est le temps calculé entre deux IT ?
    Pour la fonction interruption plus longue que le temps entre deux IT il suffit en début de fonction de bloquer et avant de sortir de la fonction inter de débloquer.
    A+

  15. #14
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    D'accord, donc ce que j'ai commencé convient

    Justement, c'était une de mes questions subsidiaires : j'ai mis un délais de 6ms entre chaque affichage de chiffre, donc a adapté selon les 4x7 segments. Mais le plus important : Quel temps je dois mettre entre deux affichage et donc entre deux interruptions ?
    Actuellement le prescaler est réglé sur 1:16 et le pic tourne a 4Mhz. Si je me trompe pas, ça fait 1µs par cycle donc 16*256
    Soit 4096µs.
    A cette fréquence là, on discerne légèrement le balayage. A voir au niveau de cette fréquence ainsi qu'au délais entre deux nombre.

  16. #15
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    Moi je fais entre 100 et 400 rafraichissements par seconde.

  17. #16
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    et j'm bien utiliser des anodes communes parce que je peux utiliser des collecteurs ouverts (ULN2803), et me brancher avant le régulateur pour avoir un 5V plus stable.
    Et 2 par 2 parce que les afficheurs en plus d'être limités en courant moyen, ils le sont aussi en courant crête.

  18. #17
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Merci a vous deux, les problèmes commencent a partir
    Il en reste un, pas extrêmement grave mais gênant pour les "utilisateurs".
    Le refresh est imperceptible mais on voit légèrement sur les 7 segments ce qui est affiché avant/après lui (selon le code).
    Baisser/augmenter le prescaler pour augmenter/baisser la vitesse de refresh ne change rien.
    Si j'augmente le délais entre l'affichage de chaque chiffre, on voit le balayage... (5ms max), si je baisse, on voit de plus en plus les "ombres". J'ai fais quelque test en tentant d'ajouter des délais d'1ms après la sélection du 7 segments mais rien n'y fait.

    (le 4x7 segments est un PARA LIGHT A-576G, la doc est très maigre, je l'ai récupéré sur un décodeur TNT )

  19. #18
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Bonjour,

    j'ai exhumé une réalisation qui utilise 4 afficheurs et un micro, les valeurs utilisées sont pour un oscillateur 4Mhz :
    * prédiviseur : 1/64 soit un temps entre chaque IT est d'environ 16ms
    * temps alloué à chaque afficheur : 3ms donc une durée IT de 12ms environ.

    Pour le délais de 300 ms il doit être beaucoup plus élevé, en effet à chaque IT le délais est augmenté de la durée de l'IT (24 ms environ).
    A la fin de l'IT il faut peut être remettre le PORTA à 0.

    Il est possible de modifier le programme en n'utilisant pas les IT, on utilise le temps de conversion du DS18B20 (environ 750 ms) pour afficher la valeur sur les 4 afficheurs.

    - commande début conversion
    - affichage
    - lecture résultat

    un petit bout de code :
    Code:
     do {
                     DS18B20();
                    for(j=1;j<60;j++)
                    {
                    for(i=1;i<5;i++)
                   {
                   PORTA = (0b00000001 << i);
                   switch(num[i]){
                     case 0 : PORTB = 0xC0; break;
                     case 1 : PORTB = 0xF9; break;
                     case 2 : PORTB = 0xA4; break;
                     case 3 : PORTB = 0xB0; break;
                     case 4 : PORTB = 0x99; break;
                     case 5 : PORTB = 0x92; break;
                     case 6 : PORTB = 0x82; break;
                     case 7 : PORTB = 0xF8; break;
                     case 8 : PORTB = 0x80; break;
                     case 9 : PORTB = 0x90; break;
                     case 10 : PORTB = 0xFF; break;
                     case 11 : PORTB = 0xBF; break;
                     }
                 delay_ms(3);
                 }
                 }
                 PORTA=0;
                     Convert_Temperature();
                     
      } while (1);

  20. #19
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Merci d'avoir pris le temps "d'exhumé votre ancien projet"

    J'ai noter les informations mais je n'ai pas compris deux lignes :

    "Pour le délais de 300 ms il doit être beaucoup plus élevé, en effet à chaque IT le délais est augmenté de la durée de l'IT (24 ms environ).

    A la fin de l'IT il faut peut être remettre le PORTA à 0."

    Le delais de 300ms, vous parlez de celui du capteur ? "
    à chaque IT" ? Le délais est augmenter de la durée du code de l'IT a chaque fois qu'elle est traité ???? Là je ne comprend plus

  21. #20
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Bonjour,

    Pour le pb de rémanence une petite modif de code au niveau de l'IT.
    Code:
    void interrupt() {
         for(i=1;i<5;i++)
     {
       
        switch(num[i]){
                     case 0 : PORTB = 0xC0; break;
                     case 1 : PORTB = 0xF9; break;
                     case 2 : PORTB = 0xA4; break;
                     case 3 : PORTB = 0xB0; break;
                     case 4 : PORTB = 0x99; break;
                     case 5 : PORTB = 0x92; break;
                     case 6 : PORTB = 0x82; break;
                     case 7 : PORTB = 0xF8; break;
                     case 8 : PORTB = 0x80; break;
                     case 9 : PORTB = 0x90; break;
                     case 10 : PORTB = 0xFF; break;
                     case 11 : PORTB = 0xBF; break;
        }
     PORTA = (0b00000001 << i);
        delay_ms(6);
     PORTA = 0;
      }
         INTCON.TMR0IF  = 0;            // On reset le drapeau TMR0IF, on set a 1 le TMR0IE
    }
    Oui c'est la fonction "delay_ms(300);" à chaque IT elle est inactive pendant l'IT (24 ms) donc la durée totale est T = 300ms + (nombre d'IT * 24 ms)

    A+

  22. #21
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Avec toutes vos recommandations l'affichage se fait parfaitement bien Le rémanence (j'avais le mot sous le bout de la langue) est presque absente. (On voit si on cherche la petite bête). Je vais aller acheter des transistors PNP et sortir le weller

  23. #22
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Par contre : il est normal que les délais ne soit plus vrai dans le main() a cause de l'interruption, comment faites-vous pour calculer le nombre de cycle que prend une séquence de code quelconque ? Avec vous un logiciel ? (avec système probabilité ou je sais pas trop quoi) où comptez vous a la main ?

    Il faudrait aussi (vu que les températures sont autour de 20°C) mettre des numéros avant les autres pour éviter que le PIC parcours tout les sélects case a chaque fois. C'est peu être une idée bête vu que tout les numéros apparaissent sur une température (en gros de 15°C à 25°C)

  24. #23
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Très bien et bon courage pour la suite.
    Juste pour info au lieu d'écrire :
    Code:
    TRISA = 0x01;
        TRISB = 0x00;
        PORTA = 0x00;
        PORTB = 0x00;
    Ecrire :
    Code:
        PORTA = 0x00;
        PORTB = 0x00;
        TRISA = 0x01;
        TRISB = 0x00;
    cela évite des niveaux indéterminés, certes pendant un temps très court mais cela peu entraîner dans certains cas des pb.
    A+

  25. #24
    invite11398957

    Re : Affichage de la température sur un 4x7 segments

    Pour éviter l'utilisation de select case dans xc8 j'utilise ceci :

    Code:
    unsigned char const table_aff[]={0x3f,0x06,0x5b,0x4f,0x66,
                                0x6d,0x7d,0x07,0x7f,0x6f};
        long unite,diz;
        long cp = 0;
        unite = val/10;
        diz = val%10;
        for(cp=0;cp<5; cp++)
        {
            PORTB = table_aff[unite];
    Je ne sais pas si cela est possible dans mikroC ?
    Il est très rare de calculer le nombre de cycles dans un programme.

  26. #25
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Je vais essayer ceci, merci. C'est possible, je l'ai vu sur d'autres topics concernant MikroC.
    Oui, je viens de comprendre pourquoi ça ne servait a rien. Seul le délais est important (ce que vous m'avez dit plus haut) et le le temps de traitement du reste du code est négligeable. Oui je suis bête pour le TRISA & PORTA, en plus l'initialisation est clairement marqué dans la doc

  27. #26
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    Voici le schéma que j'ai réaliser. (j'ai essayé avec les PNP d'origine, je n'ai pas pu y arriver) (c'est un afficheur a anode commune)
    Nom : Sans titre.PNG
Affichages : 257
Taille : 48,6 Ko

  28. #27
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    là tu peux virer les 4 résistances de base et brancher les collecteurs sur du 6V (pas plus sinon les 2222 vont cramer)
    Dernière modification par gcortex ; 14/02/2015 à 17h48.

  29. #28
    inviteb6b75063

    Re : Affichage de la température sur un 4x7 segments

    D'accord. C'est que partout où je vais je vois du PNP, j'ai pris ceux d'origine de la carte mais impossible d'obtenir un bon résultat /:
    J'ai donc pris des 2N2222, je ne savais pas si les brancher comme ça allait.

  30. #29
    gcortex

    Re : Affichage de la température sur un 4x7 segments

    Tu auras 4,3V sur les émetteurs, mais il faut vérifier qu'ils vont dissiper la puissance.

Discussions similaires

  1. Affichage 7 segments multiple
    Par invitefed784c6 dans le forum Électronique
    Réponses: 15
    Dernier message: 06/12/2011, 13h34
  2. affichage 7 segments instable
    Par invite5396f733 dans le forum Électronique
    Réponses: 5
    Dernier message: 30/08/2011, 14h03
  3. Affichage LCD 7 segments et plus
    Par invite310b3b4c dans le forum Électronique
    Réponses: 1
    Dernier message: 21/12/2008, 20h04
  4. alteration des segments de l'affichage
    Par invite01561354 dans le forum Électronique
    Réponses: 1
    Dernier message: 19/11/2008, 14h08
  5. affichage 7 segments
    Par invitee63d8d03 dans le forum Électronique
    Réponses: 6
    Dernier message: 12/12/2007, 00h56
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...