Sensors de llum amb Arduino i Phyphox

He de dir d’entrada que en l’experimentació en Física al laboratori escolar el més pràctic la major part de les vegades és utilitzar com a luxímetre el sensor de llum del telèfon mòbil. He escrit algun exemple d’utilització del sensor de llum dels telèfons en la pàgina Experiments de ciències amb dispositius mòbils i en el document Experimentación en física con dispositivos móviles.

Però hi ha vegades que convé disposar d’un sensor extern al telèfon per a realitzar mesures d’il·luminació, per exemple perquè interessa que formi part d’un conjunt més ampli de sensors (temperatura, humitat, etc.) per estudiar la influència del pas del dia en un hivernacle, o perquè es volen mesurar canvis ràpids en la il·luminació. En aquests casos un sensor de llum connectat a un Arduino pot ser la solució.

Al mercat es disposa de diferents tipus de sensors. Jo us presento el “sofisticat” sensor BH1750, la “humil” fotoresistència o la seva alternativa, el fototransistor.

Lúxmetre amb el sensor BH1750

El BH1750 es un sensor digital del nivell de llum que es connecta amb facilitat a la placa Arduino a través del bus I2C. Es troben al mercat dos tipus de sensors que funcionen igual de bé ja que tenen el mateix xip (BH1750), però un d’ells te un caputxó de plàstic translúcid que difumina la llum que li arriba i un connector amb cables integrat (BH1750FVI), i l’altre no (GY-302). Els dos son molt barats en el mercat oriental (un o dos euros).

Aquest sensor està dissenyat per a que el rang espectral que recull sigui similar al de l’ull humà per la qual cosa pot proporcionar la mesura en luxes i així podem muntar un lúxmetre del mateix nivell que el que s’aconsegueix amb el sensor de llum dels telèfons mòbils. El sensor és capaç de mesurar amb una resolució de 0,5 luxes però a una velocitat de recollida de dades moderada (120 ms), el que va bé per mesurar la il·luminació d’una habitació però que no permet mesurar canvis ràpids en la intensitat de la llum. Teniu més informació a la web de Lluis Llamas i a la de ElectroGeek.

Totes dues plaquetes amb el sensor BH1750 funcionen entre 2,6 V i 5,5 V, i les mesures s’obtenen a través de la interfície I²C de manera que els pins es connecten

  • VIN: Connexió de l’alimentació de 3,3 o 5 V
  • GND: Connexió a terra (0 V)
  • SCL: a SCL (A5 en Arduino UNO, 22 en esp32)
  • SDA: a SDA (A4 en Arduino UNO, 21 en esp32)
  • ADDR: es deixa lliure

En el dibuix de dalt es veu el sensor connectat a una placa Wemos D1 R32, però pot connectar-se a un Arduino UNO si les dades només es volen obtenir pel port sèrie de l’ordinador, o a qualsevol placa amb microprocesador esp32 que disposa de connexió bluetooth i així es podran aconseguir les dades a través del mòbil.

Per instalar a l’IDE d’Arduino una placa amb el microprocessador esp32 s’han d’instal·lar els controladors de l’esp32, si no l’estan encara. Per instal·lar-los s’ha d’anar a l’IDE de Arduino i en Archivo/Preferencias, a la pestanya d’Ajustes s’enganxa la direcció https://dl.espressif.com/dl/package_esp32_index.json en el Gestor de URLs Adicionales de Tarjetas.

Després a Herramientas/Placa/Gestor de tarjetas apareixerà esp32 by Espressif Systems. Es pitja en el botó Instalar. Trigarà una mica mentre indica Descargardo definiciones de tarjetas.

Quan s’hagi descarregat se busca la placa en Herramientas/Placa, es selecciona per defecte el mòdul ESP 32 Dev, o el de la placa concreta que es disposi.

El projecte

El projecte que proposo utilitzar permet recollir les dades en l’aplicació Phyphox que ja hem usat amb anterioritat en altres entrades. El projecte es basa en l’exemple BH1750test de la llibreria del sensor, que s’ha d’installar a l’IDE d’Arduino i s’ha de cridar en el codi.

