¿Cuánta radiación UVA te está llegando de verdad en la terraza a las 14:00 de un día de enero en Santiago? El índice UV que da el pronóstico es un promedio regional; un sensor en tu propio techo te dice lo que pasa ahí, minuto a minuto. El TSL2585 es un chip de ams OSRAM que mide tres cosas a la vez: luz visible (canal fotópico), infrarrojo y UVA en la banda de 315 a 400 nm, todo por I2C.
En esta guía vas a conectar el breakout del TSL2585 a un Arduino UNO, un ESP32 o una Raspberry Pi, cargar el código de ejemplo en Arduino o CircuitPython, entender qué significan los "counts" que entrega y por qué no son lux ni µW/cm². Al final vas a saber comparar tus lecturas de UVA contra un sensor de luz visible como el BH1750 y armar un registro propio de exposición solar.

Concepto: qué mide un sensor "tres en uno"
El TSL2585 tiene tres fotodiodos con filtros distintos:
- Fotópico: filtrado para parecerse a la sensibilidad del ojo humano. Es el canal que usarías para "¿hay mucha o poca luz?".
- Infrarrojo (IR): responde sobre todo por encima de 700 nm. Sirve para distinguir luz solar (con mucho IR) de un LED blanco (casi sin IR).
- UVA (315 a 400 nm): banda angosta. Es lo poco común del chip: la mayoría de sensores I2C baratos de luz no tienen un canal UVA dedicado.
Un detalle que conviene tener claro desde el principio: el sensor entrega cuentas (counts), no unidades físicas. El canal visible no está calibrado a lux y el canal UVA trae un byte de calibración de fábrica que solo corrige las cuentas, no las convierte a µW/cm². Eso no lo hace inútil; significa que mides en unidades relativas, y si quieres un número absoluto tienes que calibrar contra una referencia (más abajo te explico cómo).
Por qué llega a 1 milílux
El chip combina ganancia automática de hasta x4096 con tiempo de integración ajustable. La integración es cuánto rato el fotodiodo "junta" carga antes de que el ADC la lea: más tiempo = más sensibilidad pero más riesgo de saturar. La ganancia amplifica esa carga. Con luz tenue, el auto gain sube la ganancia; al sol directo la baja. Por eso el mismo chip sirve para medir una lámpara de curado de resina en interior y el sol del mediodía, algo que un LDR con divisor resistivo no logra sin cambiar resistencias.
Hardware: el breakout y sus pines
El TSL2585 por sí solo funciona a 1,8 V de alimentación y lógica, un voltaje que casi ningún microcontrolador de hobby usa. El breakout de Adafruit resuelve eso con regulador y conversión de nivel, así que puedes alimentarlo con 3,3 V o 5 V y usar lógica de 3 a 5 V sin componentes extra.

| Pin | Función |
|---|---|
| VIN | Alimentación. Usa el mismo voltaje que la lógica de tu placa: 5 V para un Arduino UNO, 3,3 V para un ESP32 o una Raspberry Pi. |
| GND | Tierra común de alimentación y lógica. |
| SCL | Reloj I2C, con conversión de nivel y pull up de 10 kΩ en la placa. |
| SDA | Datos I2C, con conversión de nivel y pull up de 10 kΩ en la placa. |
| SYNC | Entrada para disparar lecturas sincronizadas con un pulso externo. También se puede configurar como GPIO open drain. |
| INT | Salida de interrupción open drain; avisa cuando termina una conversión. |
| STEMMA QT | Dos conectores JST SH de 4 pines compatibles con Qwiic, para conectar sin soldar. |
La dirección I2C por defecto es 0x39. Ojo: es la misma dirección que usan otros sensores de luz (por ejemplo el TSL2561 con su pin ADDR flotando o el APDS-9960), así que si tu bus ya tiene uno de esos, vas a tener un conflicto. El síntoma típico es que begin() devuelve error o que lees valores sin sentido.
Hay un LED verde de encendido en la cara frontal. Si vas a medir luz muy tenue o alimentar con batería, conviene cortar el jumper "LED" de la parte trasera: ese LED está a milímetros del fotodiodo y aporta consumo innecesario.
Conexiones
Con Arduino UNO (5 V)
Son cuatro cables, con cable STEMMA QT o con jumpers en protoboard:
- 5V de la placa → VIN (rojo)
- GND → GND (negro)
- SCL → SCL (amarillo)
- SDA → SDA (azul)
En el UNO, SDA y SCL están en los pines junto a AREF (y duplicados en A4/A5).


