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

Calcul de flottants sous C18



  1. #1
    drache

    Calcul de flottants sous C18

    Bonjour

    Je ne sais pas si vous utilisez C18 de MPLAB mais je vous pose la question quand même des fois que le problème vienne d'ailleurs

    Je réalise une régulation PID pour moteur thermique et pour le calcul des différents termes du calcul j'utilise des variables de type float.
    Je travail sur un pic18F4550 et je vérifie chaque étape de mon calcul par la liaison USB via un programme développé sous delphi

    Voila l'algorithme de la régulation :

    Code:
      for(i=5;i>=1;i--) tab_erreur[i]=tab_erreur[i-1];    // sauvegarde de l'ancienne erreur, tableau FIFO
    
       tab_erreur[0] = consigne - RPM;                    // calcul de la nouvelle erreur
       som_erreur += (tab_erreur[0])*dt;                  // effectue la somme des erreurs depuis le début
       if (som_erreur>=limite_I) som_erreur=limite_I;    // limite le terme de l'intégral
       if (som_erreur<=(-limite_I)) som_erreur=-limite_I;    // limite le terme de l'intégral
       diff_erreur = (tab_erreur[0] - tab_erreur[4])/dt;    // calcul la différence entre l'erreur précédente et l'actuel
    
       P = kP * tab_erreur[0];                            // calcul le terme proportionnel
       I = kI * som_erreur;                            // calcul le terme intégrale
       D = kD * diff_erreur;                            // calcul le terme dérivé
    
    commande_AX12 += P + I + D;    // résultat final
    ou tab_erreur est un int,
    som_erreur et diff_erreur sont des float ainsi que P,I,D,
    et commande_AX12 est un int
    dt est une constante fixé à 0.005
    et limite_I à 1000

    hélas après avoir vérifié que tab_erreur fonctionné bien, som_erreur a un comportement assez particulier ainsi que som_erreur par la même occasion.
    som_erreur varie bien de -1000 a +1000 mais le comportement n'est pas normal, en négatif il varie très rapidement au début même avec une erreur = 1 puis en arrivant vers les positif une variation beaucoup plus lente voir inexistante au bout d'un moment puis des variations par pas, 8 16 32 64 128 257 513 1000.
    Pour diff_erreur je la voit toujours a 0

    En me renseignent un peut j'ai pu découvrir deux ou trois pistes,
    - le problème des float avec C18 qui serai codé différemment et donc serai mal converti lors de l'envoi au pc
    - le problème que je convertit ces float en int pour envoyer au pc
    - apparemment il existe un mode extended pour les 18F qui pourrait résoudre le problème de calcul de flottant mais que je ne peut pas utilisé car j'utilise un bootloader USB avec son propre LKR
    - un problème de calcul ou d'enchainement logique des opérations

    malgré toutes ces pistes je n'arrive pas a résoudre mon problème

    Merci de bien vouloir m'éclairer sur les calculs de nombres flottants

    Cordialement Zoïlo

    -----


  2. Publicité
  3. #2
    microchip

    Re : Calcul de flottants sous C18

    Bonjour,

    Le compilateur C18 est censé suivre le standard IEEE-754.

    Il semble cependant qu'il y ait peut-être une variation dans l'implémentation si on en croit le post de cet utilisateur (à vérifier ?) : http://www.gidforums.com/t-16044.html

    La norme IEEE-754 est expliquée ici : http://en.wikipedia.org/wiki/IEEE_754

    Je pense que cela peut aider de regarder si le codage des nombres faits par le compilateur est conforme.

    Dans le user guide du C18 qui se trouve ici : c:\MCC18\doc\hlpC18ug.chm on peut voir les limites utilisables par le compilateur ( chercher "Floating-point Types" )

    Bonne lecture
    Here to help ;=)

  4. #3
    Juliian

    Re : Calcul de flottants sous C18

    Avec un pseudonyme comme ceci, peut-on conclure que tu es une instance officielle de microchip ?

  5. #4
    drache

    Re : Calcul de flottants sous C18

    J'ais deja lu le lien que tu me propose

    malgré tout mon problème persiste, je n'arrive pas a comprendre si C18 fait tout les calculs en norme IEE ou si c'est dans sa propre norme, ensuite lorsque je l'envoi au pc je convertit ce chiffre en int, donc normalement que la partie entiere, avec (int)som_erreur mais je ne crois pas que le probleme vienne de la

    en effet le pc reçoit bien un entier entre 1000 et -1000 mais le problème est qu'il ne se realise pas comme il le faudrait,

    normalement avec une erreur faible som_erreur devrai varié tres faiblement quelque soit le valeur de som_erreur,
    hélas quand som_erreur et vers -1000 il varie très rapidement puis en s'aprochant de 0 sa variation devient tres lente puis en positif il varie par pas, 8, 16, 32, 64, 128... et ne bouge plus meme si l'erreur est de 10 par exemple, som_erreur reste a 8 puis l'erreur depasse 15 et alors som_erreur vaut 16 etc...

  6. #5
    drache

    Re : Calcul de flottants sous C18

    Voila un exemple, je demarre avec une som_erreur de -1000 ("RPM : ")
    je donne une erreur de +1 et voila ce que cela donne sans aucune autre variation de l'erreur
    entre chaque ligne j'ai un temps fixe donc au debut une variation rapide puis une variation tres lente

    comme si mon calcul ne fesais pas som_erreur= som_erreur + dt*erreur mais plutot som_erreur = dt*som_erreur +erreur

    Code:
    RPM : -1000
    RPM : -1000
    RPM : -923
    RPM : -839
    RPM : -763
    RPM : -683
    RPM : -603
    RPM : -523
    RPM : -477
    RPM : -437
    RPM : -397
    RPM : -355
    RPM : -317
    RPM : -275
    RPM : -246
    RPM : -225
    RPM : -205
    RPM : -186
    RPM : -166
    RPM : -145
    RPM : -127
    RPM : -116
    RPM : -106
    RPM : -96
    RPM : -87
    RPM : -77
    RPM : -67
    RPM : -60
    RPM : -55
    RPM : -50
    RPM : -45
    RPM : -40
    RPM : -35
    RPM : -31
    RPM : -28
    RPM : -26
    RPM : -23
    RPM : -21
    RPM : -18
    RPM : -16
    RPM : -14
    RPM : -13
    RPM : -12
    RPM : -11
    RPM : -9
    RPM : -8
    RPM : -7
    RPM : -7
    RPM : -6
    RPM : -5
    RPM : -5
    RPM : -4
    RPM : -3
    RPM : -3
    RPM : -3
    RPM : -3
    RPM : -2
    RPM : -2
    RPM : -2
    RPM : -1
    RPM : -1
    RPM : -1
    RPM : -1
    RPM : -1
    RPM : -1
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 0
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1
    RPM : 1

  7. A voir en vidéo sur Futura
  8. #6
    microchip

    Re : Calcul de flottants sous C18

    Bonjour,

    Ce que je te suggère c'est de comparer dans le détail le nombre binaire généré par le C18 pour un float et le nombre float obtenu d'après la norme IEEE 754 (il y a des exemples tous faits sur cette page : http://en.wikipedia.org/wiki/IEEE_754

    Je pense plutôt que tu as un problème de conversion dans ton programme sur le PC...mais il vaut mieux lever le doute immédiatement sur la représentation d'un float (la méthode pas à pas est toujours payante ;=)
    Here to help ;=)

  9. Publicité
  10. #7
    microchip

    Re : Calcul de flottants sous C18

    Citation Envoyé par Juliian Voir le message
    Avec un pseudonyme comme ceci, peut-on conclure que tu es une instance officielle de microchip ?
    Officielle oui mais mes réponses sont officieuses (elle n'engagent que moi) et tout humain est faillible
    Here to help ;=)

  11. #8
    drache

    Re : Calcul de flottants sous C18

    je ne comprend pas tout a fait ce que vous me demandé

    m'enfin par acqui de conscience j'ai donné a som_erreur differente valeurs flottante ou entiere et le pc me donne les bonne valeur entiere

  12. #9
    drache

    Re : Calcul de flottants sous C18

    Voila aussi une possibilité mais je ne peut pas l'apliquer parceque je travaille avec un bootloader USB et je n'arrive pas a passer en mode extended

    http://forums.futura-sciences.com/sh...ighlight=float

  13. #10
    drache

    Re : Calcul de flottants sous C18

    Pour la difference entre les flottants C18 et IEEE voir l'aide de C18 pour la librairie math.h et plus particulierement pour la fonction : ieeetomchp et mchptoieee

    eb f0 f1 f2
    IEEE-754 32-bit | seee eeee | exxx xxxx | xxxx xxxx xxxx xxxx
    Microchip 32-bit | eeee eeee | sxxx xxxx | xxxx xxxx xxxx xxxx

    s=sign bit e=exponent x=significand

    le probleme etant que je ne sait pas quand le format est celui de C18 ou du IEEE et puisque le pc donne les bons resultats je me pencherai plutot sur mon calcul

  14. #11
    drache

    Re : Calcul de flottants sous C18

    meme en reduisant mon calcul à som_erreur += tab_erreur[0] je me retrouve avec le meme comportement bien que les valeurs soit plus grande
    J'en suis venu au fait que le seul truc qui foire c'est le faite de reprendre la valeur de som_erreur pour l'aditionner avec autre chose

    mais meme en prenant la valeur de som_erreur et en la mettant dans une variable temporaire puis de faire le calcul j'obtient les memes resultats

  15. #12
    microchip

    Re : Calcul de flottants sous C18

    Citation Envoyé par drache Voir le message
    Pour la difference entre les flottants C18 et IEEE voir l'aide de C18 pour la librairie math.h et plus particulierement pour la fonction : ieeetomchp et mchptoieee

    eb f0 f1 f2
    IEEE-754 32-bit | seee eeee | exxx xxxx | xxxx xxxx xxxx xxxx
    Microchip 32-bit | eeee eeee | sxxx xxxx | xxxx xxxx xxxx xxxx

    s=sign bit e=exponent x=significand

    le probleme etant que je ne sait pas quand le format est celui de C18 ou du IEEE et puisque le pc donne les bons resultats je me pencherai plutot sur mon calcul
    Bonsoir,

    Je pense que les éléments que tu as trouvés éclairent le problème : le compilateur C18 suit donc bien la norme IEEE-754. Afin d'optimiser les temps de calculs, il convertit tout d'abord les float IEEE754 en float C18 (fonction ieeetomchp), il fait les calculs intermédiaires dans le format C18 puis reformate en IEEE754 par la fonction mchptoieee. Ceci permet de conserver la compatibilité ANSI-C et IEEE754 tout en optimisant le temps de calcul en fonction de l'architecture interne.

    Si ton PC donne le bon résultat c'est que le C18 envoie les floats au PC au format IEEE754.

    Poste ton projet en ZIP je pourrais jeter un oeil
    Here to help ;=)

  16. Publicité
  17. #13
    drache

    Re : Calcul de flottants sous C18

    J'ai definitivement cerner le probleme autour de l'adition entre som_erreur et erreur*dt
    car erreur*dt marche parfaitement

    le projet est costeau tout de meme, il contient plusieure sources dont la gestion d'un servomoteur AX-12, le calcul de RPM, la gestion de plusieur mode (Auto = envoi de la consigne des RPM par USB et respect de celle ci avec la PID, Manu = commande direct des gaz par un potar, Manu-Auto = consigne des RPM fixé par le potar et respect de celle ci par le PID)
    Le tout avec un bootloader USB et un futur affichage des rpm sur quatre digit 7 segments
    Actuelement il me reste plus que la PID a finir et a regler principalement apres ce sont des options

    Voici donc le projet complet, partie interressante dans le fichier interuption.c pour le PID et user.c pour l'envoi sur USB
    Fichiers attachés Fichiers attachés

  18. #14
    drache

    Re : Calcul de flottants sous C18

    voila une chose de faite

    lorsque l'on marque x=(int)som_erreur on ne convertit pas som_erreur en int lors du transfert mais on convertit som_erreur en int puis on le transfert dans x

    et donc mon probleme est résolu, a chaque fois que j'envoyai som_erreur je le convertissai en int et donc mon calcul suivant était faux

    il suffit donc de dire

    temporaire = som_erreur

    où temporaire est un float puis

    x = (int) temporaire

    où x est ma variable a envoyer

  19. #15
    drache

    Re : Calcul de flottants sous C18 [RESOLU]

    donc sujet resolu

  20. #16
    microchip

    Re : Calcul de flottants sous C18

    Salut,

    Bon travail d'analyse
    En C il faut toujours faire très attention au casting (quel format est utilisé dans les calculs intermédiaires).
    Il faut parfois caster de façon explicite pour éviter des troncations ou erreurs de formats sans assumer que le compilateur fait les conversions automatiquement.

    Un conseil de ma part : évite au maximum les calculs en float sur les 8 bits...C'est tout l'art de la programmation embarquée...Faire des opéations au maximum avec des nombres entier.
    Les temps de calculs sont super pénalisants en flottant. Il existe sur internet de nombreux exemples comment faire des divisions SANS utiliser des float tout en gardant une grande précision. Une bonne astuce est d'essayer d'avoir des divisions par des multiples de 2 car c'est très rapide et facile (décalages à droite). Exemple typique : quand on filtre un signal en additionant plusieurs échantillons, il vaut mieux ajouter 16 échantillons que 10...c'est beaucoup plus rapide à diviser ;=)

    D'autre part je te recommande de mettre tes variables dans la fenêtre WATCH et de sélectionner le mode d'affichage qui correspond au type de ta variable (ASCII, bin, dec,...)
    Here to help ;=)

  21. #17
    drache

    Re : Calcul de flottants sous C18

    Me revoila

    Finalement mon probleme ne venait pas du fait d'ecrire
    Code:
    x = (in) som_erreur
    car ce ne change pas le type de som_erreur

    le probleme venait d'ailleur mais je ne comprend pas exactement d'où

    lorsque j'écrit ce code cela marche, il faut que j'utilise une variable temporaire que j'initialise préalablement pour avoir un comportement normal

    Code:
           som_erreur = (tab_erreur[0])*dt+ temporaire_som;
    	temporaire_som = 0;
    	temporaire_som = som_erreur;
    donc sa marche mais je ne sait pas pourquoi

Sur le même thème :

Discussions similaires

  1. Calcul d'énergie sous Matlab
    Par DJDiablo31 dans le forum Électronique
    Réponses: 2
    Dernier message: 06/08/2008, 17h23
  2. Calcul d'aire sous Excel
    Par plug dans le forum Logiciel - Software - Open Source
    Réponses: 13
    Dernier message: 09/06/2008, 19h57
  3. calcul matriciel sous java
    Par ABN84 dans le forum Logiciel - Software - Open Source
    Réponses: 2
    Dernier message: 11/05/2007, 12h37
  4. [HELP!]PIC sous C18
    Par electromec2007 dans le forum Électronique
    Réponses: 3
    Dernier message: 15/04/2007, 16h19
  5. Pb de types C18 sur 18F - Resultat de calcul faux
    Par The Jack dans le forum Électronique
    Réponses: 14
    Dernier message: 12/04/2007, 21h32