[Arduino] Régulation pac
#61
Bon j'avais un doute depuis un moment sur le fonctionnement mais c'est confirmé, les valeurs négative foutent la merde, si je fais la formule
à partir des valeurs positives j'ai des résultats cohérents mais dès que j'intègre une négative ça part complètement en sucette ...

Genre je passe de 8.66°C calculé pour 9.03°C réel à 599°C ... Pourtant j'utilise la même méthode :
( oui j'ai converti les nombres avec exposants pour les avoir complets, donc oui j'ai trouvé la solution à mon ignorance haha )

Code :
    // Logarithmique ( temp positive )
    //return (36.276f*log(x)) - 197.28f;

    // Polynomial Ordre 3 ( temp positive )
    return ((-44.2f) + (0.256f*x) + ((-0.000306f)*pow(x,2)) + (0.000000164f*pow(x,3)));

    // Polynomial Ordre 3 ( temp positive + negative )
    //return (0.0000003f*pow(x,3)) - (0.0005f*pow(x,2)) + (0.3564f*x) - 57,599;


Mais du coup c'est pourquoi, mauvaise formule généré par excel ? Incompatibilité arduino ? :/
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#62
Juste une chose : quand la PAC sera terminée, prévoit un aménagement pour les futurs fluides, 2050 ça arrive vite ... ;-)
Répondre
#63
Ahaha spèce d'enfoiré ! lol


Je viens de me rendre compte que la formule générée par Google Sheets et excel ne donnait pas le même résultat

Sheet : ((-44.2f) + (0.256f*x) + ((-0.000306f)*pow(x,2)) + (0.000000164f*pow(x,3))) => 8.66°C
Excel : (0.0000002f*pow(x,3)) - (0.0003f*pow(x,2)) + (0.2576*x) - 44.42f => 10.33°C


Bizarre bizarre !
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#64
Bon j'ai fais plusieurs essais, j'ai des résultats satisfaisant pour la BP mais pas du tout pour la HP, plus j'essaie de monter dans la
précision avec la courbe polynomial et plus ça fait de la merde bizarrement ...


.png   tableau_courbe_134.PNG (Taille : 167.67 Ko / Téléchargements : 6)

Et les formules liées :

Code :
float correction_BP(float x)
  {   
    // Logarithmique ( temp positive ) ( Excel )
    return (36.276f*log(x)) - 197.28f;
   
    // Polynomial Ordre 3 ( temp positive ) ( Sheet )
    //return -44.2f + (0.256f*x) + ((-0.000306f)*pow(x,2)) + (0.000000164f*pow(x,3));
  }

float correction_HP(float x)
  {
    // Logarithmique ( temp positive ) ( Excel )
    return (56.321f*log(x)) - 282.86f;
   
    // Polynomial Ordre 3 ( Excel )
    //return (0.0000005f*pow(x,3)) - (0.0009f*pow(x,2)) + (0.6139f*x) - 78.267f;

    // Polynomial Ordre 4 ( sheet )
    //return -157 + (1.39f*x) + (-0.00361f*pow(x,2)) + (0.00000446f*pow(x,3)) + (-0.00000000206f*pow(x,4));

    // Polynomial Ordre 5 ( excel )
    //return (0.000000000008f*pow(x,5)) - (0.00000002f*pow(x,4)) + (0.00002f*pow(x,3)) - (0.0113f*pow(x,2)) + (3.0051f*x) - 286.11f;
  }


Si quelqu'un a une idée, je suis preneur ... Jap
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#65
rajoute (float) just avant pow() (il retourne un double, donc si tu veux être sûr de ce que fait le compilo rajoute le cast).

Mais je pense que ton pb est plus simple: est-ce que la valeur calculée est dans l'interval des valeurs mesurées utlisées pour fair la courbe ? ou bien elle tombe en dehors ?

Parce que les courbes polynomiales ne font pas juste un arc, je soupçonne qu'elle diverge fortement en dehors de ton lot de valeurs.
Congratulations !!! You've just created a temporal loophole... Mon site | Mon forum
Répondre
#66
Mêmes résultats avec les pow() entre des float(), donc ça a pas l'air de le gêner.


Justement pour les valeurs de "pression rel" et "Temp" sont des valeurs réelles du fluides frigorigène, ce sont donc théoriquement des points
de référence fiable, donc les résultat sont en dessous de 0.5K de delta pour la BP mais la HP ça part en sucette.

Mais oui, plus je montre le degré de la courbe et plus celle-ci est proche des points mais les résultat eux partent à l'opposé c'est ça que
je comprend pas, tu chercher à augmenter la précision mais tu la détruit à la place ...

Par exemple là, tu a la courbe en logarithmic à gauche et en polynomial degré 6 à droite, on voit que le tracé est propre et très proche
des points mais quand je l'utilise je me retrouve avec des valeurs genre 588°C ...


.png   courbe_hp_134_loga_poly.PNG (Taille : 58.85 Ko / Téléchargements : 5)
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#67
Ok, donc je pense que c'est le manque de précision des flottants (et en plus n'oublies pas que la puissance 6 est extrêmement élevée et à ce stade c'est quasi certain que tu overflow). Donc restes sur des exposants assez faibles avec des coefs assez gros, et/ou passe en virgule fixe avec des entiers, et/ou osef de 0.5 °C parce que ton capteur va probablement dériver plus que ça sur le long terme de toute façon.
Congratulations !!! You've just created a temporal loophole... Mon site | Mon forum
Répondre
#68
Hum donc ça serait l'arduino qui n'arriverait pas à suivre derrière ? Je peux essayer avec des entiers mais pas osef de la précision non, sur une
fonction de thermostat tu peux te le permettre mais pas sur une détente électronique, c'est comme si te me disais "osef de la lambda" sur une voiture Tongue


