Banc de test d’éclairage véhicules (arduino Mega, TTGO ESP 32...)

A l’IUT nous testons de nombreux éclairages de véhicules.
Les résultats de ces mesures poule velo sont sur ce lien

Un post sur la gestion d’éclairage avec Arduino est en cours
« Eclairage à led de vélo (7.5W à l’avant et 3 W à l’arrière) avec Arduino »
https://forum.arduino.cc/index.php?topic=591180.0

Nous mesurons l’éclairage sur un mur. Avec ces données, les valeurs sur le sol peuvent être estimées.
Mais, à la place de faire une estimation mathématique.
Ce banc d’essai permet de mesurer la distribution de l’éclairage sur un sol. En effet, 16 capteurs TEMT6000 (0.53€) ont été placé sur une réglette de 3m de long (écart de 16cm) et mémorise les mesures via le connecteur USB sur un PC tous les mètres à chaque fois que l’on appuie sur le bouton 1 comme on peut l’observer sur la figure suivante qui nous a permis de tester notre programme.
Les valeurs seront traitées dans Excel via un fichier CSV en copiant toutes les données du terminal.
Toutes les valeurs doivent etre divisé par 1.021 mais ce sera fait dans Excel.

Le schéma de simulation d’ISIS peut etre telechargé sur ce lien

Le programme est le suivant

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>
#include <avr/wdt.h>   //chien de garde
 

#define Led     13       // 13 pour la led jaune sur la carte
#define BP1     30       // 30 BP1
#define BP2     31       // 31 BP2           
#define BP3     32       // 32 BP3
#define BP4     26       // 32 BP3
#define LEDV    33       // 33 led
#define LEDJ    34       // 34 led
#define LEDR    35       // 35 led
#define relay1   8       // relay1  B1
#define relay2   9       // relay2  B2



LiquidCrystal lcd(27, 28, 25, 24, 23, 22); // RS=27, Enable=28, D4=25, D5=24, D6= 23, D7=22, BPpoussoir=30
// Configuration des variables
unsigned   int temps = 0;
unsigned   int S0[16];  // variable to store the value coming from the sensor

           
void setup() {
  pinMode(Led, OUTPUT);   //led carte arduino
  pinMode(LEDV, OUTPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDJ, OUTPUT);

  Timer1.initialize(100000);         // initialize timer1, and set a 0,1 second period =>  100 000
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
  lcd.begin(20, 4);  
//  Serial1.begin(9600); 

wdt_enable(WDTO_15MS);
wdt_enable(WDTO_1S);    // declenche le chien de garde

Serial.begin(9600);
interrupts();
}


// Interruptions  tous les 0.1s
void callback()  {
temps++;
//toogle state ledv for check 

wdt_reset();  // remise à zero du chein de garde 
//************************ 

 if (temps>=1  )  {        //
    if ( digitalRead(LEDV)== 1 ) {digitalWrite(LEDV,LOW);}  else {digitalWrite(LEDV,HIGH);}
  S0[0]=analogRead(A0);       //
lcd.setCursor(0,0);           
lcd.print(S0[0]);  
lcd.print(".");         
S0[1]=analogRead(A1);       //
lcd.print(S0[1]);
lcd.print(".");
S0[2]=analogRead(A2);       //
lcd.print(S0[2]);
lcd.print("."); 
S0[3]=analogRead(A3);       //
lcd.print(S0[3]);
lcd.print("        ");   

lcd.setCursor(0,1);
S0[4]=analogRead(A4);   
lcd.print(S0[4]);  
lcd.print(".");         
S0[5]=analogRead(A5);       //
lcd.print(S0[5]);
lcd.print(".");
S0[6]=analogRead(A6);       //
lcd.print(S0[6]);
lcd.print("."); 
S0[7]=analogRead(A7);       //
lcd.print(S0[7]);
lcd.print("        ");  

lcd.setCursor(0,2);
S0[8]=analogRead(A8);   
lcd.print(S0[8]);  
lcd.print(".");         
S0[9]=analogRead(A9);       //
lcd.print(S0[9]);
S0[10]=analogRead(A10);
lcd.print(".");
lcd.print(S0[10]);
S0[11]=analogRead(A11);
lcd.print(".");     
lcd.print(S0[11]);
lcd.print("        ");  

lcd.setCursor(0,3);
S0[12]=analogRead(A12);   
lcd.print(S0[12]);  
lcd.print(".");         
S0[13]=analogRead(A13);       //
lcd.print(S0[13]);
S0[14]=analogRead(A14);
lcd.print(".");
lcd.print(S0[14]);
S0[15]=analogRead(A15);
lcd.print(".");     
lcd.print(S0[15]);
lcd.print("        ");       
  
temps=0;
  } // fin temps

}//fin routine interruption


