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

Double tempo avec un seul timer ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#11 Message par Jérémy » jeu. 10 août 2017 10:03 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Ta solution doit fonctionner JMarc . Mais je trouve ça moins intuitif ! . car l’interruption va se déclencher 9 fois sur 10 pour incrémenter un compteur et seulement au bout de la dixième fois faire quelques choses .

Dans mon cas , j'ai vraiment deux timer en un . Un coup il est rapide, et un autre il est long ! Je pense que c'est une philosophie, ou vision de voir les choses. J'adore débattre sur ce genre de sujet, pour comparer les différentes points de vue.

paulfjujo a écrit :Source du message pouquoi pas 1ms

Ca se complique pour les servos, car la valeur la plus petite n'est pas la milli-seconde, mais les centièmes de microseconde voir dixième. Car les pulses à envoyer sont en µs .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Double tempo avec un seul timer ?
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2586
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#12 Message par paulfjujo » jeu. 10 août 2017 12:14 lien vers la Data-Sheet : Cliquez ici

Jérémy a écrit :
Ca se complique pour les servos, car la valeur la plus petite n'est pas la milli-seconde, mais les centièmes de microseconde voir dixième. Car les pulses à envoyer sont en µs .


Tu as pas mal de timers dispo sur ton PIC 18F46K22 :
3 timers 16 bits 1/3/5
+ 3 autres timers 8 bits 2/4/6

Je verrai bien : interrupt timer0 toutes les 20 ms
- traite la mise en sommeil pour les 20 ou 200ms
- traite la synchro de recurence 20ms des 2 servos
qui armerait le depart de 2 autres timers ( 2 et 4 ) (gamme en xµS) pour les 2 servos

mais les centièmes de microseconde ? .... de ms sans doute
( rappel: la resolution 1µS pour des servomoteurs de radiocommande est illusoire, se baser plutot sur des steps de +-10µS )

le traitement fait dans l'interruption 20mS devrait rester tres court
et ne pas penaliser le reste .
Aide toi, le ciel ou FantasPic t'aidera

Double tempo avec un seul timer ?
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#13 Message par cyril13110 » jeu. 10 août 2017 12:46 lien vers la Data-Sheet : Cliquez ici

bonjour à tous,

en effet c'est simpa de débatre sur des solutions divers et les points de vue, perso ca ma toujours permis de trouver des idées nouvelles.

Pour ton montage je suis du meme avie que pauljujo, un second timer pour tes servo sera bien mieux pour gerer ta precision.
et du coup bein je viens d'apprend un truc , la resolution des servo moteur de 10µs.
Javais fait un proto de radiocommande avec 2 pic et une liaison crypté par 2 XBEE PRO.
Mais je m'etais arreté à une precision d'un compteur de 127 pas (pas terrible en effet) mais avec le meme principe du timer général qui compte et 6 comparateurs j'ai reussi a commander 5 servo et 1 moteur brushless sans probleme (bon ok avec peut de precision mais ca a fonctionné), mais si j'avais sue que je pouvais descendre à 10ùs ........

Double tempo avec un seul timer ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#14 Message par Jérémy » dim. 20 août 2017 08:47 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Mode "retour de vacances" mis sur ON .

Jevais me lancer dans le pilotage de deux servos avec un seul timer ! EN AVANT ..... :langue:
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Double tempo avec un seul timer ?
JMarc
Confirmé
Confirmé
Messages : 605
Enregistré en : août 2016
Localisation : Dans le Sud...

#15 Message par JMarc » dim. 20 août 2017 23:23 lien vers la Data-Sheet : Cliquez ici

Bonjour Jérémy

Servos de recup ? Acheté ?

Je vais suivre tout cela de près :shock:

Double tempo avec un seul timer ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#16 Message par Jérémy » lun. 21 août 2017 09:43 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Il s'agit pour le moment de servo de récupération !

Mais je vais prévoir de faire en sorte dans le programme de régler facilement les débattements. car entre les servos les différences de tempo sont parfois grande suivant leur degré de liberté et de leur conception d’après se que j'ai pus lire ici et la.

