Para que negarlo, estamos rodeados de sensores que nos hacen la vida un poco más fácil, a veces por necesidad, otras por vaguería. Vamos a repasar el uso del sensor ALS y proximidad TMD2771 y lo controlaremos con Arduino, aunque puedes usar otra placa con micro o con FPGA.

En otras ocasiones hemos tratado el uno de sensores de luz basados en LDR, esta ocasión lo hacemos con un sensor basado en fotodiodos y comunicación I2C.

El integrado TMD2771

Este integrado es fabricado por AMS y es un sensor al que denominaremos mixto ya que en su interior encontramos tres posibilidades de medida.

El TMD2771 consta de un LED infrarrojo y dos fotodiodos, el primero de luz visible y el segundo infrarrojo. Además monta 3 ADCs, la lógica para controlarlos y realizar los cálculos, una memoria de 8 bits y una interfaz I2C.

La combinación de ambos fotodiodos con sus ADC y la lógica de control crean el sensor ALS. Por su parte la combinación de uno o dos fotodiodos y una segunda lógica de control crean el sensor de proximidad.

Sensor TMD2771
Sensor TMD2771

Sensor ALS

ALS no es otra cosa que la siglas en inglés de Ambient Ligh Sensor es decir, sensor de luz ambiente. Y es uno de los sensores más usados a día de hoy junto con el de temperatura ya que todos los smartphone montan al manos uno de estos sensores.

Dentro de un smartphone, el sensor ALS se suele usar para controlar el brillo de pantalla cuando varia la luz ambiente.

En este caso, la salida que proporciona el sensor es en lux.

Senor de proximidad

El sensor de proximidad también se monta en smartphons debido a su uso en otros para bloquear la pantalla cuando acercas el telefono a la cara al recibir una llamada o al escuchar una nota de audio en WhatsApp.

Quizá el  uso más original que he conocido de un sensor de proximidad en un smartphone es el uso que Casey Neistat y su equipo le dieron en su App original «Beme» la cual ya se encuentra extinta.


Sensor de proximidad y luminosidad con Arduino

Acceso a los datos del sensor ALS y proximidad TMD2771

Para acceder al sensor usamos su interfaz I2C y en resumen lo que haremos será leer registros de su memoria. Más adelante encontraras como usar el sensor ALS y proximidad TMD2771 usando Arduino.

Los datos de salida de los ADC que convierten la señal analógica de los fotodiodos en una señal digital es almacenada en los registros comprendidos entre 0x14 y 0x19. En la tabla que nos proporciona el fabricante en el Datasheet los encontramos en las últimas posiciones del mapa.

Mapa memoria 1 - AMS
Mapa memoria 1 – AMS
Mapa memoria 1 - AMS
Mapa memoria 1 – AMS

La manera en que que accedamos a leer los registros depende de la placa, micro o FPGA que usemos , para este ejemplo voy a usar Arduino debido a la existencia de una librería muy extendida y reconocida que recibe el nombre de wire.

Si analizas la columna de «Register Function» de las direcciones 0x14 y 0x15, observaras que ambas hablan sobre el ADC del canal 0. Sin embargo, la 0x14 habla del registro bajo y la 0x15 habla del registro alto.

Esta distinción es debida a que la salida de los ADC que usa el sensor ALS y proximidad TMD2771 es de 16 bits, pero los registros de memoria son de 8 bits.

Como la salida de los ADC ocupa el doble de «espacio» que un registro, cada palabra del ADC se divide por la mitad. El registro bajo hace referencia a los 8 bits menos significativos mientras que el registro alto hace referencia a los 8 bits más significativos.

Cuando queramos realizar una lectura, deberemos leer ambos registros de 8 bits y concatenarlos para generar la palabra de 16 bits que representa la lectura del sensor.

Como dato curioso decir que este problema se plantea debido a que a través de I2C solo se pueden enviar Bytes, nunca palabras de más de 8 bits, es por esto que los registro son de 8 bits. De esta manera se simplifica el uso de la información.

Configuración de registros

El TMD2771 es un sensor mixto que debe ser configurado tras cada corte de alimentación, es decir, cada vez que alimentamos el sensor, debemos confirar algunos registros para indicarle como queremos que se comporte.

El primer registro que vamos a configurar es el que en el mapa de memoria se denomina con ENABLE y se encuentra en la dirección de memoria 0x00.

Si analizamos la tabla del datasheet donde vemos el significado de ese registro, nuestro registro debe tomar el valor 0000 1111, este valor en binario se convierte a hexadecimal y queda como 0x0F. Es decir que en el registro 0x00 debemos configurar 0x0F.

