Почалось з того, що я помітив боковим зором легеньку дриганість однієї LED лампи. Лампи розжарення доволі інертні і за 10мс не встигають втратити яскравість, тому мерехтіння не помітне. А от світлодіод (LED) швидко реагує на подачу струму, тому потребує хорошого драйвера, який триматиме струм постійним. Якщо виробник економить на драйвері - лампа може світити лише 40% часу і мерехтіння буде додатково напрягати очі.

Коли світить лише 1 лампа, перевірити стабільність світла можна швидко провівши рукою вліво-вправо: якщо слід суцільний (continuous), то лампа нормальна, а якщо переривчастий - значить мигає.

Вирішив зробити прилад, щоб точно тестувати лампи на недоліки не розбираючи їх.

Отже, апаратна частина:

  • фототранзистор 3DU5C
  • резистор 1kΩ
  • Arduino Nano
  • OLED дисплей на SSD1306.

Програмна частина:

детектор спереду детектор збоку

Отриманий графік цієї лампи (Maxus R50 5W 4100K):

графік для Maxus R50 5W 4100K

З таким графіком її можна ставити лише в тимчасових кімнатах: коридор, ванна, під’їзд. Max і min (2 і 3 рядки) різняться в 27 раз, частота 100±3Hz - близька до межі сприйняття, та все ж помітна оку.

Далі 2 рядки: percent_flicker = 93% та flicker_index = 0.3117. Це величини, що використовуються для чисельного представлення миготіння (PDF на цю тему):

  • percent_flicker = ((max-min)/(max+min)) * 100%
  • flicker_index = area_above_mean / total_area, де mean - середня освітленість, а *_area мають розмірність Lumen*millisecond.

приклад аналізу

На рисунку білі полоси визначають один період, зелена область - приблизна area_above_mean. Лінія середнього значення проведена не точно, але для ілюстрації принципу згодиться.

Щоб визначити допустимі значення, заміряю лампу розжарення Electrum 60W:

графік для лампи розжерення 60W

Приблизно як синусоїда. Отже, щоб LED лампа була не гірша за лампу розжарення, значення мають бути: percent_flicker < 8%, flicker_index < 0.02. Також в кількох джерелах вказується, що миготіння не відчутне при частоті >3kHz.

Компактні люмінесцентні лампи (у всіх однакова форма хвилі, 4-6% 0.01..0.017)

  • SLS 11W 2700K
  • Electrum FC-111 18W 4000K

графік для люмінесцентної

LED лампа з хорошим драйвером Videx:

графік для хорошої LED лампи

Ще тестив цікаву 8W лампу з COB стержнями з aliexpress (Lediary). Графік виглядає як суперпозиція різних хвиль. Чотири графіки показують форму хвилі з різним масштабом (змінюється останній рядок - ширина екрану в мілісекундах і середній рядок 12sp - кількість вимірювань, що усереднюються для отримання 1 точки)

графік для хорошої LED лампи

Схоже, тут висока частота (декілька kHz) і кожен стержень працює зі своєю частотою: зі збільшенням масштабу індекс та відсоток миготіння збільшуються і стає видно, що різкі переходи просто згладжувались при іншому масштабі. В реалі маємо значення близько (26%, 0.07) при частотах 1-6kHz. Це наче допустимо (бо частота велика), але драйвер тихенько пищить, тому теж відправляється в чорний список.

Цікаво, що 4W версія цієї ж лампи поводить себе чудово.

Білий список

  • GlobalLED 10W 850Lm (наче суб-бренд Maxus, а лампи кращі)
  • Videx 9W 800Lm, 7W, 5W 460Lm (упаковка не має українського тексту, хоча фірма-пакувальник українська, роблять в Китаї)
  • Svitloton LED 7W 4200K
  • Lediary? 4W COB Warm White Frosted Candle

хороші лампи

Чорний список

  • Maxus R50 5W 4100K (1-LED-362 15.07.2013)
  • Lumen LED A60 7W
  • Lediary? 8W COB Warm White Frosted Bubble Ball (пищить)

Приклад розрахунку percent_flicker та flicker_index

Припустимо, що лампа протягом 1ms світить на 90 люмен, наступну 1ms світить на 8 люмен, тухне на 8мс, і знову повторює, тоді:

  • percent_flicker = ((90Lm-0Lm)/(90Lm+0Lm)) * 100% = 100%
  • сумарна освітленість за період total_area = 90Lm*1ms + 8Lm*1ms + 0Lm*8ms = 98Lm*ms
  • середня освітленість mean = total_area/period = 98Lm*ms/10ms = 9.8Lm
  • flicker_index = area_above_9.8Lm/total_area = 90Lm*ms / 98Lm*ms ≈ 0.918

Обмеження

  • Максимальна частота вимірювання ≈38.7 ksamples/second => максимально детектована частота 19kHz
  • Точність одиничного вимірювання ±0.5%
  • Точність визначення періоду ±1px ≈ samples / 38kHz, де samples - масштаб, значення 4го рядка
  • Точність визначення частоти ± (freq_calculated * samples / 38kHz) * 100%
  • Якщо максимально виміряне значення < 5% (слабке освітлення) - виводиться ERROR: LOW
  • Якщо максимально виміряне значення > 75% (сенсор надто близько до лампи) - виводиться ERROR: HIGH, бо в такому разі можливе обрізання корисних даних
  • Якщо графік прямий або настільки заплутаний, що неможливо визначити частоту - виводиться ERROR: FREQ

Алгоритм

  1. За одну ітерацію відбувається 256 * samples вимірювань, де samples - масштаб. Кожні samples вимірювань усереднюються і заносяться до масиву розміру 256.
  2. Екран має розмір 128*64px. Справа 30px зайняті колонкою показників, тому графіку лишається 98*64.
  3. Якщо графік так і вивести - від буде “ходити” вліво-вправо, бо кожна ітерація вимірювання може проводитись зі своїм зсувом фази. Щоб стабілізувати, рахується кореляція виміряного масиву з початковим в кожній точці. Запас для зсуву 256-98 = 158 елементів. Таким чином, на екран виведеться та частина графіку, що максимально схожа на 98 елементів початкового вимірювання.
  4. За допомогою автокореляції рахується період хвилі T, з нього рахується частота.
  5. За наведеними вище формулами рахуються percent_flicker та flicker_index на діапазоні [0..T-1] виміряного масиву.