Depuis le peu de temps que je bidouille l’électronique e la programmation, j'ai bien appris ( souvent à mes dépends) qu'un programme doit être facilement adaptable, car rien n'est jamais figé ! :wink:
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Double tempo avec un seul timer ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#17 Message par Jérémy » lun. 4 sept. 2017 08:55 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

J'avance bien et mieux , ça fonctionne bien .... :lol:

Voici mes avancées :

Code : Tout sélectionner

//-----------------------------------     VARIABLES et CONSTANTES      ------------------------------------------------
bit Pause_on ;

char iChoix_servo;
char servo0_TMR1Lservo0_TMR1Hservo1_TMR1Lservo1_TMR1HPause_TMR1LPause_TMR1H;
unsigned int Position;
//---------------------------------------        PROTOTYPE          ---------------------------------------------------
void calcul_servo0(unsigned int);
void calcul_servo1(unsigned int);

//---------------------------------------------------------------------------------------------------------------------
void interrupt() {


 if (
TMR1IF_bit){       // Interruption sur TIMER 1

    
TMR1IF_bit ;    // RAZ flag INT
    
    
if (Pause_on == 1){    // C'est l'heure d'une longue pause
        
        
Pause_on 0;
      
        
TMR1H Pause_TMR1H;  // Je précharge pour faire la longue pause
        
TMR1L Pause_TMR1L;

        
LATC.B0 LATC.B1 0;         //J'éteint les servos
     
}
     
    else {                
// Alors c'est l'heure d'allumer un servo

        
if (Choix_servo == 0){
               
TMR1H servo0_TMR1H ;
               
TMR1L servo0_TMR1L ;
               
LATC.B0 1;            // J'allume mon servo pour le temps du dessus
               
Pause_on 1;
               
Choix_servo 1;        // Je change de servo pour le prochain tour
         
}
        else{
               
TMR1H servo1_TMR1H;   //
               
TMR1L servo1_TMR1L;
               
LATC.B1 1;            // J'allume mon servo pour le temps du dessus
               
Pause_on 1;
               
Choix_servo 0;        // Je change de servo pour le prochain tour
         
}
     }
  }
}


/*#####################################################################################################################
#####################################     PROGRAMME PRINCIPAL     #####################################################
#####################################################################################################################*/


void main() {

 
ANSELA ANSELB =  ANSELC ANSELD ANSELE 0;  // tout en numérique
 
TRISC.B0 TRISC.B1 0;                          // Broche RC0 et RC1 en sortie  pourcommande servo
 
TRISD 0b11111111;                               // PORTD en entrée pour BP

 
Pause_on  Choix_servo 0;
 
 
// --------------- TIMER 1 : 8ms   --------------------------
  
T1CON  0x01;
  
TMR1H     0xC1;
  
TMR1L     0x80;

  
TMR1IF_bit 0;
  
TMR1IE_bit 1;
  
INTCON    0xC0;
  
  
  
servo0_TMR1H 0xF4;  //1.5ms
  
servo0_TMR1L 0x48;
  
servo1_TMR1H 0xF4;  //1.5ms
  
servo1_TMR1L 0x48;

/*#####################################################################################################################
#######################################     BOUCLE INFINIE      #######################################################
#####################################################################################################################*/
  
while(1) {

    if (
PORTD.B0 == 1) {    // a droite
       
delay_ms(20);
       if (
PORTD.B0 == 1) {
          
calcul_servo0(2000);
          while (
PORTD.B0 == 1);
        }
     }

    if (
PORTD.B1 == 1) {     // Au milieu
       
delay_ms(20);
       if (
PORTD.B1 == 1) {
          
calcul_servo0(1500);  // Position en µs
          
while (PORTD.B1 == 1);
        }
     }

    if (
PORTD.B2 == 1) {        // A gauche
       
delay_ms(20);
       if (
PORTD.B2 == 1) {
          
calcul_servo0(1000);  // Position en µs
          
while (PORTD.B2 == 1);
        }
     }
    
    
    if (
PORTD.B5 == 1) {    // a droite
       
delay_ms(20);
       if (
PORTD.B5 == 1) {
          
calcul_servo1(2000);
          while (
PORTD.B5 == 1);
        }
     }

    if (
PORTD.B6 == 1) {     // Au milieu
       
delay_ms(20);
       if (
PORTD.B6 == 1) {
          
calcul_servo1(1500);
          while (
PORTD.B6 == 1);
        }
     }

    if (
PORTD.B7 == 1) {        // A gauche
       
delay_ms(20);
       if (
PORTD.B7 == 1) {
          
calcul_servo1(1000);
          while (
PORTD.B7 == 1);
        }
     }
  }
}


