Aide pour conversion d'une valeur analogique en pourcentage

Bonjour,

Je suis sur un projet de serre régulée via Arduino,
j'ai pour le moment plusieurs programmes qui fonctionnent a savoir:
lecture affichage d'un capteur température et humidité sur LCD avec déclenchement de relais en fonctions des valeurs.
mais la je viens de finir un code pour l'humidité du sol avec un capteur capacitif et affichage sur LCD par contre j'aimerai avoir un affichage de type pourcentage la les valeurs sont comprises entre 400 et 800

est que quelqu'un peut m'expliquer comment faire (je ne cherche pas forcement un code tout fait le but c'est de comprendre afin de pouvoir appliquer dans d'autres projets :slight_smile: )

include <LiquidCrystal_I2C.h>

//YOUTUBE THONAIN TRONIK AVENTUR ARROSAGE AUTOMATIQUE

LiquidCrystal_I2C lcd(0x27, 16,2); 
int Relais_Pompe = 4;
int capteuranalogique = A1;
//int capteurnumerique = A0;
int sensorValue1 = 0;
int sensorValue2 = 0;
int maxi = 1023; // pour avoir toute la fenetre du traceur série 
int mini = 0; // pour avoir toute la fenetre du traceur serie
void setup() {
lcd.begin();
pinMode(Relais_Pompe, OUTPUT); // broche d'alimentation du relais
pinMode(8, OUTPUT); // broche d'alimentation de la sonde
Serial.begin(9600); // SI ON VEUT VOIR LE TRACEUR SERIE
digitalWrite(Relais_Pompe, HIGH);
digitalWrite(8, LOW); // met la sonde hors tension - protection oxydation
}
void loop() {
//digitalWrite(8, HIGH); // remet la sonde hors tension pendant temporisation pour protection oxydation  
//for(int temporisation = 0; temporisation <= 8640 ; temporisation = temporisation+1) // mettre 8640 !
{
delay(10000); // cette boucle for protège la sonde car ne fait qu'une mesure par 24h
}
digitalWrite(8, HIGH); // met la sonde sous tension
delay(1000);
sensorValue1 = analogRead(capteuranalogique); // mesure humidité
//gestion affichege lcd
 
  lcd.setCursor(0, 0);
  lcd.print("Hum.Sol = ");
  lcd.print(sensorValue1);
  lcd.print(" % ");


//sensorValue2 = analogRead(capteurnumerique);
Serial.print(maxi);
Serial.print(" ; ");
Serial.print(mini);
Serial.print("  ;  VALEUR ANALOGIQUE = ");
Serial.print(sensorValue1);
//Serial.print("  ; VALEUR NUMERIQUE = " );
//Serial.println(sensorValue2);
// si sensorValue1 est supérieur au seuil sec
  if (sensorValue1 > 600) {
  Serial.println(" TROP SEC - ACTIVATION ARROSAGE ");
  for(int arrosage = 1 ; arrosage <= 10 ; arrosage = arrosage+1) // cycle maxi de 10 tests + arrosage
     {
     sensorValue1 = analogRead(capteuranalogique); 
     if (sensorValue1 > 600) {
        Serial.print(arrosage);
        Serial.print(" arrosage ");
        Serial.print(" ; ");
        Serial.println(sensorValue1);
        digitalWrite(Relais_Pompe, LOW); 
        delay(2000); // durée fixe activation pompe
        digitalWrite(Relais_Pompe, HIGH); 
        delay(10000); // pause pompe pour laisser a l'eau le tps de pénétrer la terre  
        }
      else
      {     
      Serial.println(" FIN CYCLE ARROSAGE ");    
      }
     }
  }
}

(post deleted by author)

...
Je vais un peu plus préciser mon dilemme. Oui je sais ce qu est un pourcentage merci pour le lien wiki

Top merci toon,
Je viens de lire ton message la fonction map doit pouvoir faire ce que je veux, je test et je vous confirme ça merci.

Oui je sais ce qu est un pourcentage

Dans ce cas, il n'y a pas de raison qui t'empêche de le programmer, en utilisant simplement des additions / multiplications / divisions.
Ou bien , pour ne pas le programmer toi-même, utiliser lea fonction map() comme te t'indique to0n7 ci-avant, et dont tu trouveras la documentation sur le site arduino.cc

