Question lecture et conversion LDR

Bonjour,

Je suis en train de finaliser une "station meteo" basee sur un ESP32, j'ai deja temperature+humidite+pression+altitude (DHT22+BMP180), j'ai ajoute une photoresistance, maintenant, mon soucis est que la photoresistance me renvoie des valeurs qui ne veulent pas dire grand chose pour le commun des mortels...
Quand dans ma salon, avec lumiere ambiant normale, valeur = 3072...
Lorsque je pointe une lumiere dessus, valeur = 400...

Est ce que quelqu'un a une formule pour rendre ces donnees plus "lisibles"....

Je finalise mon shema, et je le poste vite fait, en attandant, voila mon code :slight_smile:

// ESP32 Weather station WiFi Sensors
// Yann Vautrin 2023
// ESP32 as a MQTT Broker to Raspberry Pi 4B

//Libraries
#include <WiFi.h>
#include "DHT.h"
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <PubSubClient.h>

//Sensors

// Humidity qnd Temperature
#define DHTPIN 13     
#define DHTTYPE DHT22  

//Pressure and Altitude
Adafruit_BMP085 bmp;
DHT dht(DHTPIN, DHTTYPE);

//LDR for Luminosity
int LDR_pin = 34;

// WiFi
const char* ssid     = "Yann"; // Your ssid
const char* password = "16421642"; // Your Password
char status;
WiFiServer server(80);

void setup() {
 Serial.begin(115200);
 delay(1000);
  dht.begin();
   if (!bmp.begin()) {
 Serial.println("Could not find a valid BMP085 sensor, check wiring!");
  while (1) {}
  }
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi is connected");
server.begin();
Serial.println("Server started");
Serial.println(WiFi.localIP());
}


void loop() { 
Serial.println(WiFi.localIP());
int ldrValue = analogRead(LDR_pin) -1023 ; // read analog input pin 0
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
//float voltage = ldrValue * (5.0 / 1023.0);
Serial.println(WiFi.localIP());
Serial.println(ldrValue); // prints the value read
 float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
 float p = bmp.readPressure()/100;
   Serial.print("Pressure = ");
   Serial.print(p);
   Serial.println(" mb");
  // Calculate altitude assuming 'standard' barometric
  // pressure of 1013.25 millibar = 101325 Pascal
  float a = bmp.readAltitude();
  Serial.print("Altitude = ");
  Serial.print(a);
  Serial.println(" meters");
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Luminosity: ");
  Serial.print(ldrValue);
  Serial.print("unit");
  delay(1000);
  WiFiClient client = server.available();
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
// client.println("Connection: close");  // the connection will be closed after completion of the response
client.println("Refresh: 10");  // update the page after 10 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
client.println("<style>html { font-family: Fantasy; display: block; margin: 0px auto; text-align: center;color: #333333; background-color: #ccffb3;}");
client.println("body{margin-top: 50px;}");
client.println("h1 {margin: 50px auto 30px; font-size: 50px; text-align: center;}");
client.println(".side_adjust{display: inline-block;vertical-align: middle;position: relative;}");
client.println(".text1{font-weight: 180; padding-left: 15px; font-size: 50px; width: 170px; text-align: left; color: #3498db;}");
client.println(".data1{font-weight: 180; padding-left: 80px; font-size: 50px;color: #3498db;}");
client.println(".text2{font-weight: 180; font-size: 50px; width: 170px; text-align: left; color: #3498db;}");
client.println(".data2{font-weight: 180; padding-left: 150px; font-size: 50px;color: #3498db;}");
client.println(".data{padding: 10px;}");
client.println("</style>");
client.println("</head>");
client.println("<body>");
client.println("<div id=\"webpage\">");   
client.println("<h1>ESP32 Weather Station</h1>");
client.println("<div class=\"data\">");
client.println("<div class=\"side_adjust text1\">Humidity:</div>");
client.println("<div class=\"side_adjust data1\">");
client.print(h);
client.println("<div class=\"side_adjust text1\">%</div>");
client.println("</div>");
client.println("<div class=\"data\">");
client.println("<div class=\"side_adjust text2\">Temperature:</div>");
client.println("<div class=\"side_adjust data2\">");
client.print(t);
client.println("<div class=\"side_adjust text2\">*C</div>");
client.print(f);
client.println("<div class=\"side_adjust text2\">F</div>");
client.println("</div>");
client.println("<div class=\"data\">");
client.println("<div class=\"side_adjust text1\">Pressure:</div>");
client.println("<div class=\"side_adjust data1\">");
client.print(p);
client.println("<div class=\"side_adjust text1\">mb</div>");
client.println("</div>");
client.println("<div class=\"data\">");
client.println("<div class=\"side_adjust text1\">Altitude:</div>");
client.println("<div class=\"side_adjust data1\">");
client.print(a);
client.println("<div class=\"side_adjust text1\">m</div>");
client.println("</div>");
client.println("<div class=\"data\">");
client.println("<div class=\"side_adjust text2\">Luminiousity:</div>");
client.println("<div class=\"side_adjust data2\">");
client.print(ldrValue);
client.println("</div>");
client.println("</div>");
client.println("</body>");
client.println("</html>");
}

Merci de votre aide!

Sans montage (probablement pont diviseur, mais à toi de préciser) personne ne pourra te donner de "formule".

Mais à savoir : une LDR n'est pas linéaire, mais à une réponse de type R (L) = R0 L^−k