void calcul_servo0(unsigned int Position){
     
unsigned int Temp;
     
     
servo0_TMR1H = (65536-(Position*2))>>8;
     
servo0_TMR1L = (65536-(Position*2)) && (0x00FF) ;
     
     
Temp =   0x2710 Position;  // 10ms - le temps d'activation du servo
     
Pause_TMR1H =   (65536-(Temp*2))>>8;
     
Pause_TMR1L =   (65536-(Temp*2)) && (0x00FF) ;
}

void calcul_servo1(unsigned int Position){
     
unsigned int Temp;

     
servo1_TMR1H = (65536-(Position*2))>>8;
     
servo1_TMR1L = (65536-(Position*2)) && (0x00FF) ;

     
Temp =   0x2710 Position;  // 10ms - le temps d'activation du servo
     
Pause_TMR1H =   (65536-(Temp*2))>>8;
     
Pause_TMR1L =   (65536-(Temp*2)) && (0x00FF) ;
}

 



Dans ce bout de code test, je pilote deux servo moteur de récupération avec des BP .

J'entrevois largement une amélioration du programme. comme par exemple.

Regler le temps de pause suivant le nombre de servos a commander . dans mon exemple il y en a seulement 2 donc un temps de pause de 8ms . mais si il y en avait 4 on pourrait mettre 4ms entre chaque envoi d'ordre.
Il faudrait également ajuster la pause en fonction de la consigne envoyée pour avoir précisément 20ms. Par exemple si on envoie 1ms au servo la pause devrait être de 9ms . et si on envoi 2ms au servo la pause devrait être de 8ms.

On pourrait donc envisager de piloter de nombreux servos avec un seul timer.

Le HIC c'est qu'on ne peut pas éteindre les servos du coup ! ou alors faudrait trouver une astuce .

To be continued
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Double tempo avec un seul timer ?
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#18 Message par cyril13110 » lun. 4 sept. 2017 10:47 lien vers la Data-Sheet : Cliquez ici

Jérémy a écrit :Le HIC c'est qu'on ne peut pas éteindre les servos du coup ! ou alors faudrait trouver une astuce .

To be continued



bonjour jeremy et bonjour à tous,
quelle est l'interé d’éteindre un servo? heu plutot ton besoin....
normalement si tu ne veux pas l'utiliser tu le laisse dans ca position neutre, c'est à dire à 1.5mS.

Double tempo avec un seul timer ?
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#19 Message par Jérémy » lun. 4 sept. 2017 11:02 lien vers la Data-Sheet : Cliquez ici

Hello,

Ah mais non ....

Un servo en position neutre, reçois quand même sa consigne en permanence. Donc il consomme en permanence. Pour preuve il résiste quand tu essaye de le faire manuellement.
"Éteindre" un servo ou plutôt arrêter de lui envoyer des consignes, le libère, tu peux donc le bouger manuellement ensuite.

J'ai un servo qui travaille sous contrainte ( ressort). Je souhaite arrêter mon servo , ainsi le ressort le ramène en position initiale par exemple.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Double tempo avec un seul timer ?
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#20 Message par cyril13110 » lun. 4 sept. 2017 11:41 lien vers la Data-Sheet : Cliquez ici

ok je vois, alors ce que tu peux faire ca serai de paramétrer un bit d'activation soit sur une entrée TOR avec un ensemble DIP SWITCH soit en internet que tu paramètre via un bp.
et du coup ton code serai:

si bit 3 = 1 --> alors je calcul la commande pour le servo 3
si bit 3 = 0 --> alors je ne calcul pas la commande pour le servo 3

ca va te rajouter une condition supplémentaire mais ton problème sera réglé.


Retourner vers « Langage C »

Qui est en ligne

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