Per instal·lar la llibreria del sensor BH1750 s’ha d’anar a github, clicar en code i baixar-se el zip. Després a l’IDE, en programa, incluir libreria, añadir biblioteca zip, es selecciona BH1750-master.zip.

El projecte també necessita la llibreria wire, que ja està instal·lada per defecte a l’IDE, i la llibreria phyphoxBle.h que és necesària per a que la placa es comuniqui via bluetooth amb l’aplicació Phyphox del telèfon. En github s’ha de pitjat en code i baixar el zip phyphox-arduino-master.zip. S’instal·la a l’IDE com totes les llibreries en programa, incloure llibreria, incloure llibreria zip.

El projecte a instal·lar, sketch__Luxometro_BH1750_Phyphox.ino, es pot descarregar i obrir, o bé es pot copiar el següent codi a l’IDE d’Arduino:

/*
Medida de la iluminancia utilizando el sensor BH1750.
La libreria del sensor se puede bajar de https://github.com/claws/BH1750
Este proyecto inicia el sensor BH1750 usando la resolución más baja. Si no se 
indica nada la resolución por defecto es la más alta.

El proyecto se ha de instalar en una placa con microprocesador esp32, que dispone de Bluetooth
Se ha de seleccionar la placa ESP32 DEV Module o DOIT ESP32 DEVKIT V1.

Los datos se pueden visualizar en el monitor serie del IDE de Arduino 
y con el programa para ordenador RealTerm, https://sourceforge.net/projects/realterm/
Los datos también se pueden visualizar en el teléfono móvil o la tableta 
con la aplicación Phyphox (https://phyphox.org/) a través de BT (BlueTooth).
Este sketch és una adaptación del sketch Rangefinder, ejemplo incluído en la librería Phyphox BLE, 
y del sketch BH1750test incluído en la libreria BH1750.

Conexiones
  - VCC to 3V3 or 5V
  - GND to GND
  - SCL to SCL (A5 on Arduino Uno, Leonardo, etc, or 21 on Mega and Due, on
    esp8266 free selectable)
  - SDA to SDA (A4 on Arduino Uno, Leonardo, etc, or 20 on Mega and Due, on
    esp8266 free selectable)
  - ADD to (not connected) or GND

ADD pin is used to set sensor I2C address. If it has voltage greater or equal
to 0.7VCC voltage (e.g. you've connected it to VCC) the sensor address will be
0x5C. In other case (if ADD voltage less than 0.7 * VCC) the sensor address
will be 0x23 (by default).
*/

#include <BH1750.h>
#include <Wire.h>
#include <phyphoxBle.h>   //Phyphox BLE library

BH1750 lightMeter;

void setup() {
  Serial.begin(9600);

  // Initialize the I2C bus (BH1750 library doesn't do this automatically)
  Wire.begin();
  // On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3);
  // For Wemos / Lolin D1 Mini Pro and the Ambient Light shield use
  // Wire.begin(D2, D1);

  lightMeter.begin(BH1750::CONTINUOUS_LOW_RES_MODE); //menor resolución, pero más medidas por segundo
//Si no se pone nada la resolució es la más alta
// BH1750::CONTINUOUS_HIGH_RES_MODE     (1 lux, 120 ms)
// BH1750::CONTINUOUS_HIGH_RES_MODE_2   (0,5 lux, 120 ms)
// BH1750::CONTINUOUS_LOW_RES_MODE      (4 lux, 16 ms)
// BH1750::ONE_TIME_HIGH_RES_MODE
// BH1750::ONE_TIME_HIGH_RES_MODE_2
// BH1750::ONE_TIME_LOW_RES_MODE

  Serial.println(F("BH1750 Test begin"));

PhyphoxBLE::start("Luxometro");

    //Experiment
    PhyphoxBleExperiment experiment;

    experiment.setTitle("Luxómetro"); 
    experiment.setCategory("Arduino Experiments");
    experiment.setDescription("Dibuja la gráfica de la iluminancia (en lux) con relación al tiempo.");

    //View
    PhyphoxBleExperiment::View view;

    //Graph
    PhyphoxBleExperiment::Graph graph;
    graph.setLabel("Iluminancia");
    graph.setUnitX("s");
    graph.setUnitY("lux");
    graph.setLabelX("tiempo");
    graph.setLabelY("Iluminancia");

    //In contrast to other examples, we will not generate the timestamp on the phone.
    //For experiments with a high data rate, we can achieve a better temporal
    //accuracy if we generate the timestamp on the Arduino and send it in pairs with the
    //measured values.
    
    graph.setChannel(1,2);
    
    view.addElement(graph);                 //Attach graph to view
    experiment.addView(view);               //Attach view to experiment
    PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server
}