// Boucle correspondant à la fonction main 
void loop() {  
 
  if ((digitalRead(BP1))==1) {  //envoie des données de la ligne mesurée sur le PC
int i;                           // puis enregistrement des mesures dans un fichier CSV pouvant etre traité dans excel
for (i = 0; i <= 15; i = i + 1) {
  Serial.print(S0[i]);
  Serial.print(";");
}
 Serial.println("\t");
    
       delay(1000);  
       }

   
} // fin loop

pour minimiser le nombre de fil A la place de prendre un capteur analogique, des capteurs numeriques d’éclairages avec communications tel que I2C existent (BH1750 0,8€., TSL2561 3,8€.) utilisant des photodiodes
I2C est un bus série synchrone bidirectionnel ou plusieurs maîtres ou esclaves pouvant utiliser jusqu’à 128 périphériques. La plage de mesure du BH1750 est sur 16 bits avec une précision possible à 0,5lux
Mais, le BH1750 n’a que 2 adresses possibles. Par contre, le TSL2561 est configurable mais cher.

Perspectives
Il serait intéressant d’enregistrer toutes les mesures en interne ou sur une carte SD puis de les transférer sur le PC

Banc de test Arduino

Suite du projet de test d’éclairage de véhicules :
Nous avons donc continué le projet en le réalisant en réel. On a utilisé une grande barre qui sert à passer les câbles électriques. On a donc eu la place pour placer l’Arduino Méga et son écran. On a également vissé sur cette barre les 16 phototransistors distancés les uns des autres de 2 centimètres.

Les phototransistors utilisés sont des TEMT6000.
On utilise donc le programme précèdent car il est tout à fait compatible au niveau de la sortie du capteur qui est une image de la puissance lumineuse. Les seules modifications apportées concernent la position des valeurs sur l’écran LCD et l’ajout de quelques lignes pour l’utilisation de PLX-DAQ.

On a réalisé un « bus » commun pour la masse et le +5V. Il suffit donc de raccorder les 16 phototransistors, et de rejoindre la sortie du capteur dans l’ordre sur l’Arduino.

Après avoir téléversé, pour une puissance lumineuse égale sur chaque phototransistor, on remarque que les valeurs sont différentes pour chacun des phototransistors.
Il y a des différences au niveau de la valeur des gains des capteurs, ils sont différent avec un écart allant jusqu’à 2.
Par conséquent, il a fallu faire un « calibrage » de chaque capteur pour obtenir les mêmes valeurs. La compensation des gains est faite dans le programme Arduino.
On peut observer sur la photo suivante la barre avec tous les 16 capteurs


Le bouton poussoir BP1 permet de récupérer les données de l’Arduino pour les mettre sur un fichier Excel. On va donc utiliser PLX DAQ. C’est un logiciel que l’on incorpore sur le programme Arduino, qui va envoyer toutes les données sur une feuille Excel.

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>
#include <avr/wdt.h>   //chien de garde
 

#define Led     13       // 13 pour la led jaune sur la carte
#define BP1     30       // 30 BP1
#define BP2     31       // 31 BP2          
#define BP3     32       // 32 BP3
#define BP4     26       // 32 BP3
#define LEDV    33       // 33 led
#define LEDJ    34       // 34 led
#define LEDR    35       // 35 led
#define relay1   8       // relay1  B1
#define relay2   9       // relay2  B2



