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 ---
- 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 ---
Modérateur : Jérémy
Problèmes de compatibilité de types avec les multiplications.
-
Superphénix
Débutant- Messages : 54
- Enregistré en : mars 2020
Bonjour
Ça fait un jour que j'essaye de résoudre et de comprendre un problème avec des histoires de compatibilité de types en faisant des essais et je vais devenir fou. Du coup je vais plutôt poser la question ici.
Je suis toujours sur la programmation d'un PIC18LF2620 pour faire marcher un capteur de type MS5837-02BA21.
Là je suis sur la partie calculs pour compenser l'erreur en fonction de la température en suivant plus ou moins ce qui est donné dans le datasheet.
Pour la partie "Pressure and temperature calculations: first order" je pense avoir réussit, puisque j'obtiens des valeurs crédibles.
Pour la partie "Second order", j'ai que des valeurs du genre 4.294.846.294 au lieux de quelque chose comme 101435 mBARx100 par exemple.
Je pense que le problème est au niveau de la ligne "Ti = (dT*dT*11)>>35 ;". Ti est de type long long et dT long.
En décomposant (de façon un peu abusé) en :
pour tester, j'obtiens des valeurs plus crédibles sur dT mais, je suis pas sur d'avoir compris ce qui se passe et si les valeurs "crédibles" sont aussi les bonnes.
Voilà ce que j'ai fais pour l'instant :
Ça fait un jour que j'essaye de résoudre et de comprendre un problème avec des histoires de compatibilité de types en faisant des essais et je vais devenir fou. Du coup je vais plutôt poser la question ici.
Je suis toujours sur la programmation d'un PIC18LF2620 pour faire marcher un capteur de type MS5837-02BA21.
Là je suis sur la partie calculs pour compenser l'erreur en fonction de la température en suivant plus ou moins ce qui est donné dans le datasheet.
Pour la partie "Pressure and temperature calculations: first order" je pense avoir réussit, puisque j'obtiens des valeurs crédibles.
Pour la partie "Second order", j'ai que des valeurs du genre 4.294.846.294 au lieux de quelque chose comme 101435 mBARx100 par exemple.
Je pense que le problème est au niveau de la ligne "Ti = (dT*dT*11)>>35 ;". Ti est de type long long et dT long.
En décomposant (de façon un peu abusé) en :
Code : Tout sélectionner
var_inter64 = (long long)dT*(long long)dT ;
var_inter64 = var_inter64*11 ;
var_inter64 = var_inter64>>35 ;
Ti = var_inter64 ;
pour tester, j'obtiens des valeurs plus crédibles sur dT mais, je suis pas sur d'avoir compris ce qui se passe et si les valeurs "crédibles" sont aussi les bonnes.
Voilà ce que j'ai fais pour l'instant :
Code : Tout sélectionner
unsigned long long C1=0, C2=0, C3=0, C4=0, C5=0, C6=0 ; // 64 Bits + , Normalement 16Bits mais ici 64 pour les calculs par la suite.
signed long long OFF=0, OFF2=0, SENS=0, SENS2=0, Ti=0, var_inter64=0 ; // 64 Bits ±
signed long dT=0, TEMP=0, TEMP2=0, OFFi=0, SENSi=0, P=0 ; // 32 Bits ±
__uint24 D1=0, D2=0, P2=0 ; // 24 Bits +
Code : Tout sélectionner
write_MS5837(0x1E) ; // RESET MS5837
C1 = read_MS5837(0b10100010, 2) ; // C1
C2 = read_MS5837(0b10100100, 2) ; // C2
C3 = read_MS5837(0b10100110, 2) ; // C3
C4 = read_MS5837(0b10101000, 2) ; // C4
C5 = read_MS5837(0b10101010, 2) ; // C5
C6 = read_MS5837(0b10101100, 2) ; // C6
C5 = C5<<8 ;
C2 = C2<<17 ;
C1 = C1<<16 ;
Code : Tout sélectionner
while(1)
{
D1 = read_MS5837(0x4A, 3) ; // D1, OSR=8192
D2 = read_MS5837(0x5A, 3) ; // D2, OSR=8192
// T° et P au 1er ordre :
dT = D2 - C5 ;
TEMP = ((C6*dT)>>23) + 2000 ;
OFF = C2 + ((C4*dT)>>6) ;
SENS = C1 + ((C3*dT)>>7) ;
// T° et P au 2nd ordre :
if(TEMP>=2000)
{
P = (((D1*SENS)>>21) - OFF)>>15 ;
}
else
{
Ti = (dT*dT*11)>>35 ;
var_inter64 = TEMP-2000 ;
var_inter64 = var_inter64 * var_inter64 ;
OFFi = (31*var_inter64)>>3 ;
SENSi = (63*var_inter64)>>5 ;
OFF2 = OFF - OFFi ;
SENS2 = SENS - SENSi ;
TEMP = TEMP - Ti ;
P = ((((D1*SENS2)>>21) - OFF2)>>15) ;
}
}
Problèmes de compatibilité de types avec les multiplications.
Hello,
J'ai pas tout lu, une première info.
Lorsqu'on fait R = A*B, le langage C commence par évaluer l'expression A*B sans tenir compte de R, puis il fait R = valeur obtenue.
Pour calculer A*B, il prend la taille maxi de A et B. Si A est un int et B un long, il calcule un long, avec éventuellement un débordement si le résultat ne rentre pas dans un long. Ensuite il met le résultat dans R, résultat faux s'il y a eu débordement.
Il faut toujours gérer soi même les éventuels débordements, avec un cast explicite :
long long R = (long long)A * B;
Ou avec une conversion implicite :
long long R = A; R = R * B;
Il y a peut être des petites différences selon les versions de C, mais en gros cela marche comme ça.
J'ai pas tout lu, une première info.
Lorsqu'on fait R = A*B, le langage C commence par évaluer l'expression A*B sans tenir compte de R, puis il fait R = valeur obtenue.
Pour calculer A*B, il prend la taille maxi de A et B. Si A est un int et B un long, il calcule un long, avec éventuellement un débordement si le résultat ne rentre pas dans un long. Ensuite il met le résultat dans R, résultat faux s'il y a eu débordement.
Il faut toujours gérer soi même les éventuels débordements, avec un cast explicite :
long long R = (long long)A * B;
Ou avec une conversion implicite :
long long R = A; R = R * B;
Il y a peut être des petites différences selon les versions de C, mais en gros cela marche comme ça.
Problèmes de compatibilité de types avec les multiplications.
Problèmes de compatibilité de types avec les multiplications.
-
Superphénix
Débutant- Messages : 54
- Enregistré en : mars 2020
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 106 invités