Con ESP32 (3,3 V)
Mismo esquema, pero VIN va a 3V3, no a 5V. En un ESP32 DevKit los pines I2C por defecto son GPIO21 (SDA) y GPIO22 (SCL). Como el breakout ya trae pull ups de 10 kΩ, no necesitas agregar resistencias.
Con Raspberry Pi o una placa CircuitPython
En la Raspberry Pi: 3V3 (pin 1) → VIN, GND (pin 6) → GND, SCL (GPIO3, pin 5) → SCL y SDA (GPIO2, pin 3) → SDA. Recuerda habilitar I2C con sudo raspi-config antes de probar.

Software en Arduino
Instala la librería desde el IDE: Herramientas → Administrar bibliotecas, busca Adafruit TSL2585 e instálala. Cuando te pregunte por dependencias, elige Install all. Si ya las tenías instaladas, actualízalas antes de compilar; una versión vieja de Adafruit BusIO es la causa más común de errores de compilación raros.

Este es el sketch de ejemplo de la librería. Configura una integración de 50 ms e imprime los tres canales normalizados a ganancia 1x:
#include <Adafruit_TSL2585.h>
Adafruit_TSL2585 tsl2585;
void setup() {
Serial.begin(115200);
// Wait for the Serial Monitor to open on native USB boards.
// Remove this while (!Serial) loop to run without a USB connection.
while (!Serial) {
delay(10);
}
delay(250);
Serial.println("Adafruit TSL2585 photopic, infrared, and UVA sensor test");
if (!tsl2585.begin()) {
Serial.println("Could not find a TSL2585. Check the wiring and I2C address.");
while (true) {
delay(10);
}
}
Serial.print("Device ID: 0x");
Serial.println(tsl2585.getDeviceID(), HEX);
Serial.print("Revision ID: 0x");
Serial.println(tsl2585.getRevisionID(), HEX);
Serial.print("Factory UVA calibration byte: ");
Serial.println(tsl2585.getUVCalibration());
// Register-based results support integration times from 0.25 ms to 90 ms.
if (!tsl2585.setIntegrationTime(50)) {
Serial.println("Could not set the integration time.");
while (true) {
delay(10);
}
}
Serial.print("Integration time: ");
Serial.print(tsl2585.getIntegrationTime(), 2);
Serial.println(" ms");
Serial.println();
Serial.println("Photopic 1x\tInfrared 1x\tUVA 1x\tSaturated");
}
void loop() {
if (!tsl2585.dataReady()) {
delay(100);
return;
}
tsl2585_data_t data;
if (tsl2585.readData(&data)) {
bool saturated = false;
if (data.photopic_saturated || data.infrared_saturated ||
data.uva_saturated) {
saturated = true;
}
Serial.print(data.photopic_1x, 1);
Serial.print('\t');
Serial.print(data.infrared_1x, 1);
Serial.print('\t');
Serial.print(data.uva_1x, 1);
Serial.print('\t');
if (saturated) {
Serial.print("saturated");
}
Serial.println();
}
delay(100);
}
Qué hace cada parte:
begin()busca el chip en 0x39. Si falla, revisa cables y dirección antes que nada.getUVCalibration()lee el byte de calibración UVA de fábrica. Anótalo: te sirve si algún día cambias de sensor y quieres comparar series.setIntegrationTime(50)fija 50 ms. El rango válido para este modo es de 0,25 a 90 ms.readData()llena la estructuratsl2585_data_t. Los campos_1xvienen normalizados a ganancia 1x, así que puedes comparar lecturas aunque el auto gain haya cambiado de ganancia entre una y otra. Esa es la razón de usar esos campos y no las cuentas crudas.- Los flags
*_saturatedte avisan si algún canal se pegó al máximo.
Abre el Monitor Serie a 115200 baudios. Vas a ver el ID del dispositivo, la revisión, el byte de calibración y luego columnas con fotópico, IR y UVA.