LiquidCrystal lcd(27, 28, 25, 24, 23, 22); // RS=27, Enable=28, D4=25, D5=24, D6= 23, D7=22, BPpoussoir=30
// Configuration des variables
unsigned   int temps = 0;
unsigned   int S0[16];  // variable to store the value coming from the sensor

          
void setup() {

  Serial.begin(9600);
  Serial.println("CLEARSHEET");
  Serial.println("LABEL,Capteur_1,Capteur_2,Capteur_3,Capteur_4,Capteur_5,Capteur_6,Capteur_7,Capteur_8,Capteur_9,Capteur_10,Capteur_11,Capteur_12,Capteur_13,Capteur_14,Capteur_15,Capteur_16");
  
  pinMode(Led, OUTPUT);   //led carte arduino
  pinMode(LEDV, OUTPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDJ, OUTPUT);

  Timer1.initialize(1000000);         // initialize timer1, and set a 1 second period =>  1 000 000
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
  lcd.begin(20, 4);  
//  Serial1.begin(9600);

wdt_enable(WDTO_15MS);
wdt_enable(WDTO_1S);    // declenche le chien de garde

Serial.begin(9600);
interrupts();
}


// Interruptions  tous les 1s
void callback()  {
temps++;
//toogle state ledv for check

wdt_reset();  // remise à zero du chein de garde
//************************

 if (temps>=1  )  {        //
    if ( digitalRead(LEDV)== 1 ) {digitalWrite(LEDV,LOW);}  else {digitalWrite(LEDV,HIGH);}
  S0[0]=analogRead(A0);       //
lcd.setCursor(0,0);          
lcd.print(S0[0]);  
lcd.setCursor(4,0);        
S0[1]=analogRead(A1);       //
lcd.print(S0[1]);
lcd.setCursor(8,0); 
S0[2]=analogRead(A2);       //
lcd.print(S0[2]);
lcd.setCursor(12,0); 
S0[3]=analogRead(A3);       //
lcd.print(S0[3]);

lcd.setCursor(0,1);
S0[4]=analogRead(A4);  
lcd.print(S0[4]);  
lcd.setCursor(4,1);       
S0[5]=analogRead(A5);       //
lcd.print(S0[5]);
lcd.setCursor(8,1);
S0[6]=analogRead(A6);       //
lcd.print(S0[6]);
lcd.setCursor(12,1);
S0[7]=analogRead(A7);       //
lcd.print(S0[7]); 

lcd.setCursor(0,2);
S0[8]=analogRead(A8);  
lcd.print(S0[8]);  
lcd.setCursor(4,2);        
S0[9]=analogRead(A9);       //
lcd.print(S0[9]);
lcd.setCursor(8,2);
S0[10]=analogRead(A10); 
lcd.print(S0[10]);
lcd.setCursor(12,2); 
S0[11]=analogRead(A11);   
lcd.print(S0[11]);

lcd.setCursor(0,3);
S0[12]=analogRead(A12);  
lcd.print(S0[12]);  
lcd.setCursor(4,3);        
S0[13]=analogRead(A13);       //
lcd.print(S0[13]);
lcd.setCursor(8,3);
S0[14]=analogRead(A14);
lcd.print(S0[14]);
lcd.setCursor(12,3);  
S0[15]=analogRead(A15);
lcd.print(S0[15]);      
  
temps=0;
  } // fin temps

}//fin routine interruption


// Boucle correspondant à la fonction main
void loop() {  
 
  if ((digitalRead(BP1))==1) {  //envoie des données de la ligne mesurée sur le PC
    int i;                           // puis enregistrement des mesures dans un fichier CSV pouvant etre traité dans excel
    for (i = 0; i <= 15; i = i + 1) {
  Serial.print("DATA,");  // envoi de la mesure à Excel  
  Serial.print(S0[i]);
  Serial.print(";");
}
 Serial.println("\t");
    
       delay(1000);  
       }

  
} // fin loop

Il y a une belle explication sur ce lien de cette extention de Parallax Data Acquisition (PLX-DAQ) tool

Telechargeable ici

Perspectives :

Un programme en VBA, permettra de traiter les données avec différentes courbes .

Une petite faute de fratte (C’est PLX-DAQ et pas PLX-DAX)

Mettre quelque lien par exemple :
Il y a une belle explication sur ce lien de cette extention de Parallax Data Acquisition tool

Telechargeable ici

j’ai hate de voir la finalité avec le programme VBA.
Dommage que le confinement du covid 19 bloque de pouvoir faire les tests sur differents eclairages de velo.

Et si on avait utilisé une LDR avec {ALPHA=-0.8582} donné dans ISIS ?
voir propriété text de ce composant
comment devrait evoluer le programme ?

