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

PIC pwm pour servo



  1. #1
    ben1015

    PIC pwm pour servo


    ------

    Bonjour,

    Je ne comprends pas comment faire pour réaliser une pwm de 20ms avec un quartz de 4MHz.
    Code:
    #use delay(clock=4000000)
    setup_timer_2(T2_DIV_BY_16, 254, 1);
    Avec cette configuration maximale, on arrive à une période de 4.064ms, on est donc pas encore proche des 20ms. Comment faut-il procéder?

    -----

  2. #2
    Antoane
    Responsable technique

    Re : PIC pwm pour servo

    Bonjour,
    c'est pas du flowcode, mais l'idée est la même : http://forums.futura-sciences.com/el...rvomoteur.html
    Deux pattes c'est une diode, trois pattes c'est un transistor, quatre pattes c'est une vache.

  3. #3
    ben1015

    Re : PIC pwm pour servo

    Je vois pas vraiment ce qui peut m'aider dans l'autre discussion.

  4. #4
    ben1015

    Re : PIC pwm pour servo

    J'utilise une autre méthode car c'est impossible avec l'autre.
    Code:
    #INT_RTCC
    void tick_interrupt(void)
    {
    static int8 loop_x =77;
    static int8 pulse_x;
    
    
    if(--loop_x == 0)
      {
       loop_x = 77;
       pulse_x = width_x;
      }
    
    if(pulse_x)
      {
       output_high(PWM_servo_x);
       pulse_x--;
      }
    else
      {
       output_low(PWM_servo_x);
      }
    Le problème est que la variable width_x (celle qui permet de faire varier la largeur de l'impulsion) ne varie que par pas de 0.4ms ce qui ne permet pas de faire fonctionner un servomoteur. Je ne comprends pas comment faire cette commande avec un pic. Des idées?

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


  7. #6
    freepicbasic

    Re : PIC pwm pour servo

    si l'on condidére que chaque canal à une définition de 64 pas
    comme il y a 8 voies soit 2ms x8 = 16ms + l'équivalent de 2 voies de synchro pour faire les 20ms.
    Il nous faut une base de temps de 64 x 10 = 640 ièm de 20 ms.
    0.02s / 640
    soit 31µs
    et
    un compteur sur 16 bits de position en cours (step).
    un compteur sur 16 bits de transition de la voie en cours (thischanel).
    un index de voie (chanel)

    position de chaque voie MyChanel[]

    (Avec seulement 32 pas, par voie on pourrait faire 62 µs et un compteur de 320)
    au dessus de 64 on risque de ne plus être assez rapide avec un quartz 20Mhz et avec cette méthode.


    Sur les 64 pas il y a 1ms de signal minimum reste plus que 32 positions par servo.


    exemple (non testé pour générer un signal PPM 8 voies.)
    On pourrait pour un robot indexer les sorties, de façon à avoir un seul signal par pin du port.
    Code:
    #INT_RTCC
    // global
    static int8 MyChanel[8];
    
    main()
    {
    int i;
    
    // init les position centrales des 8 servos
    for (i=0; i<7; i++)
    	MyChanel[i]=32 + 16; // 16 position centrale
    // varier entre 32 et 64
    }
    
    // 32 µs avec quartz 20Mhz
    void tick_interrupt(void)
    {
    static int16 step;
    static int8 chanel;
    static int16 thischanel;
    
    
    if(step>640)
      {
    	step=0;
    	chanel=0;
    	thischanel=MyChanel[chanel];
      }
    step++;
    if(chanel<8)
      {
    	output_high(PWM_servo_x);
    
    	if (step==thischanel) {
    		chanel++;
    		thischanel += MyChanel[chanel];
    		output_low(PWM_servo_x); //séparation
    		}
    
    	}
    else
      {
       output_low(PWM_servo_x);
      }
    A+, pat

  8. #7
    ben1015

    Re : PIC pwm pour servo

    Pas tout compris la, j'essaie juste avec une voie pour l'instant. Je ne comprends pas dans ton programme quelle est la variable qui correspond à la largeur de l'impulsion, faut-il absolument un quartz de 20Mhz? On ne peut rien avoir de correct avec un quartz de 4MHz pour deux voies (mon but est de commander deux voies)?

  9. #8
    freepicbasic

    Re : PIC pwm pour servo

    MyChanel[0] pour varier le canal 0

    Si l'on veut générer 1 pulse par pin PWM_servo_x devra avoir le no de la pin qui correspond à la voie

    à 4 mhz
    on pourrait utiliser la fonction PWM de certains pic , mais généralement il y a qu'une voie.
    Sinon chercher un pic qui peut générer 2 PWM (voir les 18f ou au dessus)
    A+, pat

  10. #9
    ben1015

    Re : PIC pwm pour servo

    Le pic 16f877 a bien 2 pwm mais il est impossible de faire une pwm de 50Hz.

  11. #10
    mmarc2007

    Re : PIC pwm pour servo

    Salut,

    je ne suis pas sur de comprendre ton problème, mais si tu cherches à générer ton signal de periode 20ms avec des puls de 0,5 à 2,5ms je te conseil d'utiliser l'interruption du pic sur le timer0.

    Avec un quartz de 4Mhz, tu utilises un prescaler de 64 et une variable d'état.

    sachant que timer0 est sur 8 bits tu peux compter jusqu'à 16ms. Donc tu utilises 2 fois ce timer en l'initialisant à 99. (255-99=156) 156 * 64us = 9,98ms

    Si tu veux générer un signal S1 de 2ms, lorsque le TMR0 dépasse 31+99=130 count (2ms/64=31 & seuil=99) tu remet S1 à 0.

    ça t'aide?

  12. #11
    ben1015

    Re : PIC pwm pour servo

    Salut mmarc2007,

    Oui ça m'aide un peu, j'ai commencé en faisant ce que tu me dit mais je bloque pour la suite. Peut-tu me dire si le début est correct? Ensuite est-ce que avec ta méthode je pourrais avoir une variable variant de 0 à 200 ce qui correspondrait à une impulsion de 0,5ms à 2.5ms par exemple ?

    Code:
    #include <16F877A.h>
    														
    #fuses XT,NOWDT,NOPROTECT,NOLVP				     		
    #use delay(clock=4000000)
    #use rs232(baud=9600,rcv=PIN_C7,xmit=PIN_C6,bits=8)	
    #define PWM_servo_x 	PIN_B0
    #define PWM_servo_y 	PIN_B1
    
    /* Déclaration des fonctions écrites */
    void init_int();
    
    // Programme principal
    main(){
    	init_int();
    	setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
    	set_timer0(99);
    }
    
    //*************   initialisation des interruptions  **************//
    
    void init_int()
    {
    enable_interrupts(global);	// Toutes les interruptions validé 
    enable_interrupts(INT_RTCC);
    }
    //***********************   interruptions  ***********************//
    #INT_RTCC
    void clock_isr(void)
    {
    }
    Merci

  13. #12
    ben1015

    Re : PIC pwm pour servo

    J'ai compris ce qu'il fallait faire, mon nouveau soucis est que j'ai une période de 16ms, j'ai surement du oublier quelque chose, j'ai des doutes au niveau de l'initialisation du timer à 99 et du fait que je dois utiliser deux fois ce timer. Voilà mon nouveau prog, si vous voyer le pb?
    Code:
    #include <16F877A.h>
    														
    #fuses XT,NOWDT,NOPROTECT,NOLVP				     		
    #use delay(clock=4000000)
    #use rs232(baud=9600,rcv=PIN_C7,xmit=PIN_C6,bits=8)	
    #define PWM_servo_x 	PIN_B0
    #define PWM_servo_y 	PIN_B1
    
    /* Déclaration des fonctions écrites */
    void init_int();
    int value, i;
    // Programme principal
    main(){
    	init_int();
    	setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
    	set_timer0(99);
    	while(1){
    	value=0;
    	for(i=0;i<30;i++){
    	value++;
    	delay_ms(1000);
    }
    }
    }
    
    //*************   initialisation des interruptions  **************//
    
    void init_int()
    {
    enable_interrupts(global);	// Toutes les interruptions validé 
    enable_interrupts(INT_RTCC);
    }
    //***********************   interruptions  ***********************//
    #INT_RTCC
    void commande(void)
    {
    	int period;
    	if(period==0) period=2;
    	else{
    		do{
    		output_high(PWM_servo_x);
    		}while(get_timer0()<value);
    	output_low(PWM_servo_x);	
    	}
    }
    Merci

  14. #13
    mmarc2007

    Re : PIC pwm pour servo

    Salut,

    Avec un prescaler de 64 tu peux compter jusquà 16ms car le registre est sur 8 bits donc 255 valeurs possibles.

    Le but c'est d'utiliser 2 fois le timer0! C'est un bon compromis pour compter jusqu'à 20 ms avec une résolution angulaire suffisante!

    J'ai fais un projet qui reprend cette idée : http://marcmittler.fr/projets/index.php?projet=2 l'explication du début + le code devraient t'aider!

    Bonne chance!

  15. #14
    ben1015

    Re : PIC pwm pour servo

    Salut,

    Le problème est que j'arrive pas à faire démarrer le timer à 99 et le faire dérouler deux fois, c'est plus un problème de programmation en CCS qu'autre chose. La fin de mon programme dans commande (le if et la variable period) tout ça ne sert à rien. Ma première question pour les personnes qui programme en CCS est comment initialiser le timer 0 à 99 (je le fais au début du programme mais visiblement il ne faut pas faire comme ça)? Et la deuxième comment faire un boucle de 2 itérations?

    Merci

  16. #15
    mmarc2007

    Re : PIC pwm pour servo

    Je pense que c'est plus un problème d'algo que de ccs!

    Pour faire deux iterations il faut une variable :

    Code:
    int iteration=1;
    
    if(iteration==1){
    
    [...]
    iteration=2;
    }
    
    
    elseif(iteration==2){
    [...]
    iteration=1;
    }

    en ce qui concerne l'initialisation de TMR0 il faut le faire après chaque interruptions!!!

    Si tu te contente de l'initialiser au demarrage, TMR0 va compter de 99 à 255 puis repasser à 0 pour compter de 0 à 255...

  17. #16
    ben1015

    Re : PIC pwm pour servo

    Merci mmarc2007, ça fonctionne!

Discussions similaires

  1. control de servo avec un pic
    Par mortaurat dans le forum Électronique
    Réponses: 22
    Dernier message: 12/02/2010, 11h09
  2. Commande PIC arret automatique Servo
    Par devobowl dans le forum Électronique
    Réponses: 4
    Dernier message: 31/12/2009, 11h02
  3. servo et pic 16f877
    Par ricorico dans le forum Électronique
    Réponses: 7
    Dernier message: 11/10/2009, 08h42
  4. problème servo controler par un pic
    Par kurty65 dans le forum Électronique
    Réponses: 4
    Dernier message: 11/05/2009, 17h19
  5. generateur pwm pour mcc a pic
    Par chirvane dans le forum Électronique
    Réponses: 2
    Dernier message: 22/04/2009, 08h45
Découvrez nos comparatifs produits sur l'informatique et les technologies.