Afficher des résultats de calcul par rapport à des potentiomètres

Bonjour,
J'essaie en vain d'afficher des valeurs bien spécifiques sur le moniteur série en fonction des valeurs de deux potentiomètres. Le programme doit toujours afficher les valeurs d'un potentiomètre en fonction de l'autre dans un intervalle de 100 pourcents. Par exemple si le premier potentiomètre est tourné à fond de sorte à faire 0 pourcents tandis que l'autre n'est tourné ne serait-ce qu'un peu alors le deuxième est à 100 pourcents, si les deux potentiomètres sont tous les deux tournés à moitié alors les valeurs qui doivent être affichées sont pour tous les deux 50 pourcents, etc. Le problème est que sur le moniteur, les valeurs n'affichent mystérieusement que -100 ou 0 pourcents.

J'ai également tenté d'attribuer une fonction à chacun des potentiomètres pour le calcul dans le programme suivant sans succès:

int valPot2=0;
int valPot3=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  valPot2=analogRead(A1);
  valPot3=analogRead(A2);
 
  int valBleu=map(valPot2,0,1023,0,100);
  int valRouge=map(valPot3,0,1023,0,101);
  int pourcentageRouge=calcul(valBleu,valRouge);
  int pourcentageBleu=calcul2(valRouge,valBleu);
  Serial.print("Bleu: ");
  Serial.print(pourcentageBleu);
  Serial.print("%");
  Serial.print("         ");
  Serial.print("Rouge: ");
  Serial.print(pourcentageRouge);
  Serial.println("%");
  delay(700);
}
int calcul(int nb1,int nb2){
    //utilisation de variables dans la fonction
    int res=(nb1/(nb1+nb2))*100;
    return res;
}
int calcul2 (int nb3,int nb4){
    //utilisation de variables dans la fonction
    int res2=(nb3/(nb3+nb4))*100;
    return res2;
}

Le montage utilisé est le suivant:

Quelqu'un aurait-il une idée de comment solutionner ce problème svp ?

Cordialement

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Faites vos calculs en utilisant des float ou double au lieu de int

1 Like

Et comprendre la différence en C/C++ entre une division entre entiers et une division entre réels.

PS : Prend l'habitude de choisir 115200 pour Serial.begin(115200);
Là tu n'aura pas de problème, mais il y aura des fois où 9600 ralentiront le programme et tu pourrais perdre des informations.
N'oublie pas de changer aussi le débit dans le moniteur sinon tu auras des caractères illisibles.

1 Like

calcul() et calcul2() font exactement la même chose.

2 Likes

Bonsoir
J'ai modifié le programme suivant toutes les suggestions de vous autres et le programme fonctionne comme voulu. Merci à tous.

float valPot2=0;
float valPot3=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  valPot2=analogRead(A1);
  valPot3=analogRead(A2);
 
  float valBleu=map(valPot2,0,1023,0,100);
  float valRouge=map(valPot3,0,1023,0,101);
  float pourcentageRouge=calcul(valBleu,valRouge);
  float pourcentageBleu=calcul(valRouge,valBleu);
  Serial.print("Bleu: ");
  Serial.print(pourcentageBleu);
  Serial.print("%");
  Serial.print("         ");
  Serial.print("Rouge: ");
  Serial.print(pourcentageRouge);
  Serial.println("%");
  delay(700);
}
float calcul(float nb1,float nb2){
    //utilisation de variables dans la fonction
    int res=(nb1/(nb1+nb2))*100;
    return res;
}

Cordialement

  • Et si nb1 et nb2 valent 0 que vaut la division ?

  • Vous retournez un entier, autant déclarer la fonction comme il faut ainsi que vos variables pourcentage

Je vois des choses bizarres entre les entiers et les réels. la fonction map retourne un int qui est rangé dans un float. Derrière calcul travaille sur des float, convertit le résultat en int (dans res) puis reconvertit le tout en float. A priori, j'aurais fais tous les calculs en float quitte à arrondir en fin (avec round et pas avec trunc comme ici), ou bien je n'aurais fait le calcul en float juste dans calcul.