ce sujet a été bloqué à cause du confinement.....
il y a de nombreuses autres idées à faire, sur ce sujet

En effet, Pour tester l’éclairage en mode clignotant, pour connaitre le rapport cyclique et la période de fonctionnement et si l’éclairage est plus puissant en mode discontinu, qu’en mode continu.
D’ailleurs, il y a des tests consumeristes sur les eclairages velo ici

Avec une routine d’interruption fixe (10ms) ou un temps fixe de mesure du signal, on pourrait utiliser le capteur TEMT6000 et recevoir les mesures dans le traceur et moniteur série comme un oscilloscope.

Si l’on désire être indépendant du PC, on peut le tracer sur l’écran du smartphone via le Bluetooth.

De même, si l’on désire être indépendant d’un smartphone, on pourrait utiliser le OLED d’un TTGO avec une batterie.

Bonjour,
Voici mon projet, qui avait pour but de faire un oscilloscope et un luxmètre avec un TTGO et un capteur TEMT6000.
Je me suis aidée des recherches que iutgeiisoissons et cicciobellobobo.
Donc voici le programme :

#include <TFT_eSPI.h>
#include <SPI.h>
#include <Wire.h>
TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240
String lire;
String myChar;
const int ledPin32 = 32;       //
const int ledChannel = 2;
const float vref=1100; 
const byte timescreen=20;   //temps d'affichage
float Lux;
int bp1Mem;
int bp1;
byte flag=10;
int bp2;
int bp2Mem;
float lux;
int etat;
int x;
int N;
byte i;
   #define S1            0    //fonctionne à 0L, switch
   #define S2            35   //key
 #define BUTTON_1            0    //fonctionne à 0L
#define BUTTON_2            35// fonctionne à 0L et définir le BP en entrée au préalable en input
#define TR_DATUM 2 //TOP RIGHT
void setup() {
  pinMode(33, OUTPUT);
  pinMode(2, INPUT);   //entree analog
 Serial.begin(9600);
  tft.init();
  tft.setRotation(1); //format portrait a l'endroit
  tft.fillScreen(TFT_BLACK);
pinMode(BUTTON_2, INPUT_PULLUP);
pinMode(13, INPUT);
pinMode(14, INPUT);
pinMode(17,OUTPUT);
analogReadResolution(12);   //12 bits 
tft.drawLine(0,249,0,0, TFT_CYAN);//Ligne drawFastVLine( x,  y,  w,  color) Verticale
 tft.drawLine(240,0,0,0,TFT_RED);// Ligne Horizontal 
 tft.setCursor(0, 249, 2);// (x,y,taille)
   tft.println("948");
  tft.setTextColor(TFT_WHITE,TFT_BLACK);
}


void loop() {
  if (digitalRead(17)==1)   {digitalWrite(17,LOW);}  else {digitalWrite(17,1);} // Le temps du programme sans le delay est de 700 micro seconde.
  N=240;
  Lux=analogRead(13);
Lux=(Lux/4.16); // de base il a 4.16 // Lux=(Lux*3,3*300)/(4095);
  lux=Lux/7.55;  //7.55 = 985/135 //1204 décimal pour 300l sature a partir de 1000 lux le max ici c'est 984.37 LUX
 for (i = 0; i < N; i--)  { x++;
tft.drawPixel(x,134.5-lux,TFT_GREEN);
delay(10);
  tft.setCursor(240, 240, 2);// (x,y,taille)
   tft.println(Lux);
   tft.setTextColor(TFT_WHITE,TFT_BLACK); }
if(x>=239){
  tft.fillScreen(TFT_BLACK);
  tft.drawLine(0,249,0,0, TFT_CYAN);//Ligne drawFastVLine( x,  y,  w,  color) Verticale
 tft.drawLine(240,0,0,0,TFT_RED);// Ligne Horizontal 
  i=0;
  x=0;}
   }

Le capteur (TEMT 6000) a des caractéristiques intéressantes comme un spectre entre (390-700 nm), une tension qui ne doit pas excéder les 6V. Mais ici, nous allons le faire fonctionner à 3.3V.
[tt][tt]​[/tt][/tt]
J'ai chercher au plus simple, donc voici ce que j'ai fait :


Je n’ai pas pu mettre la ligne rouge (l’axe X) en bas pour qu’il soit bien mis, pour faire un oscilloscope fonctionnel. Le zéro est bien en bas à gauche.

