Драйвер для датчика ультрафиолетового излучения VEML6075 (UVA/UVB) на платформе MicroPython. Полная поддержка протокола I2C, однократных и непрерывных измерений, аппаратной компенсации видимого/ИК-шума и расчёта индекса ультрафиолетового излучения (UV Index) по официальным формулам Vishay.
- Поддержка I2C: Standard Mode (100 кГц) / Fast Mode (400 кГц)
- Режимы работы:
Continuous(автоматический) иSingle-shot(по запросу) - Чтение всех каналов:
UVA,UVB,UVCOMP1(видимый свет),UVCOMP2(ИК) - Компенсация шума по формулам Vishay Application Note 84339
- Расчёт
UVIдля конфигурацииopen air(IT=100 мс, без диффузора) - Совместимость: Raspberry Pi Pico, ESP32, ESP8266, STM32 и другие платы с MicroPython
- Типизация, подробные docstring, кэширование конфигурации
| Компонент | Описание |
|---|---|
VEML6075 модуль |
Датчик UVA/UVB с интерфейсом I2C |
| Микроконтроллер | Raspberry Pi Pico, ESP32, ESP8266 и т.д. |
| Pull-up резисторы | 3.7 кОм на линиях SDA и SCL (к VDD) |
| Конденсатор | 100 нФ максимально близко к пину VDD датчика |
| Питание | 3.3 В ... 3.6 В (не подключать к 5 В напрямую!) |
Важно: Отсутствие pull-up резисторов или фильтрующего конденсатора является основной причиной "нулей", сбоев I2C и нестабильных показаний.
VEML6075 MicroController
VDD (4) ----------> 3.3V
GND (1) ----------> GND
SDA (2) --[3.7k]--> SDA (напр. GPIO 6 на Pico)
SCL (3) --[3.7k]--> SCL (напр. GPIO 7 на Pico)
- Адрес устройства:
0x10(7-bit) - Рекомендуемая частота I2C:
100_000или400_000Гц
your_project/
├── sensor_pack_2/ # Ваш фреймворк (I2cAdapter, DeviceEx, BitFields, etc.)
├── veml6075mod.py # Драйвер датчика
├── main.py # Тестовый скрипт и примеры использования
└── README.md # Документация
- Подключите датчик согласно схеме выше.
- Скопируйте
veml6075mod.pyиmain.pyв вашу папку проекта. - Отредактируйте пины I2C в
main.pyпод вашу плату:i2c = I2C(id=1, scl=Pin(7), sda=Pin(6), freq=400_000) # Raspberry Pi Pico
- Загрузите файлы на микроконтроллер и запустите main.py.
from machine import I2C, Pin
from sensor_pack_2.bus_service import I2cAdapter
import veml6075mod
import time
# 1. Инициализация шины и адаптера
i2c = I2C(id=1, scl=Pin(7), sda=Pin(6), freq=400_000)
adapter = I2cAdapter(i2c)
# 2. Создание экземпляра датчика
sensor = veml6075mod.VEML6075(adapter=adapter, address=0x10)
# 3. Проверка ID устройства
print(f"Device ID: 0x{sensor.get_id():x}") # Ожидается: 0x26
# 4. Запуск непрерывного режима (IT=100ms)
sensor.start_measurement(single_meas_mode=False, it_index=1, high_dynamic=False)
wt = sensor.get_conversion_cycle_time()
# 5. Цикл чтения
while True:
time.sleep_ms(wt)
# Читаем основные и компенсационные каналы
uva, uvb = sensor.get_measurement_value(value_index=0)
comp1, comp2 = sensor.get_measurement_value(value_index=1)
# Расчёт UV Index
uvi = veml6075mod.calc_uvi_simple(uva, uvb, comp1, comp2)
print(f"UVA:{uva:5d} UVB:{uvb:5d} | UVI:{uvi:.2f}")
| Метод/Атрибут | Параметры | Возвращает | Описание |
|---|---|---|---|
__init__ |
adapter: I2cAdapter, address: int = 0x10 |
- | Инициализация соединения с датчиком, чтение начальных настроек |
get_id |
- | int |
Возвращает Device ID датчика (должен быть 0x0026) |
start_measurement |
single_meas_mode: bool, it_index: int = 1, high_dynamic: bool = False |
- | Настройка параметров и запуск процесса измерений. it_index: 0=50ms, 1=100ms, 2=200ms, 3=400ms, 4=800ms |
get_measurement_value |
value_index: int | None |
tuple | None |
Возвращает измеренные значения. 0 → (UVA, UVB), 1 → (COMP1, COMP2), None → None |
get_uv |
uvx_data: bool = True |
tuple[int, int] |
Низкоуровневое чтение каналов. True → UVA/UVB, False → компенсационные каналы |
shutdown |
value: bool | None |
bool |
Управление питанием. None → вернуть статус, True → выключить, False → включить |
get_conversion_cycle_time |
- | int |
Возвращает время интеграции в миллисекундах для текущих настроек |
is_continuously_mode |
- | bool |
Возвращает True, если датчик в режиме непрерывных измерений |
is_single_shot_mode |
- | bool |
Возвращает True, если датчик в режиме однократных измерений |
get_data_status |
raw: bool = True |
bool |
Возвращает статус готовности данных |
read_settings |
from_sensor: bool = True |
None |
Обновляет внутренние поля класса в соответствии с настройками датчика |
| Функция | Параметры | Возвращает | Описание |
|---|---|---|---|
calc_uvi_simple |
uva: int, uvb: int, comp1: int, comp2: int |
float |
Рассчитывает UV Index по формулам Vishay App Note 84339 (для open air, IT=100ms) |
_it_index_to_ms |
raw_it: int |
int |
Преобразует индекс времени интеграции в миллисекунды (0→50, 1→100, 2→200, 3→400, 4→800) |
_check_it_index |
raw_it: int |
- | Проверяет корректность индекса времени интеграции (должен быть 0..4) |
| Константа | Значение | Описание |
|---|---|---|
ADDR_CONFIG_REG |
0x00 |
Адрес регистра конфигурации |
ADDR_ID_REG |
0x0C |
Адрес регистра Device ID |
ADDR_UVA_DATA_REG |
0x07 |
Адрес регистра данных UVA |
ADDR_UVB_DATA_REG |
0x09 |
Адрес регистра данных UVB |
ADDR_UV_COMP1_DATA_REG |
0x0A |
Адрес регистра компенсации видимого света |
ADDR_UV_COMP2_DATA_REG |
0x0B |
Адрес регистра компенсации ИК-излучения |
FMT_UINT16_LE |
"H" |
Формат упаковки 16-битных данных (little-endian) |
| Поле | Биты | Описание |
|---|---|---|
BF_NAME_UV_IT |
6:4 | Время интеграции (5 значений: 50-800 мс) |
BF_NAME_HD |
3 | High Dynamic mode (0=normal, 1=high) |
BF_NAME_UV_TRIG |
2 | Триггер однократного измерения |
BF_NAME_UV_AF |
1 | Active Force mode (0=continuous, 1=single-shot) |
BF_NAME_SD |
0 | Shutdown (0=power on, 1=shut down) |
Функция calc_uvi_simple() реализует упрощённый алгоритм расчёта индекса ультрафиолетового излучения (UV Index, UVI) на основе Vishay Application Note 84339 (стр. 6-7, формулы 1, 2, 5).
Кремниевые фотодиоды датчика VEML6075 чувствительны не только к УФ-излучению, но и к видимому свету (400-750 нм) и инфракрасному излучению (750-1000 нм). Для компенсации этого паразитного шума в датчик встроены два дополнительных канала:
| Канал | Обозначение | Диапазон | Назначение |
|---|---|---|---|
| UVA | 0x07 | 320-400 нм | Основной канал измерения UVA |
| UVB | 0x09 | 280-320 нм | Основной канал измерения UVB |
| UVCOMP1 | 0x0A | 400-750 нм | Компенсация видимого шума |
| UVCOMP2 | 0x0B | 750-1000 нм | Компенсация ИК-шума |
Перед расчётом UVI необходимо очистить сигналы UVA и UVB от влияния видимого и ИК-излучения:
UVA_clean = max(0, UVA - a * COMP1 - b * COMP2)
UVB_clean = max(0, UVB - c * COMP1 - d * COMP2)
Где коэффициенты компенсации зависят от конфигурации системы:
| Конфигурация | a (UVA VIS) | b (UVA IR) | c (UVB VIS) | d (UVB IR) | UVA_resp | UVB_resp |
|---|---|---|---|---|---|---|
| Open air (без диффузора) | 2.22 | 1.33 | 2.95 | 1.74 | 0.001461 | 0.002591 |
| 0.1 мм тефлон, окно 4.5 мм | 2.22 | 1.33 | 2.95 | 1.74 | 0.002303 | 0.004686 |
| 0.1 мм тефлон, окно 5.5 мм | 2.22 | 1.33 | 2.95 | 1.74 | 0.002216 | 0.005188 |
| 0.1 мм тефлон, окно 10 мм | 2.22 | 1.33 | 2.95 | 1.74 | 0.002681 | 0.004875 |
| 0.25 мм тефлон, окно 10 мм | 2.22 | 1.33 | 2.95 | 1.74 | 0.002919 | 0.009389 |
| 0.4 мм тефлон, окно 10 мм | 2.22 | 1.17 | 2.95 | 1.58 | 0.004770 | 0.006135 |
| 0.7 мм тефлон, окно 10 мм | 2.22 | 1.17 | 2.95 | 1.58 | 0.007923 | 0.008334 |
После компенсации шума индекс УФ-излучения рассчитывается как среднее взвешенное значение каналов UVA и UVB:
UVI = (UVA_clean * UVA_resp + UVB_clean * UVB_resp) / 2
Где:
UVA_resp,UVB_resp— коэффициенты чувствительности из таблицы выше- Результат округляется до сотых для удобства отображения
| Значение UVI | Уровень риска | Рекомендации |
|---|---|---|
| 0.0 - 2.9 | Низкий | Защита не требуется |
| 3.0 - 5.9 | Умеренный | Использовать солнцезащитный крем |
| 6.0 - 7.9 | Высокий | Избегать пребывания на солнце в полдень |
| 8.0 - 10.9 | Очень высокий | Максимальная защита, ограничить пребывание на улице |
| 11.0+ | Экстремальный | Избегать пребывания на открытом воздухе |
Важно: Шкала UVI (0-11+) откалибрована исключительно для солнечного спектра (AM1.5G). При измерении искусственных УФ-источников (например, светодиодов 365/395 нм) значения могут превышать 11 и не соответствуют биологическому воздействию на кожу.
-
Время интеграции: Коэффициенты
UVA_respиUVB_respвалидны строго дляIT = 100 мс. При использовании других значений времени интеграции чувствительность меняется линейно (умножение на 2 при удвоении IT). -
Конфигурация оптики: Коэффициенты компенсации (a, b, c, d) и чувствительности (resp) приведены для конкретных конфигураций (толщина тефлонового диффузора, размер окна). При изменении механической конструкции требуется повторная калибровка.
-
Калибровка устройства: Формула использует типовые коэффициенты Vishay. Для метрологической точности требуется индивидуальная калибровка (параметры alpha, beta, gamma, delta) по эталонному солярному симулятору (AM1.5G) или референсному датчику (например, Davis Weather Station).
-
Угловая характеристика: Без использования тефлонового диффузора датчик имеет узконаправленную чувствительность. Для корректного измерения рассеянного солнечного излучения рекомендуется использовать диффузор толщиной 0.4 мм для обеспечения косинусной угловой характеристики.
# Чтение сырых данных со всех каналов
uva_raw, uvb_raw = sensor.get_measurement_value(value_index=0)
comp1_raw, comp2_raw = sensor.get_measurement_value(value_index=1)
# Расчёт UV Index (по умолчанию: open air, IT=100ms)
uvi = calc_uvi_simple(uva_raw, uvb_raw, comp1_raw, comp2_raw)
print(f"UV Index: {uvi:.2f}")
Данный проект распространяется на условиях лицензии MIT License.
Copyright (c) 2026 Роман Шевчик kolbasilyvasily@yandex.ru
Код распространяется "как есть", без каких либо гарантий!
This project documentation is provided in Russian only.
Due to limited positive feedback from users cloning my repositories, I have decided not to maintain English documentation or translations.
If you need assistance:
- Use automated translation tools (Google Translate, DeepL, etc.) — the code comments and docstrings are structured for easy machine translation.
- Check the referenced Vishay documents (Datasheet 84304, Application Note 84339) — they are available in English and contain all technical details.
- Open an Issue in English — I will do my best to respond, though response time may vary.
Thank you for understanding.