Sérieusement, vous avez pas débuter un jours ??
Avant de demander j ai cherché mais je juste pas pensé à cette fonction, je rappel quand même que le but d un forum a la base est le partage et l entraide, si ce forum n est que pour les utilisateurs confirmés et que des demande de débutant vous saoul affiché le ou ne leur répondez pas tout simplement.
Je pe se avoir fait une demande polie pas un post à base de "help, refilezmoi un code tout fait".
Si toon m avait juste dit regarde la fonction map ça m aurait suffit je serai allé me documenter sur cette fonction et aurait tenté moi même après..

Il n'y a même pas besoin de fonction map !
Soit deux nombres A et B
Si A >B le résultat A/B donnera 1,xyz
SI A<B le résultat de A/B donnera 0, ijk

Dans le premier cas tu obtiens le pourcent en soustrayant 1 au résultat, dans le deuxièmme en soustrayant le résultat de 1 et en multipliant par 100.

A>B P= (1,xyz - 1) * 100 = xy,z %
A>B P= (1 - 0,ijk) * 100 = ij,k %

A = 12 B=11
A/B = 1,0909 => en pourcent 9,09 %

A= 11 B =12
A/B = 0,9167
1 - 0,9167 = 0,0833 => en pourtcent 8,33 %

Il ne reste plus qu'à traduire en ligne de code.

C'est quand même de l'arithmétique de base du niveau du collège, pas la peine de chercher des excuses parce que tu débutes en programmation.
Reconnais que tu as bien cherché les réponses que tu as obtenu.

Pas envi d épiloguer la dessus, mais je ne pense pas que les calculs que tu viens de me démontrer soit de niveau collège (je ne connaissait pas cette méthode mais mes étude remonte à 20 ans et je ne suis sûrement pas aussi bon que vous) mais bon.
Mais en ayant adapter la fonction map j ai les valeurs qui varient de 0 à 99%, donc oui j' ai résolu mon problème mais j'ai surtout compris comment utiliser cette fonction, donc je n aurais pas à reposer une question comme celle ci...
Et je ne me cherche pas d excuse, j ai un problème je ne trouves pas donc oui je me tourne vers le forum ou des gens compétent serons capables de m expliquer.
Je vous renvoi aussi ce lien:

Si partager vos connaissances ou aider un débutant ne vous intéresse pas ne le faites simplement pas et répondez aux sujets qui présentent un intérêt à vos yeux.
Je vous souhaite une bonne soirée mais vous donnez une bien piètre image alors que vous avez l air de maîtriser le sujet, C est juste dommage.
Du coup sujet clos et je vais tester aussi votre méthode de calcul car sait on jamais cela pourrait me servir donc je vous remercie quand même

Codialement

Je ne savais pas que j'avais découvert une nouvelle méthode pour calculer un pourcentage.
Soit la quantité A qui passe à la valeur B la forme "classique" pour calculer est :

P = (B - A) / A

Qui peut s'écrire en enlevant les parenthèses :
P = B/A - A/A
Comme A/A = 1
P = B/A - 1 que l'on multiplie par 100.

Ce n'est qu'une question de présentation de la même formule.
Je trouve celle ci plus pratique surtout avec une calculette, la soustraction et la multiplication par 100 se faisant aisément dans la tête.

68tjs:
Il n'y a même pas besoin de fonction map !
Soit deux nombres A et B
Si A >B le résultat A/B donnera 1,xyz
SI A<B le résultat de A/B donnera 0, ijk

Dans le premier cas tu obtiens le pourcent en soustrayant 1 au résultat, dans le deuxièmme en soustrayant le résultat de 1 et en multipliant par 100.

hum... comme vous le dites dans votre dernier post, on ne se pose pas la question de savoir qui est plus grand que qui, juste on s'assure que A n'est pas 0.

 P = B/A - 1

si le pourcentage est négatif, c'est qu'on est décroissant (B est plus petit que A)


pour l'autre point, la fonction map calcule la droite qui passe par 2 points (fonction affine).

Quand on sait que la droite que l'on cherche passe par (0,0) — ce qui est le cas pour un pourcentage simple — la fonction map() va faire plus d'opérations que nécessaire