Nous avons mis en place l’utilisation de boutons pour afficher les LUX mais nous préférons le mettre directement en haut à gauche pour qu’on puisse avoir les valeurs à chaque instant.

Pas si facile de gérer l’écran et les lignes,
Voilà le code qui résout le problème de l’axe horizontal

#include <TFT_eSPI.h>
#include <SPI.h>
#include <Wire.h>
TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240
String lire;
String myChar;
const int ledPin32 = 32;       //
const int ledChannel = 2;
const float vref=1100; 
const byte timescreen=20;   //temps d'affichage
float Lux;
float lux1;
int bp1Mem;
int bp1;
byte flag=10;
int bp2;
int bp2Mem;
float lux;
int etat;
int x;
int N;
byte i;
   #define S1            0    //fonctionne à 0L, switch
   #define S2            35   //key
 #define BUTTON_1            0    //fonctionne à 0L
#define BUTTON_2            35// fonctionne à 0L et définir le BP en entrée au préalable en input
#define TR_DATUM 2 //TOP RIGHT
void setup() {
  pinMode(33, OUTPUT);
  pinMode(2, INPUT);   //entree analog
 Serial.begin(9600);
  tft.init();
  tft.setRotation(1); //format horizontal (X=0,Y=0) en haut à gauche
  tft.fillScreen(TFT_BLACK);
pinMode(BUTTON_2, INPUT_PULLUP);
pinMode(13, INPUT);
pinMode(14, INPUT);
pinMode(17,OUTPUT);
analogReadResolution(12);   //12 bits 
  
 tft.setTextColor(TFT_WHITE,TFT_BLACK);   //https://wiki.microduinoinc.com/Tft.drawLine()

  tft.drawLine(0,130,0,0, TFT_CYAN);      //Ligne drawFastVLine( x,y, x1,Y1,  color) Verticale
  tft.drawLine(0,134,240,134,TFT_RED);   // ligne horizontale
}




void loop() {
  if (digitalRead(17)==1)   {digitalWrite(17,LOW);}  else {digitalWrite(17,1);} // Le temps du programme sans le delay est de 700 micro seconde.

for (i=0; i<240; i++)  { x++;
Lux=analogRead(13);
Lux=(Lux/4.16);   //Lux=(Lux*3,3*300)/(4095)=lux/4.16  
lux1=(Lux/7.55);    //variable pour l'ecran,   7.55=985/135     le max ici c'est 985 LUX   pour 3.3V
tft.drawPixel(x,134-lux1,TFT_GREEN);              
tft.setCursor(120, 0, 2);// (x,y,taille)     
tft.print(Lux);tft.print("Lux");
delay(10);             //base de temps mais un routine d'interruption serait mieux
                          
if(x>=239){                           //rafraichit tout l'ecran
  tft.fillScreen(TFT_BLACK);         //effacement de tout l'ecran
  tft.drawLine(0,130,0,0, TFT_CYAN);   //Ligne drawFastVLine( x,y, x1,Y1,  color) Verticale

  tft.drawLine(0,134,240,134,TFT_RED);      // Ligne Horizontal

  tft.setCursor(110, 120, 2);// (x,y,taille)
  tft.print("2.5s");
  tft.setCursor(220, 120, 2);// (x,y,taille)
  tft.print("5s");
  tft.setCursor(0, 67, 2);// (x,y,taille)
  tft.print("492lux");
  tft.setCursor(0, 0, 2);// (x,y,taille)
  tft.print("985lux");
  tft.drawLine(120,134,120,110, TFT_CYAN);  //ligne curseur du milieu
  x=0;}
   }     //fin tracage

   }  //end loop


Une routine d’interruption aurait pu être utilisé et la base de temps aurait pu être variable de 1ms à 50ms en l’incrémentant avec le bouton S1 ou décrémentant avec le bouton S2
En effet, la boucle du programme ne dure que 0.7ms.

avec un échantillon de 1ms, on observe le scintillement de l’eclairage du tube fluo ou de led qui ont une periode de 10ms.

l'application "luxemetre" sur smartphone, ne donnerai til pas une courbe de l'eclairage en fonction du temps ????