void loop() { 

  float t = 0.001 * (float)millis();       //Tiempo en segundos
  float lux = lightMeter.readLightLevel();
  
  PhyphoxBLE::write(t, lux); // envia los datos a phyphox
  
  Serial.print("Iluminancia: ");
  Serial.print(lux);
  Serial.println(" lx");
  //delay(1000);  //si se quieren espaciar las medidas
}

Ara, si ja s’ha seleccionat la placa a Eines i el port COM corresponent, s’ha de carregar el codi del projecte (fletxa a dalt a l’esquerra de la pantalla de l’IDE).

Una vegada carregat el projecte es pot comprovar que la estació ja està prenent valors d’il luminància si obriu el monitor sèrie propi de l’IDE (lupa a dalt a la dreta) ja que el projecte incorpora la sortida de dades pel port sèrie a 9600 bauds.

Però es pot desconnectar l’Arduino de l’ordinador i fer-lo funcionar autònomament, connectant-li una pila o una bateria, com les bateries externes que s’utilitzen pels mòbils. Els valors que recull el sensor es podran visualitzar en el telèfon mòbil amb l’aplicació Phyphox ja que la placa li està enviant les dades per bluetooth.

Per obtenir les dades en el telèfon s’ha de tenir connectat el bluetooth i la ubicació, s’ha d’obrir l’aplicació Phyphox i s’ha de pitjar en el botó més. Apareixerà una pantalla com la de sota a l’esquerra on es pot escollir entre afegir un experiment amb codi QR, afegir-lo per bluetooth o iniciar un experiment simple que es genera “simplement” escollint el sensor del telèfon que es vol utilitzar. Si s’opta per experiment per bluetooth apareix una pantalla en la que s’ha de seleccionar el dispositiu Luxometro, que és el nom que s’ha assignat en el codi del projecte. En aquest moment l’app pregunta si es vol guardar l’experiment en la llista de la pantalla d’inici per altres vegades.

Una vegada dins la pantalla del lúxmetre, si es pitja en la fletxa de dalt l’app començarà a agafar dades d’il·luminància que aniran apareixen en el gràfic com el de la captura de pantalla de dalt a la dreta. El gràfic es pot ampliar i consultar els valors sobre ell mateix. En aturar la presa de dades es poden guardar o enviar per tractar-les posteriorment i/o guardar aquest experiment concret amb els seus valors en la pantalla inicial de l’aplicació.

Fotoresistència

Una alternativa en alguns casos al sofisticat sensor BH1750 és la humil fotoresistència que, encara que és molt difícil que en doni el valor de la il·luminància en luxes, és molt més barat (20 unitats un euro), és més versàtil i pot ser més ràpida en mesurar les variacions de llum.

Una fotoresistència és un component electrònic que disminueix la resistència amb l’augment de la intensitat de la llum incident. Pot ser anomenat també fotoresistor, fotoconductor, cèl·lula fotoelèctrica o resistor dependent de la llum, LDR (light-dependent resistor).

El seu funcionament es basa en l’efecte fotoelèctric. Un fotorresistor és un semiconductor d’alta resistència com el sulfur de cadmi, CdS. Si la llum que li arriba dona l’energia suficient als electrons per saltar a la banda de conducció disminueix la seva resistència. Els valors típics de la seva resistència varien entre 10 MΩ en la foscor i 5 kΩ amb llum brillant.

Pel que sembla, la variació del valor de la resistència LDR manté un cert retard d’uns 30 ms quan varia la intensitat de llum que li arriba, per la qual cosa tindria limitat el número de mesures quan la llum varia amb ràpid. Aquesta lentitud donaria avantatja en algunes aplicacions ja que es suavitzarien variacions ràpides d’il·luminació que podrien donar valors inestables, per exemple amb llum de tubs fluorescents, el que ja era en el cas del sensor BH1750 que hem vist abans. En altres aplicacions (saber si és de dia o és de nit) la lentitud de la detecció no és important.

