Traitement de int et de float dans une equtation

Bonjour à tous,

Je dois reproduire cette equation sur Arduino

|433x500

Etant donné que le résultat de la première division va donné une chiffre après virgule, j'ai pensé mettre le résulta dans un float. Je pense que c'est fonctionnable, non?

Vin est egal à 3.3, alors j'ai aussi opté pour un float en parametre. Je me suis assi dit que je pouvais avoir 33 au lieu de 3.3, mais la division de vIn avec 1023 donnerai un chiffre avec virgule...

Est-ce que ca vous semble correct de mixer des float et des int? Ou si non, que suggeriez-vous pour mieux faire?

float measure_swp(int wmvalue, int soilTemp, float vIn, int res){
    Si.sprint(F("Analog value: "),2); Si.sprintln(wmvalue,2);
    
    float vOut = wmvalue * (vIn/1023.0);
    
    Si.sprint(F("vOut: "),2); Si.sprintln(vOut,2);
    
    float r_wm = res * (vIn/vOut);
    float rwm = r_wm/vOut;
    
    Si.sprint(F("rwm: "),2); Si.sprintln(rwm,2);
    
    // swp
    float v1 = 4.093 + 3.213 * rwm;
    float v2 = 1 - 0.009733 * rwm - 0.01205 * soilTemp;
    float v = -v1/v2;
    return v;
}

Merci

Pas de soucis de mixer, assurez vous d’avoir un float à droite du égal et pas que des entiers si vous voulez faire le calcul en float

Par exemple float x = 1/3;==> x sera égal à 0 car le calcul est évalué en entier, puis affecté au alors que si vous faites float x = 1.0/3;alors comme il y a un flottant à droite tout le calcul sera fait en flottant et x vaudra 0.333333333333

Attention un float n’est pas super précis sur un UNO et similaire (32 bits - comme les double). dans l’absolu conserver le plus longtemps possible la valeur entière originale et faire les transformations qu’à l’affichage ou que dans des calculs plus complexes nécessaires

On peut aussi bidouiller les équations et simplifier les calculs. Si on écrit la première sous la forme :

Vout = k * Vin

avec

k = reading / 1023

alors on peut simplifier la seconde en

Rwm = res * (1-k) / k

et

(1-k)/k = (1023 - reading) / reading

soit en final

Rwm = res * (1023 - reading) / reading

Vin a disparu de l'équation : c'est magique (mais c'est vrai) !

Donc en appliquant ce que dit J-M-L, tu calcules en int :

int A = res * (1023 - reading);

puis en float

float Rwm = float(A)/reading;

Je pense que ça devrait marcher.

lesept: Donc en appliquant ce que dit J-M-L, tu calcules en int :

int A = res * (1023 - reading);

res désignant la valeur d'une résistance, ce doit être un float.

Et puis la bonne méthode est : - faire d'abord un calcul "naturel", au plus simpe, en respectant la nature des constituants (dans les équations fournies, seul reading est un entier) - tester cela, - ensuite et [u]seulement en cas de besoin avéré[/u], faire des optimisations, où il est facile d'introduire des erreurs et qui rendent le code moins maintenable.

lesept: Donc en appliquant ce que dit J-M-L, tu calcules en int :

int A = res * (1023 - reading);

Attention si res est grand et reading petit devant 1023 alors le résultat le tient pas dans un int ==> passer sur un long

Selon le texte de pierrot10, les résistances sont en kOhms. res vaut 10. Je ne sais pas combien vaut reading, mais si c'est une valeur de mesure analogique, elle doit rester entre 0 et 1023, ce qui fait varier A entre 0 et 10230. Ça tient dans un int. (ceci sauf erreur de compréhension de ma part)

Merci pour vos réponses. Je n’ai pas encore eu le temps de me concentrer là dessus, mais je le ferai au plus tard ce soir :slight_smile:
Mais en tout, ca me semble bien parti!
:slight_smile:
Merci

Disons que si on regarde la formule (2)

pierrot10: |433x500

on peut effectivement conserver res et R[sub]wm[/sub] en kΩ puisque ce ne sont que des multiplications et auquel cas suivant le reste des valeurs ça peut tenir dans un int en sachant donc qu'il faut donc bien penser aux unités suivant ce que l'on fait de ces valeurs ensuite

lesept: Ça tient dans un int.

Qu'est-ce qui motive cet acharnement à jouer avec le feu ? A utiliser des entiers à tout prix ? A se préoccuper davantage de la [u]représentation[/u] d'une information que de sa [u]nature[/u] ? A mettre la physique au service des bits, plutôt que l'inverse ? Est-ce une réminiscence du temps où on programmait en assembleur ? Ou une obsession pour l'optimisation, même quand on en a pas besoin ?

Ouais, ça fait beaucoup de questions, mais là je ne vous suis pas !

Bonjour, je crois que le mieux est que je teste ceci (ce que je ne peux pas encore faire). Les propositions de simplification de lesept, il faudrait que les apppliques mais je ne suis pas convaincu qu'on puisse faire abstraction à Vin... A essayer

Dans tous les cas, je vais devoir traiter des résultats et ds chiffres à virgules, comme par exemple

(vIn/1023.0)

si vIn est egal à 3.3 qui est divisié par 1023, ou m'eme si on voulait traiter que des int

33 / 1023/ 10

le résultat aura une virgule, et je ne dois pas perdre cette virgule.Donc de suite, je serai confronter à un float.

Au passage res est egal à 10kho, donc il prend la valeur de 10000.

Il y a un point qui a particulièrement retenu mon attention

Attention un float n'est pas super précis sur un UNO et similaire (32 bits - comme les double)

Il faudrait comme même que j'aie une précision même si je ne vais pas régler une montre suisse.

Donc pour faire au mieux, en terme de précision, si les float ne sont pas précis, et les doubles aussi (si j'ai bien compris), est-ce que je devrait utiliser de long?

Corrigez-moi, si je me trompe , mais un long peux contenir un chiffre à virgule?

Non, un long c'est un entier sur 32 bits.

@Biggil : oui c'est vrai, j'ai des tendances maso parfois... :)

Pour les simplifications des formules, j'y peux rien, c'est juste des maths. Les formules telles qu'elles apparaissent dans la doc de Pierrot se simplifient ce qui fait que Vin n'y joue aucun rôle. Mais uniquement pour ces calculs : Vin a son rôle dans le montage électronique associé.