Nous continuons les tests d'éclairages véhicules.
Cette fois nous avons décidé de réaliser de tests avec un Arduino Nano et un seul capteur TEMT6000 et pour la visualisation des résultats nous avons utilisé :

  • Un afficheur LCD 16x2.
  • Un module Bluetooth HC-04 pour pouvoir se communiquer avec un téléphone portable à l'aide de l'application Bluetooth Electronics. La carte se communique avec le module via liaison série.

Voici tous les composants du système :


Pour le code je me suis inspiré du travail réalisé par iutgeiisoissons et Antonindavid02. Avec les nouvelles modifications j'ai le code :

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>

#define LED     13       // 13 pour la led jaune sur la carte

LiquidCrystal lcd(8, 3, 7, 6, 5, 4); // RS=8, Enable=3, D4=7, D5=6, D6= 5, D7=4
// Configuration des variables
unsigned   int temps = 0;

float lux;
float tension;

          
void setup() {
  pinMode(LED, OUTPUT);   //led carte arduino
  pinMode(A0, INPUT);
  Timer1.initialize(50000);         // initialize timer1, and set a 0,1 second period =>  100 000    
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
  lcd.begin(16, 2);  
  Serial.begin(9600);
}

// Interruptions  tous les 0.05s
void callback()  {
temps++;
//toogle state ledv for check
  if ( digitalRead(LED)== 1 ) {digitalWrite(LED,LOW);}  else {digitalWrite(LED,HIGH);}
  tension=analogRead(A0);       //lecture de la tension reçu par le capteur
  lux=(tension*300)/1023;      //1V  300lux
   Serial.print("*L");Serial.print(lux);Serial.print("*");
 
if (temps>=100){
  lcd.setCursor(0,0);  
   lcd.print("lux=");         
  lcd.print(lux,1); 
   lcd.print("    ");
  temps=0;
}
   
}//fin routine interruption

void loop() {
  // put your main code here, to run repeatedly:

}

Il y a besoin d’effectuer une mesure chaque 0,05s pour avoir une bonne visualisation du graphe sur l’application mais cela provoque que l’afficheur montre trop rapides les mesures et ils ne sont pas visibles du tout. Donc, l’affichage sur le LCD se fait chaque 5s grâce à la boucle if dans la ligne 33.
Voici les résultats sur l’afficheur :

Et le graphe dans l'application :

Pour la suite, nous allons réaliser un programme qui permettra insérer les résultats directement dans un document.

Bonjour,
sur l'application "Luxmeter"

Le temps minimal est de 3 secondes et le maximum est de 120 secondes

Donc sur mon code j'ai du ajouter des variables pour que l'utilisateur puisse changer le temps de sur l'oscilloscope, le temps se fait incrémenter et désincrémenter avec les boutons déjà intégré par le TTGO, il peux aller de 0.25s à 10s.
Il y a 5 mode donc de 0.25s, après jusqu'à 2.50, après jusqu'à 5s, après jusqu'à 7.5s et pour finir 10s.

#include <TFT_eSPI.h>
#include <SPI.h>
#include <Wire.h>
TFT_eSPI tft = TFT_eSPI();  //library   1,4" color 135, 240
String lire;
String myChar;
const int ledPin32 = 32;       //
const int ledChannel = 2;
const float vref=1100;
const byte timescreen=20;   //temps d'affichage
float Lux;
float lux1;
int bp1Mem;
int bpMem;
int bp1;
byte flag=10;
int bp2;
int bp2Mem;
float lux;
int etat;
int x;
int N;
byte i;
int Y;
float tempsmoy;
float tempsmax;
   #define S1            0    //fonctionne à 0L, switch
   #define S2            35   //key
 #define BUTTON_1            0    //fonctionne à 0L
#define BUTTON_2            35// fonctionne à 0L et définir le BP en entrée au préalable en input
#define TR_DATUM 2 //TOP RIGHT
void setup() {
  pinMode(33, OUTPUT);
  pinMode(2, INPUT);   //entree analog
 Serial.begin(9600);
  tft.init();
  tft.setRotation(1); //format horizontal (X=0,Y=0) en haut à gauche
  tft.fillScreen(TFT_BLACK);
pinMode(BUTTON_2, INPUT_PULLUP);
pinMode(13, INPUT);
pinMode(14, INPUT);
pinMode(17,OUTPUT);
analogReadResolution(12);   //12 bits
  
 tft.setTextColor(TFT_WHITE,TFT_BLACK);   //https://wiki.microduinoinc.com/Tft.drawLine()


  tft.drawLine(0,130,0,0, TFT_CYAN);      //Ligne drawFastVLine( x,y, x1,Y1,  color) Verticale
  tft.drawLine(0,134,240,134,TFT_RED);   // ligne horizontale
}