Però el cas és que ja he treballat amb anterioritat amb fotoresistències en els equips EXAO, amb el dattaloguer LittleDoctor, o connectada a un telèfon mòbil, entre d’altres, i he aconseguit mesurar el temps que triga una boleta en passar davant el sensor o veure els canvis de lluminositat d’una bombeta com a conseqüència de la freqüència del corrent altern amb el que està alimentada, i per tot això cal que el sensor sigui capaç de mesurar cada 10 ms o menys.

Gràfica obtinguda amb la fotoresistència de la placa LittleDoctor. Amb un període de 10 ms la freqüència del parpelleig de la llum que s’obté és de 100 Hz i, per tant, la del corrent altern de 50 Hz
Gràfica obtinguda amb una fotoresistència connectada una tauleta i l’aplicació Audiotime+. Amb un període de 10 ms la freqüència del parpelleig de la llum que s’obté és de 100 Hz i, per tant, la del corrent altern de 50 Hz.

Si les fotoresistències son capaces de mesurar tant ràpid pot ser també és possible mesurar la freqüència del parpelleig de la llum connectant-les a una placa Arduino. He provat diferents projectes i explico els resultats més a baix.

Connexió de la fotoresistència a Arduino

La fotoresistència és una resistència i per tant no te polaritat, així que no cal preocupar-se a on va cada pota. El que s’ha de fer es connectar una de les potes a 3,3 o a 5 V i l’altra a una entrada analògica, per exemple a la A0 (Arduino) o a la 2 (esp32 amb bluetooth). També es necessita una resistència d’uns 10 kΩ connectada entre el terra (GND) i la mateixa entrada analògica de la fotoresistència, com es veu a les fotos de sota.

El valor de la resistència en sèrie ha de ser de l’ordre de la mínima de la fotoresistència. Una alternativa és comprar el sensor amb la resistència integrada com és el cas del sensor de llum KY-018, que tampoc és car.

Projecte amb Phyphox

El codi per a una fotoresistència en un projecte Arduino és relativament simple i no necessita cap llibreria per ella mateixa, però com que en aquest primer projecte amb la LDR vull fer la lectura dels valors en Phyphox a través de bluetooth s’han de fer els mateixos passos per instal·lar la llibreria que en el projecte de dalt del BH1750, si no s’han fet abans.

El projecte a instal·lar, sketch_sensor_LDR_phyphox.ino, està basat en una adaptació de l’sketch Rangefinder, exemple inclòs en la llibreria Phyphox BLE i en l’entrada de Lluis Llamas Medir nivel de luz con Arduino y fotoresistencia LDR (GL55). Es pot descarregar i obrir, o bé es pot copiar el següent codi a l’IDE d’Arduino:

//Medida del nivel de iluminación con una fotorresistencia LDR
//en una placa con microprocesador esp32, que dispone de Bluetooth
//Se ha de seleccionar la placa ESP32 DEV Module o DOIT ESP32 DEVKIT V1
//Los datos se pueden visualizar en el monitor serie del IDE de Arduino 
//y con el programa para ordenador RealTerm, https://sourceforge.net/projects/realterm/
//Los datos también se pueden visualizar en el teléfono móvil o la tableta 
//con la aplicación Phyphox (https://phyphox.org/) a través de BT (BlueTooth)
//Este sketch és una adaptación del sketch Rangefinder, ejemplo incluído en la librería Phyphox BLE. 

//Conexiones: Fotorresistencia en serie con resistencia de 10K 
//Resistencia a GND, Fotorresistencia a +3.3 o 5 V, común de las dos resistencias a 2

#include <phyphoxBle.h>   //Phyphox BLE library

const long A = 10000;     //Resistencia del LDR en oscuridad en KΩ
const int B = 15;        //Resistencia del LDR a la luz en KΩ
const int Rc = 10;       //Resistencia calibracion en KΩ
const int LDRPin = 2;   //Pin del LDR