Registros_ENABLE - AMS
Registros_ENABLE – AMS

También debemos configurar otos registros tal y como se aprecia en la siguiente tabla para pder usar ambos sensores sin interrupciones. Si tienes cualquier duda sobre alguno de los registros, preguntalo en los comentarios y la responderemos.

Dirección – Dato

0x00 – 0x0F

0x01 – 0xDB

0x02 – 0xFF

0x03 – 0xFF

0x0E – 0x04

0x0F – 0x20

Conversor de niveles

Debido a que el sensor trabaja a tensiones comprendidas entre 1.25 y 3.3v no lo podemos conectar directamente a Arduino o cualquier otra placa que no use estas tensiones. La solución es usar un conversor de niveles, en el caso del vídeo uso un módulo que implementa dos canales de conversión de niveles. Si no dispones de este tipo de módulos, siempre puedes montar el circuito con componentes discretos. Por ejemplo usando el transistor MOSFET de canal N BSS138 implementado el siguiente circuito.

Conversor niveles I2C
Conversor niveles I2C

Implementación con Arduino

De nuevo y para no faltar a la tradición, vamos a leer los datos del sensor ALS y proximidad TMD2771 usando Arduino ya que estoy seguro que tienes uno en casa 😉

El resumen rápido es que tras indicar la librería a usar y crear una constante con la dirección del sensor TMD2771, inicializamos comunicaciones y enviamos todos los registros de configuración a la memoria usando la función set, la cual he creado solo para este caso.

En el loop conectamos con el sensor, se cambia su puntero a la dirección de memoria 0x14 y se piden 6 registros a partir de el. Los dos primeros de el primer fotodiodo, los dos segundos del segundo fotodiodo y los dos últimos del sensor de proximidad.

#include "Wire.h"

//Dirección del integrado (siempre 0x39)
#define addr 0x39

void setup()
{
Wire.begin(); //Inicializar I2C
Serial.begin(9600); //Inicializar puerto serie

//Configurar los registros para:
set(0x00, 0x0F); //Activar ALS, proximidad, temporizador y sensor
set(0x01, 0xDB); //Tiempo de integración del ALS 101ms
set(0x02, 0xFF); //Tiempo de integración de proximidad (0xFF - 2.72ms, recomendado)
set(0x03, 0xFF); //Tiempo de espera
set(0x0E, 0x04); //Número de pulsos emiidos por el LED (4)
set(0x0F, 0x20); //Registro de control (LED 100%, CH1 para proximidad, again x1
conversor
//Los registros están descritos en el datasheet del TMD2771

delay(800);
}

void loop()
{
byte registro[6]; //Registros para almacenar los datos

//Petición de los registros a partir del 0x14
Wire.beginTransmission(addr);
Wire.write(0x14 | 0xA0);
Wire.endTransmission();
//Pedir 6 registros 0x14 al 0x19
Wire.requestFrom(addr, 6);

//Recuperar los registros desde I2C
if(Wire.available() == 6)
{
registro[0] = Wire.read();
registro[1] = Wire.read();
registro[2] = Wire.read();
registro[3] = Wire.read();
registro[4] = Wire.read();
registro[5] = Wire.read();
}

//Calcular proximidad
int proximidad = registro[5]<<8|registro[4];

//Calcular luminancia
int ch0 = registro[1]<<8|registro[0];
int ch1 = registro[3]<<8|registro[2];
float CPL = (101.0) / 24.0;
float fotodiodo1 = (ch0 - 2 * ch1) / CPL;
float fotodiodo2 = (0.6 * ch0 - ch1) / CPL;

float luminancia = 0.0; if(fotodiodo1 > fotodiodo2)
{
luminancia = fotodiodo1;
}
else if(fotodiodo2 > fotodiodo1)
{
luminancia = fotodiodo2;
}

//Mostrar datos
Serial.print("Proximidad: ");
Serial.print(proximidad);
Serial.print("\t | ALS: ");
Serial.print(luminancia);
Serial.println(" lux");
delay(1000);
}

void set(byte dir, byte value){
Wire.beginTransmission(addr); //Iniciar comunicación
Wire.write(dir); //Seleccionar registro
Wire.write(value); //Enviar valor
Wire.endTransmission(); //Finalizar comunicación

}

Enrique Gómez

Ingeniero Electrónico Industrial y Automático, amante de la comunicación audiovisual y de la divulgación ingenieril y científica. Friki de Star Wars, cuenta más de lo que parece. Puedes saber más sobre mi y sobre mis trabajos en www.enriquegomez.me