void loop() {
  if (digitalRead(17)==1)   {digitalWrite(17,LOW);}  else {digitalWrite(17,1);} // Le temps du programme sans le delay est de 700 micro seconde.


for (i=0; i<240; i++)  { x++;
Lux=analogRead(13);
Lux=(Lux/4.16);   //Lux=(Lux*3,3*300)/(4095)=lux/4.16  
lux1=(Lux/7.55);    //variable pour l'ecran,   7.55=985/135     le max ici c'est 985 LUX   pour 3.3V
tft.drawPixel(x,134-lux1,TFT_GREEN);              
tft.setCursor(120, 0, 2);// (x,y,taille)    
tft.print(Lux);tft.print("Lux");
bp1 = (!(digitalRead(BUTTON_1)));
  // compare l'état actuel du bouton poussoir à l'état précédent mémorisé
  if (bp1 != bp1Mem){
   // si l'état du bouton poussoir a changé  
    // on mémorise l'état courant du bouton poussoir pour les prochains passages dans la boucle loop
    bp1Mem = bp1;
    bpMem= bpMem +1 ;
    
   // si ce nouvel état est passé à 1, on a donc un front montant.
  }
  bp2 = (!(digitalRead(BUTTON_2)));
// // compare l'état actuel du bouton poussoir à l'état précédent mémorisé
 if (bp2 != bp2Mem){
   // si l'état du bouton poussoir a changé  
   // on mémorise l'état courant du bouton poussoir pour les prochains passages dans la boucle loop
    bp2Mem = bp2;
    bpMem= bpMem - 1 ;
    
   // si ce nouvel état est passé à 1, on a donc un front montant.
 }


 
 if( bpMem == 1) {
  Y=1;


 }
 if (bpMem ==2) {
  Y=10;


  }
 if(bpMem ==3){
  Y=20;


  }
  if (bpMem==4){
    Y=30;


    }
    if(bpMem==5) { 
      Y=40;
      }
    
   
  tft.setCursor(110, 120, 2);// (x,y,taille)
  tempsmoy=0.125*Y;
  tft.print(tempsmoy);
  tft.setCursor(210, 120, 2);// (x,y,taille)
   tempsmax=0.250*Y;
  tft.print(tempsmax);
  tft.setCursor(0, 68, 2);// (x,y,taille)
  tft.print("492lux");
  tft.setCursor(0, 0, 2);// (x,y,taille)
  tft.print("985lux");
  tft.drawLine(120,134,120,110, TFT_CYAN);  //ligne curseur du milieu
delay(Y);
if(x>=239){     //rafraichit tout l'ecran
  
  tft.fillScreen(TFT_BLACK);         //effacement de tout l'ecran
  tft.drawLine(0,130,0,0, TFT_CYAN);   //Ligne drawFastVLine( x,y, x1,Y1,  color) Verticale


  tft.drawLine(0,134,240,134,TFT_RED);      // Ligne Horizontal
tft.setCursor(110, 120, 2);// (x,y,taille)
tempsmoy=0.125*Y;
  tft.print(tempsmoy);
  tft.setCursor(210, 120, 2);// (x,y,taille)
  tempsmax=0.250*Y;
  tft.print(tempsmax);
  tft.setCursor(0, 68, 2);// (x,y,taille)
  tft.print("492lux");
  tft.setCursor(0, 0, 2);// (x,y,taille)
  tft.print("985lux");
  tft.drawLine(120,134,120,110, TFT_CYAN);  //ligne curseur du milieu
    x=0;
      }
  }  //fin tracage
}  //end loop

Peut-on faire un luxmètre facilement avec une LDR ?

En faisant 3 à 4 mesures, il est facile de modéliser la LDR et de retourner l’équation pour afficher des lux ?

Mais la communauté manque de base mathématique comme on peut l’observer dans les articles suivants qui ne retournent pas la valeur en lux