void setup() {
    PhyphoxBLE::start("Sensor de luz");

    //Experiment
    PhyphoxBleExperiment experiment;

    experiment.setTitle("Sensor de luz LDR"); 
    experiment.setCategory("Arduino Experiments");
    experiment.setDescription("Dibuja la gráfica de la luminosidad (en unidades arbitrarias) con relación   al tiempo.");

    //View
    PhyphoxBleExperiment::View view;

    //Graph
    PhyphoxBleExperiment::Graph graph;
    graph.setLabel("Luminosidad");
    graph.setUnitX("s");
    graph.setUnitY("ua");
    graph.setLabelX("tiempo");
    graph.setLabelY("Luminosidad");

    //In contrast to other examples, we will not generate the timestamp on the phone.
    //For experiments with a high data rate, we can achieve a better temporal
    //accuracy if we generate the timestamp on the Arduino and send it in pairs with the
    //measured values.
    
    graph.setChannel(1,2);

    view.addElement(graph);                 //Attach graph to view
    experiment.addView(view);               //Attach view to experiment
    PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server

    Serial.begin(9600);  //inicia el terminal serie
}

void loop() {
    float t = 0.001 * (float)millis();       //Tiempo en segundos
    float V = analogRead(LDRPin);  //en la parte proporcional (voltaje) 
    float luminosidad = ((long)V*A*10)/((long)B*Rc*(4095-V));  //usar si LDR entre 2 y Vcc
    //float luminosidad = ((long)(4095-V)*A*10)/((long)B*Rc*V);  //usar si LDR entre GND y 2 
    //Las ecuaciones se han copiado de 
    // https://www.luisllamas.es/medir-nivel-luz-con-arduino-y-fotoresistencia-ldr/
   
    PhyphoxBLE::write(t, luminosidad); // envia los datos a phyphox

    Serial.print(t,3); //Escribe el tiempo en segundos con tres decimales
    Serial.print("; "); //separa los valores de tiempo y distancia con un punto y coma
    Serial.println(luminosidad); //Escribe la luminosidad en unidades arbitrarias
  
    PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards.
}

Com es veu en la captura de pantalla, els valors (en unitats arbitràries) que s’obtenen en Phyphox de la il·luminància son pocs en un interval de 100 ms, el que impedeix mesurar variacions de la llum molt ràpides, com les d’un fluorescent.

Provant, provant, he aconseguit obtenir suficient quantitat de valors per visualitzar les variacions de lluminositat de les bombetes només amb un projecte mínim en el que les dades s’han de llegir pel port sèrie de l’ordinador. El codi del projecte sketch_sensor_LDR_IDE_Arduino.ino  és:

//Medida del nivel de iluminación con una fotorresistencia LDR

//en una placa Arduino o con microprocesador esp32
//Se ha de seleccionar la placa que corresponda: Arduino Uno, ESP32 DEV Module o DOIT ESP32 DEVKIT V1
//Los datos se pueden visualizar en el monitor serie del IDE de Arduino 
//y con el programa para ordenador RealTerm, https://sourceforge.net/projects/realterm/

//Conexiones: Fotoresistencia en serie con resistencia de 10K 
//Resistencia a GND, Fotorresistencia a +3.3 o +5 V, 
//común de las dos resistencias a A0 (Arduino) o a 2 (esp32)

const int LDRPin = 2;   //Pin del LDR en esp32
    
void setup() {
    Serial.begin(9600);  //inicia el terminal serie  
}

void loop() {
    int t = millis();       //Tiempo en milisegundos
    int V = analogRead(LDRPin);  //en la parte proporcional (voltaje) 

    Serial.print(t); //Escribe el tiempo en milisegundos
    Serial.print("; "); //separa los valores de tiempo y distancia con un punto y coma
    Serial.println(V); //Escribe la luminosidad en unidades arbitrarias (voltaje)
}

En la gràfica es veu com 10 variacions de llum es produeixen aproximadament en 100 ms, el que correspon a una freqüència de 100 Hz. La lectura i gravació de les dades està feta amb Realterm i la gràfica amb SciDavis.

Encara que la veritat és que la major part de les vegades no aconsegueixo unes lectures tant ràpides, per la qual cosa no m’atreveixo a animar-vos a utilitzar el sensor per mesurar temps petits, malgrat que funciona perfectament com a indicador de la quantitat de llum ambiental. Potser algú ens pot il·luminar una mica i aclarir-nos la confusió que porto.

