[P18f4520] Problème fonction "if...else"
Répondre à la discussion
Affichage des résultats 1 à 22 sur 22

[P18f4520] Problème fonction "if...else"



  1. #1
    invite8d0b7120

    [P18f4520] Problème fonction "if...else"


    ------

    Bonjour à tous,

    Je dispose d'une carte picdem 2+ et d'un p18f4520. J'utilise ce matériel pour piloter une pompe et des électrovannes dans le but de réguler la pression dans les coussins d'un matelas (cycle gonflage dégonflage).

    Des capteurs de flexion sont installés sur les matelas et l'ordre de gonfler/dégonfler est donné selon la valeur en tension qu'ils fournissent.

    Pour l'instant je fais le test sur 2 coussins. Lorsque j'agis sur un seul d'entre eux (aucune instruction pour l'autre), tout marche nickel. Par contre, lorsque je rentre des instructions pour les 2, seul l'instruction pour le 2ème coussin fonctionne.

    Je pense savoir pourquoi mais je ne sais pas trop quelle autre structure condition utiliser pour palier à ce problème.

    Voici mon programme :

    Code:
    #include <p18cxxx.H>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <adc.h>
    #include <string.h>
    #include "ftoa.c"
    #define q 4.8828e-3 
    
    //Déclaration des variables
    char string1[30];
    char string2[30];
    
    float Sortie_Capteur1;
    float Sortie_Capteur2;
    
    void main (void)
    {
    
    TRISAbits.TRISA0=0; 
    PORTAbits.RA0=0;//Commande de la pompe (0 = arrêt, 1 = marche)
    	
    TRISD=0;
    
    PORTD=0;
    
    
    
    
    /* Configuration du module ADC */
    		
    		ADCON1 = 0b00001000;	// Vref+ = +Vdd & Vref+ = -Vdd 
    		ADCON2 = 0b10101011;	// Right justify result, Set Acq Time 12 Tad & Conversion clock Fosc/16
    
    			
    while(1){
    
    		ADCON0 = 0b00000101;	// Select AN1
    		Delay100TCYx(20); 		  
    		ADCON0bits.GO = 1;		// Start acquisition
    		Delay100TCYx(20);
    		while (ADCON0bits.GO == 1)	
    		{}
    
    		Sortie_Capteur1 = ADRES;        		
    
    		ftoa(Sortie_Capteur1*q, string1,0,'f');
    			
    
    		ADCON0 = 0b00001001;	// Select AN2
    		Delay100TCYx(20); 		  
    		ADCON0bits.GO = 1;		// Start acquisition
    		Delay100TCYx(20);
    		while (ADCON0bits.GO == 1)
    		{}
    
    
    		Sortie_Capteur2 = ADRES;
    
    		
    		ftoa(Sortie_Capteur2*q, string2,0,'f');
    
    		/* Régulation */
    
                             if (Sortie_Capteur1*q < 3.8)
     		{
    		PORTD=0b0100 // Vanne coussin 1 ouverte
    	             PORTAbits.RA0=1; //Activation pompe
                                                                                                                                      }
    		else
    		{
    	              PORTD=0; // Vannes fermées
    	              PORTAbits.RA0=0; //Désactivation pompe
    
    		}[/
    		if (Sortie_Capteur2*q < 2.5)
     		{
    		PORTD=0b010000 // Vanne coussin 2 ouverte
    	             PORTAbits.RA0=1; //Activation pompe
                                                                                                                                      }
    		else
    		{
    	              PORTD=0; // Vannes fermées
    	              PORTAbits.RA0=0; //Désactivation pompe
    
    		}
    Le souci doit venir du "else"...

    Voila si quelqu'un a une autre approche à me proposer je suis preneur

    Cordialement

    -----

  2. #2
    Seb.26

    Re : [P18f4520] Problème fonction "if...else"

    Evite de travailler en flottant, c'est pas un Core 2 Duo, mais un PIC ... ...

    Sinon, pour ton problème, travaille avec des masques pour PortD, sinon ça peut pas marcher ... le 2nd if 'écrase' le PortD du 1er ...

    Ou alors, utilise RD2 et RD4.

    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  3. #3
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Bonjour, merci de ta réponse.

    Citation Envoyé par Seb.26 Voir le message
    Evite de travailler en flottant, c'est pas un Core 2 Duo, mais un PIC ... ...
    Je n'ai pas compris ce que tu voulais dire .

    Par rapport aux masques, je vais regarder comment ça fonctionne je m'en rappelle plus trop.

    Cordialement.

  4. #4
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Tu pourrais m'aiguiller un peu plus sur les masques? (je ne demande pas de réponse toute faite, juste d'être mis sur la bonne voie =)....).

    Cordialement.

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

    Re : [P18f4520] Problème fonction "if...else"

    Code:
                    /* Régulation */
    		if (Sortie_Capteur2*q < 2.5)
    			{
    			PORTD=0b010000 // Vanne coussin 2 ouverte
    	                PORTAbits.RA0=1; //Activation pompe
    			}
    		else
    			{
    			//Désactivation pompe
    			if (Sortie_Capteur1*q < 3.8)
    				{
    				PORTD=0b0100 // Vanne coussin 1 ouverte
    	                        PORTAbits.RA0=1; //Activation pompe
    				}
    			else
    				{
    				PORTD=0; // Vannes fermées
    	                        PORTAbits.RA0=0; //Désactivation pompe
    				}
                           }

  7. #6
    sdec25

    Re : [P18f4520] Problème fonction "if...else"

    Bonjour,
    Quand on travaille au niveau des bits il y a plusieurs solutions :
    1) Utiliser des structures (LATDbits en est une, qui permet de manipuler les bits 1 par 1. Si besoin on peut créer une structure pour manipuler plusieurs bits du registre)
    2) Utiliser les opérateurs bit à bit du langage C : http://www.bien-programmer.fr/bits.htm
    3) Utiliser de l'assembleur (voir datasheet, bit oriented instructions)

    PS : Toujours utiliser LAT au lieu de PORT quand on travaille en sortie, ça évite pas mal de problèmes (cf recherche sur le forum).
    Dernière modification par sdec25 ; 25/05/2010 à 13h14.

  8. #7
    Seb.26

    Re : [P18f4520] Problème fonction "if...else"

    Pour les masques :

    Code:
    PORTD |= 0x04; // mettre un bit à 1
    PORTD &= ~0x04; // mettre un bit à 0


    Mais le plus simple AMA, c'est d'utiliser PORTDbits.RD0 ( comme tu as fait pour PORTAbits.RA0 )

    @+
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  9. #8
    Seb.26

    Re : [P18f4520] Problème fonction "if...else"

    Citation Envoyé par Madje55 Voir le message
    Je n'ai pas compris ce que tu voulais dire .
    Faire des calculs en flottant ("float" et "double") sur un uCPU, c'est un peu jeter les cycles CPU par la fenêtre ... surtout quand on peut éviter ...

    Dans ton cas, tu peux tout à fait faire ta comparaison sans utiliser de float ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  10. #9
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    @freepicbasic: ça fonctionne... je me sens tout con là, je venais de faire ça, mais ta solution est beaucoup plus simple.

    Code:
    	             if (Sortie_Capteur1*q < 3.9)
     		{
    		a=1;
    	             }                     
    
    		if (Sortie_Capteur2*q < 2.7)
     		{
                              a=2;
    		}
    
    		if ((Sortie_Capteur1*q < 3.7 || Sortie_Capteur2*q < 2.6))
     		{
    		PORTAbits.RA0=1;
    		switch (a)
    		{
    			case 1: PORTD=0b0100;
    			break;
    
    			case 2: PORTD=0b010000;
    			break;
    
    		}		
    	             }                     
    		else
    		{
    			PORTB=0;
    			PORTD=0;
    			PORTAbits.RA0=0;
    
    		}
    @sdec: Compris, merci pour les infos, je vais me plonger dans la datasheet du pic pour y voir plus clair.

    Merci bien à vous.

    EDIT: Seb, je viens de voir ta réponse , merci.

  11. #10
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Re...

    J'ai encore un petit souci...

    Les 2 vannes n'arrivent pas à s'ouvrir simultanément (la vanne 2 s'active toujours dans tous les cas). C'est assez gênant car la j'ai posé un sac sur le coussin et les capteurs sont donc sollicités en permanence... Cependant le gonflage ne suit pas.

    Comment puis-je régler ce problème?

    J'ai remplacé les instructions de commande PORT par LAT, mais rien n'y fait. Il me semble que LAT sert juste à garder en mémoire la valeur de la sortie quel que soit l'état dans lequel est défini le port (entrée ou sortie).

    Merci d'avance.

  12. #11
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Bon j'ai temporairement résolu le problème avec l'instruction suivant au sein de la boucle de régulation.

    Code:
    if ((Sortie_Capteur1*q < 3.9 && Sortie_Capteur2*q < 2.7))
    		{
    			PORTD=0b010100;
    		}
    Mais sachant que mon objectif est de réguler 8 coussins, je recherche une solution plus... élégante .

  13. #12
    sdec25

    Re : [P18f4520] Problème fonction "if...else"

    Tous les éléments t'ont été donnés : utiliser des masques ou la structure PORTD ou LATD :
    Code:
    #define VANNE1 LATDbits.LATD2
    #define VANNE2 LATDbits.LATD4
    if (Sortie_Capteur1*q < 3.9) {
    VANNE1 = 1;
    }
    else {
    VANNE1 = 0;
    }
    // idem pour VANNE2
    ou + court:
    Code:
    VANNE1 = (Sortie_Capteur1*q < 3.9) ? 1 : 0;
    VANNE2 = (Sortie_Capteur1*q < 2.7) ? 1 : 0;

  14. #13
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    En fait mon problème ne vient pas de la manipulation des bits mais plutôt de la structure.

    Je pense ne pas devoir utiliser l'opérateur OU, sinon seul un capteur sera activé à la fois, ce que je ne veux pas.

    Utiliser un opérateur ET pour le cas particulier où les 2 capteurs sont activés est possible vu que je n'ai que 2 capteurs pour l'instant, mais je me vois mal réécrire cette condition pour tous les cas possibles lorsque j'aurais 8 capteurs.

    EDIT:VANNE1 = (Sortie_Capteur1*q < 3.9) ? 1 : 0;
    Tiens je ne connaissais pas cette façon d'écrire la condition "if" .

  15. #14
    sdec25

    Re : [P18f4520] Problème fonction "if...else"

    Je ne comprends pas ton problème.
    As-tu modifié ton code depuis le post 9 ?
    Si oui, montre le nous.
    Si non, il serait temps de le refaire

    Je pense ne pas devoir utiliser l'opérateur OU, sinon seul un capteur sera activé à la fois, ce que je ne veux pas.
    Tu peux être plus clair ?

  16. #15
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Bonjour,

    Oui j'ai modifié mon programme:


    Code:
    		if (Sortie_Capteur2*q < 2.7)
     		{
                              a=2;
    		}
    
    		if (Sortie_Capteur1*q < 3.9)
     		{
    		a=1;
    		}                     
    
    		if ((Sortie_Capteur1*q < 3.7 || Sortie_Capteur2*q < 2.5))
     		{
    		PORTAbits.RA0=1;
    		switch (a)
    		{
    			case 1: LATDbits.LATD2=1;
    			break;
    
    			case 2: LATDbits.LATD4=1;
    			break;
    		}	
    
    		if ((Sortie_Capteur1*q < 3.7 && Sortie_Capteur2*q < 2.5))
    		{
    			LATDbits.LATD2=1;
                                           LATDbits.LATD4=1;
    		}	
    	             }                     
    		else
    		{
    			PORTB=0;
    			PORTD=0;
    			PORTAbits.RA0=0;
    		}
    Il fonctionne, tout comme celui de freepicbasic mais j'ai préféré garder cette forme, je pense que ce sera plus lisible avec 8 capteurs (il y aura moins de "if else" imbriqués).

    J'explique mon problème.

    Au début j'avais le programme, sans la partie en gras, à savoir:
    Si le capteur 1 OU le capteur 2 est activé, on active la pompe, puis on ouvre la vanne 1 OU 2.

    J'ai posé un sac sur le matelas (les 2 capteurs sont activés), et donc seule une vanne s'activait à la fois, alors que j'aimerais que lorsque les 2 le soient lorsque les 2 capteurs sont sollicités.

    J'ai donc rajouté la partie en gras pour créer cette condition.

    Sachant que je compte mettre 8 capteurs, je ne peux pas créer une telle condition pour tous les cas. J'en aurais beaucoup trop.

    Ex:
    Si capteurs 1 ET 2 activés, activer vannes 1 ET 2...
    Si capteurs 3 ET 4 activés, activer vannes 3 ET 4...
    Si capteurs 1 ET 8 activés, activer vannes 1 ET 8...
    Si capteurs 1, 3 ET 7 activés, activer vannes 1,3 ET 7...
    etc... etc...

    Voila c'est un peu touffu mais j'espère m'être fait comprendre

  17. #16
    RISC

    Re : [P18f4520] Problème fonction "if...else"

    Salut,

    Il faut utiliser LATx partout ou tu manipules un bit en SORTIE.
    C'est une précaution indispensable si 2 instructions qui se suivent manipule un bit différent sur le même port....
    Donc remplace également PORTAbits.RAx par LATAbits.LATAx.

    D'après tes tests ci-dessus, il y aurait des méthodes plus rapides et plus simples pour éviter de refaire plusieurs fois des comparaisons de nombres flottants qui vont mettre à plat ton PIC18....(il n'a pas de coprocesseur à virgule flottante lui....).

    a+

  18. #17
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    C'est fait, mais j'ai toujours le même problème...

  19. #18
    sdec25

    Re : [P18f4520] Problème fonction "if...else"

    Ce que j'ai compris :
    Vanne1 active si capteur1<3.9
    Vanne2 active si capteur2<2.7
    Vanne3 active si capteur3<X
    ...

    Si c'est le cas, tu peux le faire avec des tests sans if :
    Code:
    VANNE1 = (Sortie_Capteur1*q < 3.9) ? 1 : 0;
    VANNE2 = (Sortie_Capteur1*q < 2.7) ? 1 : 0;
    Si tu ne veux pas des tests sans if :
    Code:
    if (capteur1<3.9) {
    LATAbits.LATA0 = 1;
    VANNE1 = 1
    }
    else VANNE1 = 0;
    if (capteur2<2.7) {
    LATAbits.LATA0 = 1;
    VANNE2 = 1;
    else VANNE2 = 0;
    ...
    PS : doit-on obligatoirement activer RA0 avant les vannes ?
    Dernière modification par sdec25 ; 26/05/2010 à 19h34.

  20. #19
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Bonjour,

    Non on ne doit pas obligatoirement activer la pompe (RA0) avant les vannes, mais ça permet de ne mettre cette instruction qu'une fois, avant de choisir les vannes à activer.

    Ca pourrait changer quelque chose?

  21. #20
    invite8d0b7120

    Re : [P18f4520] Problème fonction "if...else"

    Bon j'ai fait au plus simple:

    Code:
       POMPE = ((Sortie_Capteur1*q < 3.8)|| (Sortie_Capteur2*q < 2.6)) ? 1 : 0;
    		EV1 = (Sortie_Capteur1*q < 3.8) ? 1 : 0;
    		
    		EV2 = (Sortie_Capteur2*q < 2.6) ? 1 : 0;
    ça fonctionne mais je ne comprends pas pourquoi il ne m'activait qu'une vanne à la fois dans mon programme précédent...

    PS: Y a-t-il un moyen de voir le %age d'utilisation du microprocesseur? (à la façon du gestionnaire des tâches pour pc).

    Merci bien en tout cas.

  22. #21
    Seb.26

    Re : [P18f4520] Problème fonction "if...else"

    Citation Envoyé par Madje55 Voir le message
    PS: Y a-t-il un moyen de voir le %age d'utilisation du microprocesseur? (à la façon du gestionnaire des tâches pour pc).
    ...
    ... Ton CPU est toujours à 100% ou endormi.

    ... Par contre, tu peux regarder le temps qu'il faut pour faire un tour de ta boucle sans fin ... ce qui te donnera la granularité de ton temps réel

    Tu peux inverser un bit de debug à chaque tour, et voir le temps nécessaire à tout tes calculs en float ... et pleurer ...
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  23. #22
    sdec25

    Re : [P18f4520] Problème fonction "if...else"

    Citation Envoyé par Madje55 Voir le message
    ça fonctionne mais je ne comprends pas pourquoi il ne m'activait qu'une vanne à la fois dans mon programme précédent...
    Ton ancien programme était plutôt compliqué pour ce qu'il devait faire, pas étonnant qu'il ne fonctionnait pas.
    Sinon tu peux faire :
    Code:
    POMPE = VANNE1 || VANNE2 || ... ;
    Ça évite de refaire les calculs.

Discussions similaires

  1. question de définition entre "fonction" et "application linéaire"
    Par invite00c17237 dans le forum Mathématiques du supérieur
    Réponses: 3
    Dernier message: 19/02/2009, 15h52
  2. Problème avec pic16f84 fonction "delay_ms()"
    Par Montd'est dans le forum Électronique
    Réponses: 2
    Dernier message: 15/06/2008, 00h36
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...