Mais quand on est décalé (votre range 400 à 800) il faudra faire la même opération que map() fait.

Ensuite il faut savoir que map() fait ses calculs en nombre entiers, donc que cela peut conduire à des approximations ou arrondis vers le bas non souhaités.

Il faut bien qu'il reste un peu de travail personnel à faire pour l'analyse et l'exploitation des résultats.
Je répondais sur une "nouvelle méthode" qui n'en est pas une.

mon point était plutôt relatif à

Dans le premier cas tu obtiens le pourcent en soustrayant 1 au résultat, dans le deuxième en soustrayant le résultat de 1 et en multipliant par 100.

mais tout dépend de ce que l'on entend par pourcentage (on peut le voir positif et préciser que c'est une décroissance)

Oui et alors, ça n'empêche pas le demandeur de réfléchir à ce qu'il veut faire et de préciser son besoin.

je pense que c'est ce qu'il voulais dire par "cette méthode", mais je peux me tromper.

Bonsoir,

Avec vos derniers échanges je comprends mieux votre méthode de calcul qui effectivement est plus précise, c'est vrai que je n'avait pas préciser que la valeur affichée sera en entier afin de limiter le nombre de caractère et que mon projet ne demande pas une précision au pourcentage près.
Le but premier de ce projet est d'apprendre la programmation en pratiquant sur un cas pratique utilisable après.
et avec ça je me rend compte que mes cours de maths sont loin... :o

Et je me doute aussi que vous avez souvent affaire a des post ou les demandeurs attendent de vous une solution clé en main voir un code complet ( comme dans tous les forums malheureusement)

Si cela avait été le cas j'aurais juste commandé le matériel nécessaire et reproduis le système de J.M.L qui est complet ( je l'ai téléchargé mais pour le moment je ne le comprend pas :confused: )

J'ai depuis un peu avancé sur mon projet et rassemblé mais petits programmes qui séparément fonctionnent, et forcement les mettre bout a bout ne donne rien ( j'ai tenté quand même)

le code se compile mais une seule partie s'active.
Je pense qu'a cause des fonctions delay ça bloque, donc je me penche sur la fonctions millis et je commence a coder un module RTC DS3231 afin de mettre l'ensemble en déclenchement selon le timing,

Je joint le code ci-dessous mais je précise que je souhaite pas une correction de ce dernier mais plutôt des conseils pour l'optimiser , ou une logique pour réussir a faire moi même après.

merci d'avance pour ceux qui prendrons le temps d'y jeter un oeil.

Question alternative savez si il existe des cours, formations ou rassemblement pour progresser ( j'ai un ouvrage mais si vous avez un a conseiller plus qu'un autre je suis preneur aussi)