Je n'ai jamais aimé map qui travaille sur des long. Au lieu de
float valBleu=map(valPot2,0,1023,0,100);
qui travaille sur des entiers, j'utiliserais
float valBleu=valPot2*100.0/1023;
qui travaille sur des float (je crois que c'est plus rapide en plus)

Je ne comprends pas bien pourquoi il y a un 101 dans map et pas 100.

Enfin pourquoi faire deux fois le calcul alors que normalement on pourrait avoir
pourcentageRouge = 100.0 - pourcentageBleu;

Si les pourcentages doivent être entiers, quel est l'utilité de les mettre dans des float?

En lisant le programme, j'ai l'impressions que les deux pourcentages sont toujours entiers, mais que la somme des deux ne fait pas forcément 100.

Mais est-ce possible?

Suivant le code oui


  valPot2=analogRead(A1);
  valPot3=analogRead(A2);
 
  float valBleu=map(valPot2,0,1023,0,100);
  float valRouge=map(valPot3,0,1023,0,101)

On se demande aussi pourquoi 101 dans le second map()

Dans les essais il y a des chances que l'analogRead n'aille jamais ni à 0 ni à 1024.

1024 c’est sûr :wink:

Emporté par mon élan.... 1023!

Bonjour

float calcul(float nb1,float nb2){
    //utilisation de variables dans la fonction
    int res=(nb1/(nb1+nb2))*100;
    return res;
}

Si nb1 et nb2 valent 0 alors je dois voir s'afficher sur le moniteur 0 pour "pourcentageRouge" et "pourcentageBleu". Lorsque je tente le programme suivant:

int valPot2=0;
int valPot3=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  valPot2=analogRead(A1);
  valPot3=analogRead(A2);
 
  int valBleu=map(valPot2,0,1023,0,100);
  int valRouge=map(valPot3,0,1023,0,101);
  int pourcentageRouge=calcul(valBleu,valRouge);
  int pourcentageBleu=calcul(valRouge,valBleu);
  Serial.print("Bleu: ");
  Serial.print(pourcentageBleu);
  Serial.print("%");
  Serial.print("         ");
  Serial.print("Rouge: ");
  Serial.print(pourcentageRouge);
  Serial.println("%");
  delay(700);
}
int calcul(int nb1,int nb2){
    //utilisation de variables dans la fonction
    int res=(nb1/(nb1+nb2))*100;
    return res;
}

rien ne s'affiche dans le moniteur série.
Lorsque je tente le programme suivant:

float valPot2=0;
float valPot3=0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  valPot2=analogRead(A1);
  valPot3=analogRead(A2);
 
  float valBleu=valPot2*100.0/1023;
  float valRouge=valPot3*100.0/1023;
  float pourcentageRouge=calcul(valBleu,valRouge);
  float pourcentageBleu=calcul(valRouge,valBleu);
  Serial.print("Bleu: ");
  Serial.print(pourcentageBleu);
  Serial.print("%");
  Serial.print("         ");
  Serial.print("Rouge: ");
  Serial.print(pourcentageRouge);
  Serial.println("%");
  delay(700);
}
float calcul(float nb1,float nb2){
    //utilisation de variables dans la fonction
    int res=(nb1/(nb1+nb2))*100;
    return res;
}

il est cette fois impossible d'obtenir 50 pourcents des deux cotés et des "nan" s'affichent dans le moniteur série à la place des 0.

Il y a un 101 dans map car à cet endroit il y a un mystérieux décalage que moi même ne comprend pas lorsque j'ai fait quelques tests au préalable pour créer le programme, les chiffres ne s'affichant que de 0 à 99 alors que je veux que les chiffres s'affichent de 0 à 100. Je suis entrain de construire un programme étape par étape. Les prochaines étape seront de faire fonctionner ce présent programme en le combinant avec un autre relatif aux moteurs pas à pas dont j'ouvrirai un autre sujet. Puis l'étape suivante sera de "capturer" ces valeurs dans le moniteur à un moment ou l'on appuie sur un bouton poussoir pour faire tourner les moteurs pas à pas par rapport aux valeurs capturées. C'est pourquoi je souhaite retourner un int pour éviter d'avoir des chiffres après la virgule instables dans le moniteur qui complexifieraient davantage le programme. Je reste ouvert à toute suggestion pour simplifier le code

Cordialement

un truc comme ça ?

const byte pinPotRouge = A1;
const byte pinPotBleu  = A2;

// à adapter par rapport à la course de votre potentiomètre rouge
const int minPotRouge = 0;
const int maxPotRouge = 1023;

// à adapter par rapport à la course de votre potentiomètre bleu
const int minPotBleu = 0;
const int maxPotBleu = 1023;


int ratio(int nb1, int nb2) {
  if ((nb1 == 0) && (nb2 == 0)) return 0;
  return (100.0 * nb1) / (nb1 + nb2);
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  int bleu = constrain(map(analogRead(pinPotBleu), minPotBleu, maxPotBleu, 0, 100), 0, 100);
  int rouge = constrain(map(analogRead(pinPotRouge), minPotRouge, maxPotRouge, 0, 100), 0, 100);
  Serial.print("Rouge: "); Serial.print(ratio(bleu, rouge));  Serial.print("%\t");
  Serial.print("Bleu: ");  Serial.print(ratio(rouge, bleu)); Serial.println("%");
  delay(1000);
}

tapé ici donc à tester

il faut faire avant un petit programme qui lit et affiche la valeur de analogRead() au min et max de vos potentiomètres et rentrer ces valeurs dans cette partie

// à adapter par rapport à la course de votre potentiomètre rouge
const int minPotRouge = 0;
const int maxPotRouge = 1023;

// à adapter par rapport à la course de votre potentiomètre bleu
const int minPotBleu = 0;
const int maxPotBleu = 1023;
1 Like

Bonsoir,
Ce programme proposé fonctionne bien. Je vais le garder. Merci infiniment

Cordialement

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.