D'ailleurs j'avais essayé d'utiliser la fonction exp() pour éviter de devoir convertir mais dans un serial.print ça me retournait un nombre genre 1.23 et c'est tout
du coup ça bouffait tout ce qui se trouve après ...
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#69
Le pb là spa l'arduino c'est les types. Un flottant a une précision limitée. Et quand t'as du cube ou plus tu perds aussi en précision, voir tu overflow. Un float c'est codé sur 32 bits, comme un long, autrement dit seulement environ 4 milliards de valeurs possibles.

Un truc que tu peux faire pour augmenter la précision sans passer en virgule fixe c'est multiplier les coefs et en même temps diviser les variables pour garder les ratios égaux tout en ayant des chiffres pas trop grands ou trop petits.

Par ex, au lieu d'avoir:

Code :
x = 123.456;
y = 0.00000123 * x * x;

Tu peux faire:

Code :
x = 123.456;
x /= 100.0f;
y = 0.0123 * x * x;

//

Nan t'as pas compris: être en virgule fixe avec des entiers ne veut pas dire que t'as pas de décimales, ça veut juste dire que t'utilises des entiers pour stocker des nombres décimaux avec un nombre fixe de décimales, au lieu d'avoir une virgule flottante. Dans la plupart des cas c'est plus opti et plus précis mais ça demande plus d'efforts de la part du développeur.

Par exemple tu peux décider de tout stocker avec 3 décimales après la virgule donc 123.456 devient 123456. T'as juste à diviser par 1000 au dernier moment pour l'affichage si besoin, mais jamais dans les calculs qui restent en entiers purs. Il faut faire gaffe à pas overflow par contre parce que les nombres peuvent vite devenir grands, surtout avec du carré et cube.

//

Ben regarde ce que fait une fonction avant de l'utiliser aussi, ça peut servir...
Congratulations !!! You've just created a temporal loophole... Mon site | Mon forum
Répondre
#70
et même en cours tu peux décaler en virgule pour éviter l'OF, faut garder une autre variable qui garde en mémoire tes manipulations de virgule ^^ VariableX= 2134 VirguleX = 2 par ex ... de plus les calculs en ENTiers sont plus rapides ^^
Répondre
#71
Hum du coup tu divise les valeurs par 100, ça veut dire qu'il faudra multiplier le résultat aussi par 100 pour retrouver la bonne valeur ? J'ai du mal
à voir comment tu augmente la précision en réduisant des nombres du coup, en plus si tu divise une valeur ça veut dire que tu dois le faire sur toutes non ?


Et pour les entiers, si si j'avais bien compris, on en parlent peut être pas de la même manière mais c'est une méthode que j'avais essayé mais comme les
formules n'étaient pas au point les résultats non plus, mais par exemple j'avais viré les virgules dans les mapf().
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#72
non c'est l'inverse t'as 1.001 donc en entier 1001 et virgule 3 (10^3) 1³0²0¹1 > 1001/1000=1.001 en fin de formule

par contre tout ce qui est fonction genre Log t'es obligé de calculer en valeur réelle Log(1001) c'est pas Log(1.001)
Répondre
#73
Tu m'as largué là ... Tu sors un "virgule 3" de nul part et après 10^3, erreur d'écriture ?

Du coup si tu divise certaines valeurs dans une formule polynomial mais que tu ne peux pas le faire sur les valeurs avec des fonctions
tu va forcément fausser ton résultat non ?
T'as un problème, t'veux un ban ?  Ohgod
Répondre
#74
Ma proposition avec l'exemple de code est différente de la virgule fixe avec des entiers. C'est une solution intermédiaire.

Je divise par 100 la variable mais je multiplie par 10000 le coef car 100² = 10000 et la variable est au carré. Si elle était au cube il faudrait multiplier le coef par 100³ soit 1000000.

//

Concernant la virgule fixe avec des entiers c'est un poil plus complexe. Il faut choisir combien de décimales tu veux conserver et multiplier toutes tes variables et constantes par 10 puissance le nombre de décimales ce qui permet de tout stocker dans des entiers (il faudra probablement des long au lieu d'int pour pas overflow).

Tout tes calculs se font avec ces variables, tu peux evidemment les passer aux fonctions, etc... à l'exception de log() (ou autre fonction où l'ordre de grandeur importe, mais y'en a pas 36 et tu ne devrais pas en avoir besoin pour ce que tu fais à priori) à part ça le seul moment où t'as besoin de les diviser par le même facteur que t'as utilisé avant c'est pour les humains. Tu peux aussi changer les unités (par exemple si t'as tout multiplé par 1000 tu peux afficher des m°C au lieu de °C) pour pas te faire chier à diviser si tu préfères.

//

Tu peux mélanger les deux techniques précédentes (passer en virgule fixe + changer les ordres de grandeurs pour les polynomes pour augmenter le nombre de décimales effectives) mais ça devient plus complexe, y'a plutôt intérêt à mettre des commentaires si tu fais ça.
Congratulations !!! You've just created a temporal loophole... Mon site | Mon forum
Répondre