Répondre à la discussion
Affichage des résultats 1 à 19 sur 19

USB/PIC18F4550: PB rebond interrupteur



  1. #1
    tiamat

    USB/PIC18F4550: PB rebond interrupteur


    ------

    Bonjour à tous,

    j'ai réalisé une carte d'interface USB (en CDC) avec mon PC. Cette carte fonctionne bien mais j'ai quelques soucis de rebond lorsque j'ai besoin de remonter l'état des interrupteurs connectés aux sorties de mon PIC.

    j'ai donc deux interrupteurs et deux Leds connectés aux sorties du PIC:
    Code:
    #define LED1 PORTCbits.RC0
    #define LED2 PORTCbits.RC1
    
    #define BOUTON1 PORTDbits.RD0
    #define INTERR1 PORTDbits.RD1
    j'ai récupéré la stack USB de Microchip pour commencer mon projet, et voici donc la partie ProcessIO() qui est exécutée en while(1):

    Code:
    void ProcessIO(void)
    {
        if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
    	CheckSensors();
    	ServiceRequests();
    
    }//end ProcessIO
    
    void ServiceRequests(void)
    {
    
      	if(getsUSBUSART(input_buffer,6)){
    		switch(input_buffer[1]){
    			
    			//LED1
    			case REQ_LED1:
    				LED1 = !LED1;		
    				if(mUSBUSARTIsTxTrfReady()){
    					if(LED1 == 1)
    		        			putrsUSBUSART("LED1_ON\n");
    					else
    						putrsUSBUSART("LED1_OFF\n");
    				     }
    				break;
    			//LED2
    			case REQ_LED2:
    				LED2 = !LED2;		
    				if(mUSBUSARTIsTxTrfReady()){
    					if(LED2 == 1)
    		        			putrsUSBUSART("LED2_ON\n");
    					else
    						putrsUSBUSART("LED2_OFF\n");
    				     }
    				break;
    et voici la fonction CheckSensors() qui va renvoyer au PC l'état des deux interrupteurs:
    Code:
    //dans init
     old_sw2 = INTERR1;
    ....
    void CheckSensors(void){
    	//Bouton Poussoir
    	if(BOUTON1 == 1){
    		if(mUSBUSARTIsTxTrfReady()){
           		putrsUSBUSART("BOUTON1_PRESSED\r\n");
    	   	}
    		Delay10KTCYx(0);
    		Delay10KTCYx(0);
    	}
    	//Bouton ON/OFF
    	if(INTERR1 != old_sw2){
    		old_sw2 = INTERR1;
    		if(mUSBUSARTIsTxTrfReady() & INTERR1==0){
           		putrsUSBUSART("BOUTON2_ON\r\n");
    	   	}
    		else if(mUSBUSARTIsTxTrfReady() & INTERR1==1){
           		putrsUSBUSART("BOUTON2_OFF\r\n");
    	   	}
    		Delay10KTCYx(0);
    		Delay10KTCYx(0);
    	}
    
    }
    donc j'ai une question à ce sujet.... l'information d'état de BOUTON1 pressed m'est remontée quasiment en permanence, je dois le recevoir une bonne centaine de fois par minute, alors que je n'ai besoin de l'info qu'une fois...j'ai tenté de mettre des delay mais à priori ce n'est pas la bonne méthode...
    l'information pour BOUTON2 (ON, OFF) est également erronée remonte au PC plusieurs fois comme précisé pour le BOUTON1.
    Pourriez vous m'aider à traiter ce problème de rebond sur mes retours capteurs ?

    par contre je recontre également quelques problèmes de stabilité avec la com, et je me demandais s'il ne vallait pas mieux réorienter mon projet vers une stack USB en HID plutot qu'en simulation de port de COM. qu'en pensez vous ?

    Merci pour votre aide.
    Tiamat.

    -----

  2. #2
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    Pour le traitement des rebonds, regarde la pièce jointe.

    Bonne lecture

  3. #3
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    Merci Jack,

    j'ai bien lu ton doc qui est intéressant, ça m'a donné quelques conseils sur une implémentation d'un anti rebond soft.
    Par contre je me rend compte que les données que je reçois sont incohérentes...

    je reçois des changements d'état fréquents sans rien toucher au niveau de mes interrupteurs....:
    Code:
    BOUTON2_OFF
    BOUTON2_ON
    BOUTON2_OFF
    BOUTON2_ON
    BOUTON2_OFF
    BOUTON1_PRESS
    BOUTON1_PRESS
    BOUTON2_OFF
    BOUTON2_ON
    BOUTON2_OFF
    BOUTON2_ON
    BOUTON2_OFF
    j'ai un interrupteur par sortie du PIC, en série avec une résistance de 1kOhm....connecté à la masse donc rien de bien compliqué normalement !

    je me demande si je n'ai pas oublié quelque chose sur ma platine, parce que les données remontées ne sont pas cohérentes du tout !

    qu'en pensez vous ?

  4. #4
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    j'ai un interrupteur par sortie du PIC, en série avec une résistance de 1kOhm....connecté à la masse donc rien de bien compliqué normalement !
    Un interrupteur sur une sortie ??? Tu veux dire sur une entrée j'espère.

    Lorsque tu appuieras sur l'inter, tu auras donc un beau '0'. Et lorsque l'interrupteur est ouvert quel est l'état arrivant sur cette entrée à ton avis?

    A+

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

    Re : USB/PIC18F4550: PB rebond interrupteur

    oui oui ce sont des entrées...
    les deux Tris correspondants sonc D0 et D1:
    Code:
    #pragma code
    void UserInit(void)
    {
    	ADCON1 = 0x0E ;
    	TRISC = 252;
    	TRISDbits.TRISD0 = 1;
    	TRISDbits.TRISD1 = 1;
    	BOUTON1 = 1;
    	INTERR1 = 1;
    	PORTC = 1;
            prev_switch2_state = INTERR1;
    	old_Bouton1 = BOUTON1;
    	LED1 = 0;
    	LED2 = 0;
    }//end UserInit
    par contre j'ai effectivement un doute sur l'init de BOUTON1 et INTERR1, si ils sont tous les deux à la masse si ils sont actionnés j'aurais donc 0 sur l'entrée.

    c'est bien ça ?

  7. #6
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    Ca ne répond pas à ma question:
    Et lorsque l'interrupteur est ouvert quel est l'état arrivant sur cette entrée à ton avis?
    A moins que le pic possède des pull ups et que tu les aies activées.

    A+

  8. #7
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    à l'etat bas (non actionné) l'interrupteur est à 1, si on actionne l'interrupteur il passe à 0.
    à savoir que j'ai deux types de boutons, un bouton poussoir ou cette règle s'applique, et un autre interrupteur ou là par contre selon la selection de l'interrupteur je passe soit à 1 soit à 0.
    enfin c'est ce que je pense ! mais j'ai tenté d'inverser l'init des sorties (de 0 à 1) mais ça ne change rien, j'obtiens toujours beaucoup trop d'acquisition et surtout pas forcément correctes.

    penses tu que cela peut provenir d'un probleme de conf ? ou manque t'il quelque chose au niveau composant ? j'ai regardé les composant anti-rebond, mais j'aurais préféré le faire en soft, tout en évitant des boucles d'attente sur le PIC qui me bloquent le temps machine...

  9. #8
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    Mais tu parles de 1 et de 0, mais qu'est-ce qui te garantit que tu as un 1? Tu as mesuré? Je rpose la question: as-tu une pull up quelque part pour garantir ton état haut?

    A+

  10. #9
    pierr0t

    Re : USB/PIC18F4550: PB rebond interrupteur

    Salut,

    Ca peut peut etre t'aider,
    j'ai ecris ce code pour un clavier matriciel.
    Y a un anti rebond ds la fonction DRVKbdScanKeys()
    Cette fonction est appelée sur timer du coup pas de boucle
    d'attente. Ca ne consomme que le temps nécessaire a l'exécution.

    C'est pas du code optimal mais ca tourne.

    Code:
    #include "DRV_KBD.h"
    
    //       Keyboard Matrix
    //                      Input_F       PORTB3
    //              F E D   Input_E       PORTB4 
    //              ^ ^ ^   Input_D       PORTB5 
    //              | | |    
    //          K-> 1 2 3   Output_K      PORTC5 
    //          J-> 4 5 6   Output_J      PORTB0 
    //          H-> 7 8 9   Output_H      PORTB1 
    //          G-> * 0 #   Output_G      PORTB2 
    //                       
                           
    static U8  KeyCount[2][cNumberOfKeys];
    static U16 KeyPressed;
    static U16 KeyReleased;
    static U8 LocalCounter;
                            
    void DRVKbdinit(void)
    {
        DDRC  |=  (1<<PORTC5); // Output_K
        DDRB  |=  (1<<PORTB0); // Output_J
        DDRB  |=  (1<<PORTB1); // Output_H
        DDRB  |=  (1<<PORTB2); // Output_G
                                
        
        DDRB  &= ~(1<<PORTB3); // Input_F
        DDRB  &= ~(1<<PORTB4); // Input_E
        DDRB  &= ~(1<<PORTB5); // Input_D
                                   
        
        PORTB &= ~(1<<PORTB3); // Input_F
        PORTB &= ~(1<<PORTB4); // Input_E
        PORTB &= ~(1<<PORTB5); // Input_D
                                   
    }
    
    
    static void DRVKbdScanKeys(void)
    {    
        PORTC |=  (1<<PORTC5);
        mLibNop();
        if((PINB >> PORTB3) & 0x01) KeyCount[cKeyPressed][cKey_01] += 1  ; // F
        else if (KeyPressed & (1<<cKey_01)) KeyCount[cKeyReleased][cKey_01] += 1  ;
        if((PINB >> PORTB4) & 0x01) KeyCount[cKeyPressed][cKey_02] += 1  ; // E
        else if (KeyPressed & (1<<cKey_02)) KeyCount[cKeyReleased][cKey_02] += 1  ;
        if((PINB >> PORTB5) & 0x01) KeyCount[cKeyPressed][cKey_03] += 1  ; // D
        else if (KeyPressed & (1<<cKey_03)) KeyCount[cKeyReleased][cKey_03] += 1  ;
        PORTC &= ~(1<<PORTC5);  
    
        mLibNop();
    
        PORTB |=  (1<<PORTB0);
        mLibNop();
        if((PINB >> PORTB3) & 0x01) KeyCount[cKeyPressed][cKey_04] += 1  ; // F
        else if (KeyPressed & (1<<cKey_04)) KeyCount[cKeyReleased][cKey_04] += 1  ;
        if((PINB >> PORTB4) & 0x01) KeyCount[cKeyPressed][cKey_05] += 1  ; // E
        else if (KeyPressed & (1<<cKey_05)) KeyCount[cKeyReleased][cKey_05] += 1  ;
        if((PINB >> PORTB5) & 0x01) KeyCount[cKeyPressed][cKey_06] += 1  ; // D
        else if (KeyPressed & (1<<cKey_06)) KeyCount[cKeyReleased][cKey_06] += 1  ;
        PORTB &= ~(1<<PORTB0);            
    
        mLibNop();
    
        PORTB |=  (1<<PORTB1);
        mLibNop();
        if((PINB >> PORTB3) & 0x01) KeyCount[cKeyPressed][cKey_07] += 1  ; // F
        else if (KeyPressed & (1<<cKey_07)) KeyCount[cKeyReleased][cKey_07] += 1  ;
        if((PINB >> PORTB4) & 0x01) KeyCount[cKeyPressed][cKey_08] += 1  ; // E
        else if (KeyPressed & (1<<cKey_08)) KeyCount[cKeyReleased][cKey_08] += 1  ;
        if((PINB >> PORTB5) & 0x01) KeyCount[cKeyPressed][cKey_09] += 1  ; // D
        else if (KeyPressed & (1<<cKey_09)) KeyCount[cKeyReleased][cKey_09] += 1  ;
        PORTB &= ~(1<<PORTB1);              
     
        mLibNop();
    
        PORTB |=  (1<<PORTB2);
        mLibNop();
        if((PINB >> PORTB3) & 0x01) KeyCount[cKeyPressed][cKey_ST] += 1  ; // F
        else if (KeyPressed & (1<<cKey_ST)) KeyCount[cKeyReleased][cKey_ST] += 1  ;
        if((PINB >> PORTB4) & 0x01) KeyCount[cKeyPressed][cKey_00] += 1  ; // E
        else if (KeyPressed & (1<<cKey_00)) KeyCount[cKeyReleased][cKey_00] += 1  ;
        if((PINB >> PORTB5) & 0x01) KeyCount[cKeyPressed][cKey_SH] += 1  ; // D
        else if (KeyPressed & (1<<cKey_SH)) KeyCount[cKeyReleased][cKey_SH] += 1  ;
        PORTB &= ~(1<<PORTB2);      
    
    
        
        for(LocalCounter = 0;LocalCounter < cNumberOfKeys; LocalCounter++)
        {
            if(KeyCount[cKeyPressed][LocalCounter]  > cKeyPressedFilterThereshold)  KeyPressed  |= (1 << LocalCounter);
            if(KeyCount[cKeyReleased][LocalCounter] > cKeyReleasedFilterThereshold) KeyReleased |= (1 << LocalCounter);
        }
        
     
    }
    
    
    void DRVKbdCommand(tAddress aAddr,Buffer * aBuffer)
    {
        switch(aAddr)
        {
        case cScanKeyboard:
            DRVKbdScanKeys();
            break;
            
        case cReadPressedkey:
            mLibMemcpy(aBuffer->Address,&KeyPressed,sizeof(KeyPressed));
            break;
           
        case cReadReleasedkey:
            mLibMemcpy(aBuffer->Address,&KeyReleased,sizeof(KeyPressed));
            break;
            
        case cClearKeyState:
            KeyPressed = 0;
            KeyReleased= 0;
            mLibMemset(KeyCount,0,24);
            break;
            
    #ifdef AssertActive        
        default:
    
            mLibAssert(cTrue);
            break;
    #endif        
        }    
    
    }
    Code:
    #ifndef DRV_KBD
    #define DRV_KBD
    
    #include "TypeDefinition.h"
    #include "DRV_REG_RW.h"
    #include "LIB.h"
    
    #define cInput_F                PORTB3
    #define cInput_E                PORTB4
    #define cInput_D                PORTB5
    
    #define cOutput_K               PORTC5
    #define cOutput_J               PORTB0
    #define cOutput_H               PORTB1
    #define cOutput_G               PORTB2
    
    #define cKeyPressedFilterThereshold    5
    #define cKeyReleasedFilterThereshold   20
    #define cKeyNeverReleasedFilterThereshold    55
    
    
    
    #define mDrvKBDInit()			DRVKbdinit()
    
    
    extern void DRVKbdinit(void);
    extern void DRVKbdCommand(tAddress aAddr,Buffer * aBuffer);
    
    #endif	//DRV_KBD

  11. #10
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    Merci Pierrot, je vais regarder ça en détail je te remercie, cela va m'être très utile.

    et pour répondre à Jack, non je n'ai pas de pull up, j'ai juste un interrupteur et une résistance... et lorsque je parle de 0 et de 1 je parle du courant nominal de ma platine, 0= Ov, 1=5v mais en effet je n'ai pas d'oscillo pour vérifier comment se comportent les interrupteurs.

    Merci à vous deux je reviens vers vous dès que j'ai testé tout ça !
    ++

    Tiamat.

  12. #11
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    et pour répondre à Jack, non je n'ai pas de pull up
    Donc ça ne PEUT PAS fonctionner.

    et lorsque je parle de 0 et de 1 je parle du courant nominal de ma platine, 0= Ov, 1=5v
    Courant nominal ??? Plutôt tension d'alimentation

    mais en effet je n'ai pas d'oscillo pour vérifier comment se comportent les interrupteurs
    Un simple mutimètre suffira.

    Mais le problème, c'est que ton montage est faux depuis le début. Ta résistance est mal placée et ne sert à rien en plus. Il faut que tu branches ton inter entre l'entrée du pic et la masse, la résistance étant alors entre l'entrée du oic et le +5V. Note que tu peux permuter la résistance et l'inter.

    A+

  13. #12
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    Voici le montage.
    je me suis inspiré de nombreux montages du net, et je suis supris d'entendre qu'il est faux...


    donc tu me dis qu'il faut lever la résistance et la mettre en direct entre l'entrée du PIC et la masse ?

    Merci.
    Images attachées Images attachées  

  14. #13
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    Voilà comment tu annonçais ton câblage:
    j'ai un interrupteur par sortie du PIC, en série avec une résistance de 1kOhm....connecté à la masse donc rien de bien compliqué normalement !
    Ce qui est faux

    Voilà comment il faut câbler:
    Il faut que tu branches ton inter entre l'entrée du pic et la masse, la résistance étant alors entre l'entrée du pic et le +5V.
    , ce qui correspond bien au câblage du BP "bootloader" du schéma proposé.

    A+

  15. #14
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    pardon le schéma est erroné, en RD0 et RD1 ce sont des interrupteurs et pas des LEDS.

  16. #15
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    Citation Envoyé par tiamat Voir le message
    pardon le schéma est erroné, en RD0 et RD1 ce sont des interrupteurs et pas des LEDS.
    Donc ton schéma n'est pas bon à ce niveau.

  17. #16
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    ok merci jack,

    donc je vire les deux résistances et je laisse mes interrupteurs entre la masse et l'entrée du PIC.
    je fais la manip et je vous tiens au courant.

    Tiamat.

  18. #17
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    Tu es sur de vraiment lire attentivement ce que j'ai écrit? J'ai pourtant assez clairement expliqué qu'il fallait bien une résistance, mais qu'elle n'était pas à sa place. Je t'ai même dit quel modèle il fallait suivre sur ton schéma.

    Que faire de plus????

  19. #18
    tiamat

    Re : USB/PIC18F4550: PB rebond interrupteur

    ok j'ai compris.

    je dois avouer être un peu dérouté par tes réponses un peu "sèches", je fais les modifs de mon schéma et je te remercie.

  20. #19
    Jack
    Modérateur

    Re : USB/PIC18F4550: PB rebond interrupteur

    je dois avouer être un peu dérouté par tes réponses un peu "sèches"
    Désolé dans ce cas. Ca doit être parce que j'avais l'impression d'avoir évoqué depuis le début le problème (les pull up) et que j'avais l'impression que ça n'avançait pas.

    Montre-nous ton montage qu'on puisse voir si c'est bon.

    A+

Discussions similaires

  1. Débuter avec un PIC18F4550 USB
    Par synapsium dans le forum Électronique
    Réponses: 11
    Dernier message: 22/03/2012, 22h40
  2. Programmer un PIC18F4550
    Par Dodonojutsu dans le forum Électronique
    Réponses: 2
    Dernier message: 03/04/2009, 10h07
  3. envoyer float par USB- PIC18f4550
    Par titoff dans le forum Électronique
    Réponses: 9
    Dernier message: 28/07/2008, 21h18
  4. Probleme PIC18F4550 et USB
    Par RicounetZap dans le forum Électronique
    Réponses: 0
    Dernier message: 14/07/2008, 23h59
  5. Probleme pic18f4550
    Par nickie001 dans le forum Électronique
    Réponses: 1
    Dernier message: 13/04/2006, 09h18
Découvrez nos comparatifs produits sur l'informatique et les technologies.