Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Problème Servo moteur
hoffmann
Membre
Membre
Messages : 11
Enregistré en : mai 2018

#1 Message par hoffmann » ven. 25 mai 2018 17:24 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,
Je suis sur un PIC 18F et je rencontre un problème avec l'utilisation d'un servo moteur....

Quartz = 4MHz

J'utilise le Timer 0 et cherche donc à générer des impulsions de 1 => 2ms avec une période de 20ms.

Je l'ai configuré comme suis :


Code : Tout sélectionner

    //TIMER 0
    T0CON1bits.T0CS = 0b010;       //FOSC/4
    T0CON1bits.T0ASYNC = 0;         //The input to the TMR0 counter is synchronized to FOSC/4
    T0CON1bits.T0CKPS = 0b0000;    //Préscaler 1:1
    TMR0H = 200 ;                   //TIMER0 COUNT REGISTER
               
    T0CON0bits
.T0EN = 1;           // The module is enabled and operating
    T0CON0bits.T016BIT = 0;         //TMR0 is an 8-bit timer
    T0CON0bits.T0OUTPS = 0b0000;    //1:1 Postscaler
    PIE0bits.TMR0IE=1;               //Timer 0 interrupt enable


/*INTERRUPTIONS*/
    INTCONbits.GIEH=1;     //Global Interrupt Enable bit
    INTCONbits.PEIE=1;     //Peripheral Interrupt Enable bit
    INTCONbits.IPEN=0;     //Interrupt Priority Enable bit



counterB = 10; // 2ms
 




Dans l'interruption :

Code : Tout sélectionner