(voir Photorésistance par ex.)

Sinon il y a d'autres façons d'avoir plus directement, plus précisement la valeur de l'éclairement.

Hello Professeur!

Voila un shema rapide de mon montage!
Sinon, c'est quoi a methode pour avoir une valeur plus precise de l'eclairement ?????

PS: la resistance a une valeur de 100 KOhm

Desolé de vous faire une réponse assez négative, mais les photorésistances sont sensibles à la température et il sera assez difficile de faire une mesure "parlante".
Selon Photorésistance — Wikipédia

Les photorésistances trouvent leurs applications principales dans la détection d'une différence de flux plutôt que dans la mesure précise du niveau de flux reçu (impulsions lumineuses, variation d'éclairage par exemple).

Une idé (non testée) serait d'avoir 2 photoresistances (l'esp32 a suffisamment de voies analogiques), l'une orientée vers le Sud, l'autre vers le Nord; si les valeurs sont très différentes, on est en présence de ciel clair (Soleil visible); si elles diffèrent peu, on est en présence d'un ciel couvert. avec pas mal d'efforts et une mesure du temps, vous arriveriez à déterminer la durée d'ensoleillement Durée d'ensoleillement — Wikipédia sur l'heure précédente -ce qui est une valeur interessante-

Edité: c'est hors sujet, mais je me dispenserais d'afficher la température en Fahrenheit (deux grandeur redondantes, qui compliquent la lecture. Si on était aux States, je serais tout aussi négatif pour la température en Celsius)

Bonjour @yvautrin

pour établir TA formule , tu peux :
-utilser un application Luxmetre sur smartphone et faire une série de relevés pour des niveaux d'éclairement variés
-reporter ces relevés dans un tableur , analyser la progression et en tirer une formule
-reporter cette formule expérimentale dans ton code pour obtenir un affichage en lux

1 Like

Si les LDR sont sensibles a la temperature, je peut passer la temperature lue par le DTH ou par le BMP en parametre dans la formule, non?

ok, ca, je peut faire, je vais faire un essai maintenant!

regarde du côté des BH170 ou BH1750

il y en a problement plein d'autre. C'est probablement basé sur une photodiode ou un phototransistor un peu plus fiable qu'une LDR.

Le vaste marché des smartphones à déclenché la mise sur le marché de bons capteurs luxmetres sur bus I2C de la part de Texas Instruments, AMS.....

pour l'univers 'maker' ils existent sous forme de breakout + bibliothèques
un exemple

voila quelques releves rapides!

Lux ldrValue
45 3072
360 2600
1350 1800
1900 1020
34000 42

Je vais regarder du cote des capteurs disponibles ici (je suis en Egypte)!

Mais en attendant j'aimerais quand meme avoir une formule, meme si j'ai bien compris que ce ne sera pas "super"fiable et precis!"!

Votre formule est dans le lien wikipédia (à une constante près, qui dépend:

  • de la LED
  • de la température)
1 Like

{isplaystyle R(L)=R_{0}L^{-k}}

Mais la, du coup ca depasse mes competences en Maths...

Pas trop... edité "k" doit dépendre du type de LCD et de la température
réidité: en plein soleil (ce qui est un emplacement assez rationnel pour un capteur de luminosté) la température doit différer assez considérablement (10 ou 20C) de ce que mesure un capteur de température d'une station météo rationnelle, mis à l'ombre -sinon, la mesure est hyper bruitée et très biaisée, avec un biais dépendant de la saison)

c'est pour ça que je conseille plutôt d'avoir 2 LDR (a priori à la même température) et de tenter une mesure de durée d'insolation, et que al1fch conseille (ce qui est mieux) d'avoir un vrai capteur d'éclairement sur I2C basé sur un principe plus sain.

1 Like

un petit panneau photovoltaîque comme on en trouve dans divers gadgets peut également faire office de luxmetre basique après étalonnage
-> Le faire débiter sur une faible résistance : le courant de court circuit du PV est représentatif de l'éclairement.... dans une relation nettement moins non-linéaire que la photorésistance....

capteur I2C : je n'ai utilisé que le TSL2561 sous forme de 'breakout' acheté via Aliexpress, utilisé avec la bibliothèque proposée pour ce composant par Adafruit

3 Likes

Ça va pas suffire comme mesures pour étalonner la courbe :

La courbe des log devrait idéalement être une droite pour déterminer les différents paramètres de la formule. Sauf qu'il manque beaucoup de points au milieu de la courbe pour espérer avoir qq chose de potable.

Tu peux refaire d'autres mesures un peu mieux réparties entre 2000 et 30000 lux ?

Je refais des mesures cet apres midi pour completer la courbe!
Merci de ton aide!

Sauf que si elles ne sont pas éclairées de la même manière, il y a peu de chance qu'elle soient à la même température. Surtout si l'une des deux est en plein soleil. Une régulation de T semble "overkill" surtout si d'autres capteurs plus pertinents existent.

Oublie : c'est la température de la LDR qui est à prendre en compte, donc d'un composant placé en plein soleil (50 °C facile si tu es en Egypte !) et non pas la température de l'air prise dans des conditions un peu plus "normalisée" (aka à l'ombre) telles que souhaitées dans une station météo.

1 Like

J'ai eu le même problème en tentant d'ajuster au sens des moindres carrés log10(R) et luxes...

Il faut les coller l'une à l'autre... Ca peut suffire pour tenter de faire un capteur de ciel clair.