Fototransistor

Sembla ser que la velocitat de resposta dels fototransistors és més elevada que la de les fotoresistències i per això he provat amb el fototransistor TEMT6000 que ja ve preparat per a connectar-se directament a una de les entrades analògiques de les plaques Arduino.

El pin GND va a terra (GND), el pin VCC a 3,3 o 5 V i el pin OUT va a l’entrada analògica A0 en Arduino UNO o a la 2 en un esp32, com s’intueix en la foto de sota.

El sensor no necessita cap llibreria per funcionar i, per tant, quan es volen obtenir els valors només pel port sèrie de l’ordinador recull les dades carregant el mateix projecte sketch_sensor_LDR_IDE_Arduino.ino que per a la fotoresistència. Si els valors es volen recollir en un telèfon amb Phyphox el projecte per la fotoresistencia s’ha de modificar una mica i quedaria com el sketch_fototransistor_phyphox.ino que teniu a sota. En tots dos casos, però, els resultats quant a velocitat son molt similars als aconseguits amb la fotoresistència.

//Medida del nivel de iluminación con un fototransistor TEMT6000

//en una placa con microprocesador esp32, que dispone de Bluetooth
//Se ha de seleccionar la placa ESP32 DEV Module o DOIT ESP32 DEVKIT V1
//Los datos se pueden visualizar en el monitor serie del IDE de Arduino 
//y con el programa para ordenador RealTerm, https://sourceforge.net/projects/realterm/
//Los datos también se pueden visualizar en el teléfono móvil o la tableta 
//con la aplicación Phyphox (https://phyphox.org/) a través de BT (BlueTooth)
//Este sketch és una adaptación del sketch Rangefinder, ejemplo incluído en la librería Phyphox BLE. 

//Conexiones: GND a GND, VCC a +3.3 o 5 V, OUT a 2

#include <phyphoxBle.h>   //Phyphox BLE library

const int LDRPin = 2;   //Pin del LDR

void setup() {
    PhyphoxBLE::start("Fototransistor");

    //Experiment
    PhyphoxBleExperiment experiment;

    experiment.setTitle("Sensor de luz Fototransistor"); 
    experiment.setCategory("Arduino Experiments");
    experiment.setDescription("Dibuja la gráfica de la luminosidad (en unidades arbitrarias) con relación al tiempo.");

    //View
    PhyphoxBleExperiment::View view;

    //Graph
    PhyphoxBleExperiment::Graph graph;
    graph.setLabel("Luminosidad");
    graph.setUnitX("s");
    graph.setUnitY("ua");
    graph.setLabelX("tiempo");
    graph.setLabelY("Luminosidad");

    //In contrast to other examples, we will not generate the timestamp on the phone.
    //For experiments with a high data rate, we can achieve a better temporal
    //accuracy if we generate the timestamp on the Arduino and send it in pairs with the
    //measured values.
    
    graph.setChannel(1,2);

    view.addElement(graph);                 //Attach graph to view
    experiment.addView(view);               //Attach view to experiment
    PhyphoxBLE::addExperiment(experiment);  //Attach experiment to server

    Serial.begin(9600);  //inicia el terminal serie
}

void loop() {
    float t = 0.001 * (float)millis();       //Tiempo en segundos
    float V = analogRead(LDRPin);  //en la parte proporcional (voltaje) 
   
    PhyphoxBLE::write(t, V); // envia los datos a phyphox

    Serial.print(t,3); //Escribe el tiempo en segundos con tres decimales
    Serial.print("; "); //separa los valores de tiempo y distancia con un punto y coma
    Serial.println(V); //Escribe la luminosidad en unidades arbitrarias
  
    PhyphoxBLE::poll(); //Only required for the Arduino Nano 33 IoT, but it does no harm for other boards.
}


Deixa un comentari

Fill in your details below or click an icon to log in:

WordPress.com Logo

Esteu comentant fent servir el compte WordPress.com. Log Out /  Canvia )

Facebook photo

Esteu comentant fent servir el compte Facebook. Log Out /  Canvia )

S'està connectant a %s

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.