Software en CircuitPython o Python (Raspberry Pi)
En una Raspberry Pi con Blinka instalado, la librería se instala con:
pip3 install adafruit-circuitpython-tsl2585
En una placa CircuitPython, copia a CIRCUITPY/lib las carpetas adafruit_bus_device/, adafruit_register/ y el archivo adafruit_tsl2585.mpy (vienen en el Project Bundle de la guía original). El ejemplo es corto:
# SPDX-FileCopyrightText: Copyright (c) 2026 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Print three channel measurements from the TSL2585."""
import time
import board
import adafruit_tsl2585
i2c = board.I2C()
sensor = adafruit_tsl2585.TSL2585(i2c)
print(f"Found TSL2585, revision {sensor.revision_id}")
while True:
if sensor.data_ready:
data = sensor.measurement
print(f"Photopic: {data.photopic}, IR: {data.infrared}, UVA: {data.uva}")
if data.photopic_saturated or data.infrared_saturated or data.uva_saturated:
print("Warning: at least one channel saturated")
print()
time.sleep(0.5)
La lógica es la misma que en Arduino: esperar data_ready, leer measurement e imprimir los tres canales, con aviso si alguno saturó. En una Pi, lo corres con python3 code.py.
Pruebas: comparar UVA contra luz visible
Aquí está el ángulo que la guía original no desarrolla. Deja corriendo el sketch y prueba estas cuatro situaciones:
- Ampolleta LED blanca a 30 cm: fotópico alto, IR casi nulo, UVA casi nulo. Los LED blancos emiten muy poco fuera del visible.
- Detrás de una ventana al sol: fotópico alto, IR alto, UVA bajo. El vidrio común corta buena parte del UVB y atenúa el UVA; por eso sirve para comprobar que tu canal UVA responde a lo que debe.
- Sol directo en el exterior: los tres canales altos. Si alguno marca
saturated, baja el tiempo de integración (por ejemplo a 10 ms) y vuelve a probar. - Linterna UV de 395 nm o lámpara de curado de resina: UVA muy alto, fotópico moderado.
Si además tienes un BH1750 conectado al mismo bus I2C (dirección 0x23, no choca con 0x39), puedes graficar lux del BH1750 contra cuentas UVA del TSL2585 a lo largo de un día. La razón UVA/visible sube al mediodía y en días de nubosidad alta delgada, algo que un sensor de luz visible solo nunca te va a mostrar. Ese es justamente el valor de tener un canal UVA propio.
Errores comunes
- "Could not find a TSL2585": casi siempre es SDA/SCL invertidos o VIN sin conectar. Un escáner I2C debería mostrar 0x39.
- Todos los canales en saturated: integración demasiado larga para luz solar directa. Baja a 5 a 10 ms.
- UVA en cero bajo el sol: revisa si estás midiendo a través de vidrio o de una carcasa de acrílico. Muchos plásticos bloquean UVA; para un montaje exterior usa una ventana de cuarzo o PTFE delgado.
- Lecturas que saltan en interior: la luz de tubos y algunos LED parpadea a 100 Hz (red de 50 Hz en Chile). Usa integraciones de 10 ms o múltiplos para promediar ciclos completos.
Variantes y mejoras
- Índice UV aproximado con calibración casera: registra durante varios días a mediodía tus cuentas UVA y el índice UV que publica la Dirección Meteorológica de Chile para tu comuna. Una regresión lineal simple te da un factor de conversión válido para tu sensor, tu carcasa y tu ubicación. No es un instrumento certificado, pero sí una buena alarma de "hoy ponte bloqueador".
- Estación de exposición solar con ESP32: envía las lecturas cada minuto a una base de datos por WiFi y aprovecha el pin INT para despertar al ESP32 del deep sleep solo cuando hay una medición lista. Con una batería 18650 y un panel pequeño puede quedar semanas en el techo.
- Detector de lámparas para terrarios o curado de resina: las lámparas UVB/UVA de reptiles pierden potencia UV mucho antes de dejar de alumbrar. Guarda la lectura UVA de una lámpara nueva y avisa con un buzzer cuando caiga bajo el 60 %.
Personalización para Chile
El TSL2585 es un sensor muy nuevo y lo más probable es que tengas que importarlo; el resto del montaje es estándar y lo consigues en MechatronicStore:
- Placa de desarrollo: un Arduino UNO R3 compatible o un ESP32 DevKit sirven igual; si quieres conectividad WiFi para registrar datos, elige el ESP32.
- Protoboard y jumpers: una protoboard de 400 puntos y jumpers macho macho alcanzan para los cuatro cables I2C.
- Sensor de luz BH1750: para el experimento de comparación UVA contra lux.
- Cable STEMMA QT / Qwiic: si tu placa no tiene conector JST SH, un cable Qwiic a pines macho te ahorra soldar.
Revisa precios y stock actualizados buscando cada componente en el catálogo de MechatronicStore. Si en la guía original ves una Adafruit Metro o una Feather RP2040, un Arduino UNO compatible o un ESP32 DevKit cumplen la misma función para este proyecto.
Recursos
- Tutorial original (inglés): Adafruit TSL2585 Digital UVA and Ambient Light Sensor, de Liz Clark para Adafruit. Esta guía está basada en ella.
- Librería Arduino (documentación): Adafruit_TSL2585
- Librería CircuitPython (documentación): adafruit circuitpython tsl2585
- Guía en PDF: descarga de la guía original

Versión chilena con componentes en stock local en MechatronicStore.