https://www.carnetdumaker.net/articles/mesurer-la-luminosite-ambiante-avec-une-photoresistance-et-une-carte-arduino-genuino/

cet article est bien

Faut-il mettre une résistance de pull down ou pull up ?
Quelle valeur de résistance pour alimenter la LDR ?

Pour avoir le plus de sensibilité il faut la résistance alimentant la LDR ait la même valeur que celle pour les lux que l’on voudrait mesurer.

Voici l’étude mathématique de la LDR




Capture3

Voici la simulation avec ISIS, il est possible de mettre le modèle électrique de la LDR en éditant « all propriety text » le coefficient du modèle spic peut être modifié et permet de verifier le code

donc, voici le code du programme

#include <Wire.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>


#define PWM5   5      //   timer2   
#define LED13    13     

LiquidCrystal lcd(9, 8, 4, 3, 6, 7);   // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables



float LDR, lux;

                   

void setup() {
  pinMode(LED13, OUTPUT);
  pinMode(PWM5,OUTPUT);

  Timer1.initialize(100000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000 
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt   500=>2KHz    5000=>200Hz
  lcd.begin(20, 4);                   //modifier pour un afficheur 20x4

  Serial.begin(9600);
}


// Interruptions   par le timer1    ***********************************
void callback()  {
digitalWrite(LED13,HIGH);  //permet de mesurer à l'oscillo, le temps du calcul du filtre et le temps de la routine d'interruption

LDR=analogRead(A0); //convertisseur 10 bits sous 5V
lux=(LDR*10/((1024-LDR)*75));   //lux1=(LDR*10k/((1024-LDR)*75k));
float a1=1/-0.73;
lux=pow(lux, a1);    //      

digitalWrite(LED13,LOW);   //le temps de la mesure et du calcul est de 0.5ms

}//fin routine

///////////////////////////////////////////// Boucle correspondant à la fonction main
void loop() {
 lcd.setCursor(0,0);   
 lcd.print("LDR=75000*E^0.73");
  
  lcd.setCursor(0,2);   
  lcd.print("lux=");
  lcd.print(lux,0);
  lcd.print("    ");

} // fin loop

Pour trouver le modèle mathématique de la LDR, une courbe de tendance sous Excel aurait pu être utilisée

avec une resistance de pull down de 500ohms et pour le modele de la LDR precedent

Les courbes avec EXCEL qui permettent d'avoir la courbe de tendance et le modele de la LDR avec une precision de 8bits


avec les equations suivante, on retrouve la mesure en lux
ANDEC(V) =500* 5* 255 /((500+B2)5)
Lux LCD==(((255/C2)-1)
(500/(75*10^3)))^(1/-0,729)
lux line= =(C2-31,2)*10,16 lineairisation en 2 points

voici la simulation qui verifie le code et les equations

#include <Wire.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
#include <TimerOne.h>

#define LED13    13     

LiquidCrystal lcd(9, 8, 4, 3, 6, 7);   // LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Configuration des variables



float LDR, lux;

                   

void setup() {
  pinMode(LED13, OUTPUT);

  Timer1.initialize(100000);           // initialize timer1, and set a 0,1 second period =>  100 000  pour 0.01s  10 000 
  Timer1.attachInterrupt(callback);   // attaches callback() as a timer overflow interrupt   500=>2KHz    5000=>200Hz
  lcd.begin(20, 4);                   //modifier pour un afficheur 20x4

  Serial.begin(9600);
}


// Interruptions   par le timer1    ***********************************
void callback()  {
digitalWrite(LED13,HIGH);  //permet de mesurer à l'oscillo, le temps du calcul du filtre et le temps de la routine d'interruption

LDR=analogRead(A0); //convertisseur 10 bits sous 5V
lux=((1024/LDR)-1)*(0.5/75);   //lux=((5/LDR)-1)*(0.5k/75k);
float a1=1/-0.73;
lux=pow(lux, a1);    //      

digitalWrite(LED13,LOW);   //le temps de la mesure et du calcul est de 0.5ms

}//fin routine

///////////////////////////////////////////// Boucle correspondant à la fonction main
void loop() {
 lcd.setCursor(0,0);   
 lcd.print("LDR=75000*E^0.73");
  
  lcd.setCursor(0,2);   
  lcd.print("lux=");
  lcd.print(lux,0);
  lcd.print("    ");
  
} // fin loop

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