Ci joint le code en question ( bon j'ai un peur des retours des pros mais bon :slight_smile: faut bien se lancer )

#include <LiquidCrystal_I2C.h>   //librairie de l'ecran adresse apres scan 0x27

#include <Adafruit_Sensor.h>    //librairies des capteurs tst sur DHT22
#include <DHT.h>
#include <DHT_U.h>

// declaration des relais
const int Relais_Arrosage =  4; // voir programme arrosage automatique
const int Relais_Chauffage = 5; //voir prog Lcd et relais
const int Relais_Humidite = 6;  //voir prog Lcd et relais
const int Relais_Ventilateur = 7; //declenchement programmée par cycle rtc a faire
const int Alim_Sonde=8;         //alimentation de la sonde humidite sol
// declaration des capteurs
#define DHTPIN 12    //broche du DHT
#define DHTTYPE DHT22      // ou DHT 11 selon le modele utilisé

DHT dht(DHTPIN, DHTTYPE);  // Initialise le capteur DHT11
//capteur d humidite sol de type capacitif calibré sec a 800 et eau a 400
int capteuranalogique = A1;
// declaration de l'ecran
LiquidCrystal_I2C lcd(0x27, 20, 4); // ecran lcd

    //partie pour l'arrosage
int sensorValue1 = 0;
int maxi = 1023; // pour avoir toute la fenetre du traceur série
int mini = 0; // pour avoir toute la fenetre du traceur serie






void setup() {
  // put your setup code here, to run once:
  // demarrages des elements
  Serial.begin(9600);                // moniteur série
 lcd.begin ();
 lcd.println("DEMARRAGE SYSTEME");
 lcd.clear();
 dht.begin();
// declaration des sorties

pinMode(Relais_Arrosage, OUTPUT); // broche d'alimentation du relais
pinMode(Alim_Sonde, OUTPUT); // broche d'alimentation de la sonde
pinMode(Relais_Chauffage,OUTPUT);
pinMode(Relais_Humidite,OUTPUT);
pinMode(Relais_Ventilateur,OUTPUT);
//etat des sorties
digitalWrite(Relais_Arrosage, HIGH);  // les relais sont en inverse
digitalWrite(Alim_Sonde, LOW); // met la sonde hors tension - protection oxydation
digitalWrite(Relais_Chauffage,HIGH);
digitalWrite(Relais_Humidite,HIGH);
digitalWrite(Relais_Ventilateur,HIGH);

}

void loop() {
capteursol();
capteurair();
affichage();
}
void capteursol(){
  digitalWrite(8, HIGH); // met la sonde sous tension
sensorValue1 = analogRead(capteuranalogique); // mesure humidité
int humi = map(sensorValue1,810,390,0,100);
 Serial.print(maxi);
Serial.print(" ; ");
Serial.print(mini);
Serial.print("  ;  VALEUR ANALOGIQUE = ");
Serial.print(sensorValue1); 

 if (sensorValue1 > 600) 
 {
    lcd.setCursor(17,2);
    lcd.print("EAU"); // probleme ici eau ne s'efface pas a corriger
  Serial.println(" TROP SEC - ACTIVATION ARROSAGE ");
  for(int arrosage = 1 ; arrosage <= 10 ; arrosage = arrosage+1) // cycle maxi de 10 tests + arrosage
     {
     sensorValue1 = analogRead(capteuranalogique); 
     if (sensorValue1 > 600) {
        Serial.print(arrosage);
        Serial.print(" arrosage ");
        Serial.print(" ; ");
        Serial.println(sensorValue1);
        digitalWrite(Relais_Arrosage, LOW); 
        delay(2000); // durée fixe activation pompe
        digitalWrite(Relais_Arrosage, HIGH); 
        delay(10000); // pause pompe pour laisser a l'eau le tps de pénétrer la terre  
        }
     }
 }


}
void capteurair(){
    // Lecture de température et de l'humiditer environ 250 millisecondes
  // La durer des capteurs peuvent etre regler jusqu'a 2 secondes (capteur tres lent)
  byte h = dht.readHumidity();
  // Lit la temperature en degres Celsius (valeur par defaut
  byte t = dht.readTemperature();
  byte c = dht.readTemperature(true);

  // Vérifie si toutes les lectures ont échoué et quitte le début (pour réessayer).
  if (isnan(h) || isnan(t) || isnan(c)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  {
 if (h >= 40 && h <= 60) // si hum. est = ou sup. a 75 ET hum infer. ou = a 80 relais ouvert
  {
    digitalWrite(Relais_Humidite, LOW);
    digitalWrite(Relais_Chauffage,HIGH);
  }
  else
  {
    digitalWrite(Relais_Humidite, HIGH);
    digitalWrite(Relais_Chauffage,HIGH);// Sinon relais fermé
  }
  if (t<=27)// si la temperature est inf a X° alors
  {
    digitalWrite (Relais_Chauffage,LOW);
  }
  else
  {
    digitalWrite (Relais_Chauffage,HIGH);
  }
  delay(1000);// Delai d'une seconde entre les mesures
  }

} 

void affichage(){
sensorValue1 = analogRead(capteuranalogique); // mesure humidité
int humi = map(sensorValue1,810,390,0,100);
    byte h = dht.readHumidity();
  // Lit la temperature en degres Celsius (valeur par defaut
  byte t = dht.readTemperature();
  //gestion affichage lcd
  lcd.setCursor(0, 0);
  lcd.print("T.AIR = ");
  lcd.print(t);
  lcd.print(" *C ");
  lcd.setCursor(0, 1);
  lcd.print("H.AIR = ");
  lcd.print(h);
  lcd.print(" % ");
  lcd.setCursor(0, 2);
  lcd.print("H.SOL = ");
  lcd.print(humi);
  lcd.print(" % ");
  }