if(PIR0bits.TMR0IF == 1)                // Timer 0
    {
        counter = counter + 1;
        
        if 
(counter == counterB)
        {
            TEST = 0;
        }
        
        if 
(counter == 100)
        {
            counter = 0;
            TEST = 1;
        }
        PIR0bits.TMR0IF = 0;

    


4MHZ / 4 ==> 1µs
Pas de préscaler/post scaler
J'attends 200 cycles => 200µs puis encore 100 cycles ==> 20ms.
En cours de route, counterB permet de monter ou baisser la pwm.

PS : si en parallèle je fais un bête DELAY de 2 secondes... mon délais réel fait presque 4 secondes... et cela m'étonne d'une si grande différence...

Résultat :
A l'oscilloscope, j'obtiens exactement ce que je souhaite en terme de forme de courbe.
Le servo se rends bien à la bonne position, MAIS il a ensuite la tremblote.
(dur a expliquer)
Une fois a la bonne position, le servo va faire trois petites secousses, une pause, puis recommencer. C'est quelque chose de périodique.

Cela fait la même chose sur n'importe quel servo.

Auriez vous des conseils ?

Merci par avance !!

Hoffmann
Modifié en dernier par hoffmann le sam. 26 mai 2018 09:14, modifié 1 fois.

Problème Servo moteur
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#2 Message par cyril13110 » ven. 25 mai 2018 21:20 lien vers la Data-Sheet : Cliquez ici

bonsoir offmann et bonsoir a tous,
si le servo tremblote cest que ton signal n'est pas stable. Dans un post sur le forum, je ne sais plus qui a parlé de la sensibilité des servomoteurs, mais il me semble qu'un servo classique de memoire etait semsible a une variation de quelques dizaines de microsecondes.

as tu regardé à l'oscilloscope la stabilité du signal dans le temps et surtout au moment ou ca tremble?


apres au sujet de ton code, la partie interruption doit etre le plus petit possible.
teste aves seulement l'incrementation de ta variable.
le restr du code tu le mets dans le programme principal ou dans une sous fonction simple.

Problème Servo moteur
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » sam. 26 mai 2018 00:32 lien vers la Data-Sheet : Cliquez ici

Bonjour et bienvenue hoffmann,

Il faudrait que nous indique un lien vers la DS de ton PIC : procédure
SAns quoi o nen peut pas verifier si les registres sont les bons.

Si déjà avec un delay de 2 secondes tu obtiens un temps de 4 secondes, tu auras forcement des problèmes ! fais clignoter une LED pour commencer et surtout vérifier que tout fonctionne correctement.

Les servos moteurs ne fonctionne pas tous pareils, je ne sais pas combien tu en as testé ? mais essaye de le mettre plutôt 1.8ms plutôt que 2ms . 2ms c'est peu être trop les servos peuvent arriver en buter.

Les alimentations sont-elles bien découplées ? le schéma du montage ?

Une photo de ton signal au scope ?

J'ai pris pour habitude de ne jamais vérifier une égalité parfaite dans une INT . Car si pour une raison ou une autre tu loupe cette égalite le programme part en vrille.

Code : Tout sélectionner

        if (counter == counterB)
        {
            
TEST 0;
        } 


A remplacer par :

Code : Tout sélectionner

        if (counter >= counterB)
        {
            
TEST 0;
        } 


Et il faudrait la partie qui gère aussi les impulsions de ton programme ? est ce la variable "TEST" ?

Essaye de nous amener le plus d'infos possibles car la c'est un peu juste, les raisons peuvent être multiples
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème Servo moteur
hoffmann
Membre
Membre
Messages : 11
Enregistré en : mai 2018

#4 Message par hoffmann » sam. 26 mai 2018 01:22 lien vers la Data-Sheet : Cliquez ici

Merci pour les aides...

Voici le lien vers la Datasheet

J'ai bien modifié le code de l'interruption

Code : Tout sélectionner

 if(PIR0bits.TMR0IF == 1)                // Timer 0
    
{
        
counter counter 1;
        
        if (
counter >= counterB)
        {
            
TEST 0;               // Sortie PWM
        
}
        
        if (
counter == 100)
        {
            
counter 0;
            
TEST 1;                 // Sortie PWM
        
}
        
PIR0bits.TMR0IF 0;
    } 


J'ai testé sur 4 servo différents : même problème...

Le #define test correspond a D0.
TRISDbits.TRISD0 = 0; // TEST
#define TEST LATDbits.LATD0


Les delay pur et dur fonctionnent très bien quand le TMR0 n'est pas activé. Dès qu'il est activé, je double les temps sans le vouloir...

Les alimentations sont bien découplés. La mise en position initiale du servo se passe bien, mais je n'arrive pas a comprendre pourquoi, au bout de x secondes il se mets a rebouger, puis pause, puis recommence. Très périodique.....

Problème Servo moteur
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » sam. 26 mai 2018 08:13 lien vers la Data-Sheet : Cliquez ici

Hello ,

tout d'abord, merci de suivre la procédure pour mettre la Data-sheet de ton PIC comme indiqué ici : procédure

Ainsi la DS apparaitras dans tous les posts, pas besoin de cherche le post où tu l'a mise. Cela arrange tout le monde :furieux:
Ta DS donne plusieurs PIC lequel utilises tu ?

Je nz comprends rien à la configuration de ton Timer0 ! Je pense que tu as fait des copier coller non ? un PIC ca demande plus d'effort et d'amour qu'un Arduino !

par exemple :

Code : Tout sélectionner

PIR0bits.TMR0IF == 1

Le flag du Timer0 se tropuve dans le registre INTCONet pas PIR0. d'ailleur PIR0 n'existe pas ou je l'ai pas vu !

TOUTE ta configuration du timer0 est à refaire ! les registre n'existe même pas !

Code : Tout sélectionner

T0CON0bits.T016BIT 0;         //TMR0 is an 8-bit timer 

Page 125 de la DS, on voit qu'il faut mettre le bit T08BIT à 1 pour avoir un compteur de 8bit ?

Soit c'est la mauvaise DS......soit c'est le mauvais PIC lol .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème Servo moteur
hoffmann
Membre
Membre
Messages : 11
Enregistré en : mai 2018

#6 Message par hoffmann » sam. 26 mai 2018 09:15 lien vers la Data-Sheet : Cliquez ici

Salut, je suis dsl j'ai pris le PIC de mon précédent projet.

J'ai mis à jour le post pour y inclure la bonne datasheet.

C'est donc bien un pic 18F47K40.

Cordialement

Problème Servo moteur
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » sam. 26 mai 2018 09:59 lien vers la Data-Sheet : Cliquez ici

:mur: effectivement c'est mieux !

Il faudrait le programme en entier pour y voir plus clair !

regarde déjà ici pour vérifier la configuration de ton timer0: viewtopic.php?f=27&t=71

Ensuite fais clignoter une led toute les secondes avec ce timer0 ensuite se sera gagné .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème Servo moteur
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2586
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#8 Message par paulfjujo » sam. 26 mai 2018 11:02 lien vers la Data-Sheet : Cliquez ici

bonjour,


Peux-tu montrer ton code en entier ...

avec XC8 est-ce que la fonction Delay utilise un timer ou interrupt ?
sinon ressaie de remplacer ta fonction Delay de 2sec par une boucle de comptage


Code : Tout sélectionner


void Delay_2sec
()    // 1.956 sec 
 
{
 
unsigned long L1=110000;  
 while(
L1>0L1--;
  } 


pour etre plus precis , au lieu d'etre à +-200µS de resolution ,
tu pourrais utiliser le Timer0 en mode 16bits.
et augmenter FOSC de 4 à 16Mhz, 32 voir 64Mhz
Aide toi, le ciel ou FantasPic t'aidera

Problème Servo moteur
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#9 Message par satinas » sam. 26 mai 2018 12:49 lien vers la Data-Sheet : Cliquez ici

Bonjour,
Tu serais pas en alimentation 3,3V par hasard ?
Le pic a t-il assez de pêche pour piloter le servo ?
Alimente le en 5V
Ne pas dépasser les timings, entre 1ms et 2ms

Problème Servo moteur
hoffmann
Membre
Membre
Messages : 11
Enregistré en : mai 2018

#10 Message par hoffmann » lun. 2 juil. 2018 16:05 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous et vraiment désolé pour cette longue absence ! congé paternité :)

Alors,
Je suis bien en 5V partout et l'alimentation semble tenir le coups !

Voici mon code de paramétrage des registres :

Code : Tout sélectionner

    //TIMER 0
    T0CON1bits.T0CS = 0b010;       //FOSC/4
    T0CON1bits.T0ASYNC = 0;         //The input to the TMR0 counter is synchronized to FOSC/4
    T0CON1bits.T0CKPS = 0b0000;    //Préscaler 1:1
    //TMR0H = 200 ;                   //TIMER0 COUNT REGISTER
               
    T0CON0bits
.T0EN = 0;           // The module is enabled and operating
    T0CON0bits.T016BIT = 0;         //TMR0 is an 8-bit timer
    T0CON0bits.T0OUTPS = 0b0000;    //1:1 Postscaler  


Voici l'interruption :

Code : Tout sélectionner

if(PIR0bits.TMR0IF == 1)                // Timer 0
    {
        counter = counter + 1;
        
        if 
(counter >= counterB)
        {
            TEST = 0;               // Sortie PWM
        }
        
        if 
(counter == 75)
        {
            counter = 0;
            TEST = 1;                 // Sortie PWM
        }
        PIR0bits.TMR0IF = 0;
    }



et dans mon main :

Code : Tout sélectionner

counterB = 8; // ou 4
 T0CON0bits.T0EN = 1;


Alors, aujourd'hui ça fonctionne :) Je ne sais trop guerre pourquoi. (Peut être parceque je ne renseigne plus le TMR0H = 200 ;) ?
Le servo est stable.
Par contre, je sens que toute la puissance de mon pic part dans cet interruption :(

==> Meilleur moyen de le savoir, la fonction qui ne fait rien que perdre du temps
=> Au lieu de perdre 1 seconde (normal), je perds environ 1,7 seconde...
J'en déduis que je passe presque 70% de mon temps dans cette interruption... :(

J'aimerai bien, moins déclencher l'interruption. Mais je pense que la vitesse de mon horloge à 4MHz est trop faible non ?

Qu'en pensez-vous ?


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 6 invités