Asservissement P.I.D. PIC16F876
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

Asservissement P.I.D. PIC16F876



  1. #1
    invite0c083bae

    Asservissement P.I.D. PIC16F876


    ------

    Bonjour à tous,

    Je tiens déjà à remercier les futurs "lecteurs". Je vais essayer d'être clair et concis. J'ai fait un programme assez complet qui permet, à partir de la fréquence de deux sondes HALL de générer 4 signaux de commandes de rapport cyclique 25% et déphasés de 90°... Jusque là ... ok. Les fréquences sont comprises entre 15 et 150Hz (je n'ai pas utilisé le PWM pour la génération car ça me posait des problèmes, j'ai opté pour le timer1).

    Le problème arrive!! Il faut désormais que je fasse un asservissement PID car il ne faut pas que je génère les commandes brutalement mais avec un certain délais, une certaine accélération. C'est pourquoi je fais appel à vous. J'ai gratté l'exemple sur MicroChip et différent sites internet (fribotte ..) mais ça me parait très compliqué et ils passent tous par le PWM. Voici ce que j'ai tenté de faire pour le moment mais je suis bloqué :

    Code:
    void MAINPid () {
    
    	// Calcul du terme intégrale
    	i16SumE = i16SumE + i8En0;						// Addition des erreurs
    	if (i16SumE > SUM_E_MAX) {						// Test si SumE trop grand ...
    		i16SumE = SUM_E_MAX;						// Alors le fixer à la valeur max
    	}
    	if (i16SumE < SUM_E_MIN) {						// Test si SumE trop petit ...
    		i16SumE = SUM_E_MIN;						// Alors le fixer à la valeur min
    	}
    										// Le terme intégral est (Ts/Ti) * SumE où Ti vaut Kp/Ki
    										// et Ts est la période d'échantillonnage
    										// L'équation actuelle utilisée pour calculer le terme intégral est
    										// Ki*SumE / (Kp * Fs * X) où X est le facteur d'échelle inconnu
    										// et Fs est le fréquence d'échantillonnage
    
    	i16IntegralTerm = i16SumE / 256;					// Divisé par la fréquence d'échantillonnage											
    	i16IntegralTerm = i16IntegralTerm * i1Ki;				// Multiplié par Ki
    	i16IntegralTerm = i16IntegralTerm / 16;					// Combinaison du facteur d'échelle et de Kp
    
    
    	// Calcul du terme dérivé
    	i16DerivativeTerm = i8En0 -i8En3;
    	if (i16DerivativeTerm > 120) {						// Test si le terme dérivé est trop grand ..
    		i16DerivativeTerm = 120;					// Alors le fixer à 120
    	}
    	if (i16DerivativeTerm < 120) {						// Test sur le terme dérivé est trop petit ...
    		i16DerivativeTerm = -120;					// Alors le fixer à -120
    	}
    
    										// Le calcul du terme dérivé est (Td/Ts)[E(n) - E(n-1)]
    										// Où Td est Kd/Kp
    										// L'équation actuellement utilisée est Kd(en0-en3)/(Kp*X*3*Ts)
    	i16DerivativeTerm = i16DerivativeTerm * i1Kd;				// Où X est le facteur d'échelle inconnu
    	i16DerivativeTerm = i16DerivativeTerm  >> 5;				// Divisé par 32 précalculé Kp*X*3*Ts
    	if (i16DerivativeTerm > 120) {
    		i16DerivativeTerm = 120;
    	}
    	if (i16DerivativeTerm < 120) {
    		i16DerivativeTerm = -120;
    	}	
    										// C(n) = K(E(n) + (Ts/Ti)SumE + (Td/Ts)[E(n) - E(n-1)])
    	i16Cn = i8En0 + i16IntegralTerm + i16DerivativeTerm;			// Addition des termes
    	i16Cn = i16DerivativeTerm * i1Kp / 1024;				// Multiplié par Kp après échelonnage
    
    }
    Il y a surement des erreurs, n'hésitez surtout pas. J'ai trouvé des cours sympathiques sur le PID sur internet et mes souvenirs de BTS resurgissent (un peu) mais j'arrive pas à traduire tout ça en programmation. S'il vous semble nécessaire d'avoir ma génération de signaux via le timer1 n'hésitez pas.

    NB : Les éternels râleurs de forum (he oui y'en à toujours!), pas la peine de me dire "google est ton amis" ou autre ... j'ai fait bon nombre de recherches sans pouvoir avancer. On est ici pour de l'entraide alors faites part de vos connaissances (et elles sont souvent utiles!), pas de vos blabla!

    Merci à tous pour votre attention et/ou futures réponses.

    Julien

    -----

  2. #2
    invite29971eb1

    Re : Asservissement P.I.D. PIC16F876

    Citation Envoyé par Julien21000 Voir le message
    NB : Les éternels râleurs de forum (he oui y'en à toujours!), pas la peine de me dire "google est ton amis" ou autre ... j'ai fait bon nombre de recherches sans pouvoir avancer. On est ici pour de l'entraide alors faites part de vos connaissances (et elles sont souvent utiles!), pas de vos blabla!
    Ce n'est pas parce que tu as cherché que tu as forcément bien cherché.

    Je vais me reconnaître dans cette description (avec une certaine fierté ) mais quand perso j'affirme qu'on trouve tout en 3 secondes de Google, c'est que j'ai essayé juste avant pour être sur. Pour les autres râleurs, je te laisse te débrouiller avec eux...

    Que tu utilises le Timer ou le PWM, ça ne change pas grand chose, si ce n'est que par le timer, le micro a du code en plus à gérer.

    Concernant ton programme même, j'avoue m'y paumer totalement avec tes noms de variables pas très clairs.

    Il y a deux choses qui me choquent:
    Code:
    i16Cn = i8En0 + i16IntegralTerm + i16DerivativeTerm;			// Addition des termes
    	i16Cn = i16DerivativeTerm * i1Kp / 1024;
    Dans la première ligne (et ailleurs dans le prog d'ailleurs), tu ne peux pas mélanger impunément des nombres sur 8 bits et d'autres sur 16. Le compilateur risque de changer arbitrairement le type de ta variable résultat et donc fausser ton résultat. Dans la mesure du possible, il faut toujours travailler avec le même type ou forcer les casts (transtypages) pour éviter ce genre de problèmes

    Ensuite, tu calcules ici deux fois i16Cn, autrement dit, le premier calcul est jeté à la poubelle. Ta deuxième ligne ne devrait pas être plutôt?
    Code:
    i16Cn = i16Cn * i1Kp / 1024;
    Ce qui parait plus logique

  3. #3
    inviteeb160de1

    Re : Asservissement P.I.D. PIC16F876

    Verifier aussi que le compilo ne traite pas la division par 1024 comme une vulgaire division 16 bits (et donc complexe et longue sur un 16F), alors que de simples decalages vers la droite suffisent et prennent un minimum de temps de cycles.

    Aurélien

  4. #4
    invite0c083bae

    Re : Asservissement P.I.D. PIC16F876

    ftorama :
    remarqueS pertinentes !!! (même en râlant un peu )Erreur effectivement sur le calcul et changement de la variable de 16 à 8Bits sans faire attention. Effectivement généralement je fais gaffe de faire du transtypage pour ce genre de cas Merci

    Aurélien :
    Bonne remarque aussi!

    ça fait déjà quelques erreurs de corrigées, mais c'est dans le déroulement de la procédure de calcul du PID que je bloque.

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

    Re : Asservissement P.I.D. PIC16F876

    Bon, je suis toujours bloqué sur ce sujet. Ftorama si tes recherches ont été moins infructueuses que les miennes, je veux bien ce que tu as trouvé Merci

  7. #6
    invite29971eb1

    Re : Asservissement P.I.D. PIC16F876

    Citation Envoyé par Julien21000 Voir le message
    Bon, je suis toujours bloqué sur ce sujet. Ftorama si tes recherches ont été moins infructueuses que les miennes, je veux bien ce que tu as trouvé Merci
    3 secondes de Google :
    http://fribotte.free.fr/bdtech/PidSurPic/PidSurPic.html
    http://pobot.org/Asservissement-PID.html

    Ces deux sites-là, tu peux normalement y aller en toute confiance...

    L'algo du PID n'est pas compliqué en soit...

    Il faut tout d'abord baser tes calculs sur l'erreur de ton système, c'est-à-dire la différence entre la consigne et la sortie réelle

    n est l'échantillon actuel
    e(n)=s(n)-c(n);

    PWM(n)= Kp*e(n) + Ki*I(e(n)) - Kd*D(e(n))

    I(e(n)): l'intégrale, comme tu l'as calculée, la somme des erreurs, bornée à la capacité de ta variable, pour éviter les débordements

    D(e(n)): la dérivée: e(n)-e(n-1)

    Après, tu es libre de mettre ça à ta sauce, c'est à dire de tout englober sous le facteur Kp par exemple. Ça revient au même, Ki et Kd étant généralement réduits dans ce cas.

    Certains additionnent aussi le terme dérivé plutôt que de le soustraire...

    Certains mettent des seuils sur chaque action, mais là ça n'est plus vraiment du PID...

    Comme m'avait dit un chef de projet quand j'avais fait un stage justement sur du PID: "Tu peux chercher toutes les méthodes de calcul d'un PID, ça finira toujours en bidouillage des coeffs pour que ça marche"

Discussions similaires

  1. usart pic16f876
    Par invite9c84e471 dans le forum Électronique
    Réponses: 2
    Dernier message: 21/03/2010, 11h31
  2. pic16F876
    Par invite77e59936 dans le forum Électronique
    Réponses: 1
    Dernier message: 29/05/2009, 02h30
  3. pb CAN du PIC16f876
    Par invite0b61f2e8 dans le forum Électronique
    Réponses: 11
    Dernier message: 11/05/2008, 22h16
  4. Pic16f876
    Par invite0f39f32f dans le forum Électronique
    Réponses: 1
    Dernier message: 02/05/2006, 18h48
  5. PIC16F876
    Par inviteaaaccd27 dans le forum Électronique
    Réponses: 1
    Dernier message: 04/02/2004, 13h56
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...