Enter Your Electronics & Design Project for a chance to win an $200 Shopping cart of product!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll



The basic idea was to create a simple device which allow to compare the quality of light sources e.g. LED bulbs. I have used TSL250R IC containing photodiode and operational amplifier with configured feedback loop. This IC is optical sensor which output voltage is proportional to light intensitivity. I have put this sensor inside to M5Stick case and connected directly to ESP32 module. Output from sensor is connected to GPIO with number 35. Below there are images with mounted sensor:



Output data is sampled by ADC which is triggered by hardware timer of ESP32 board.

After sampling there is calculated FFT. After that there is obtained frequency for maximum peak.

Additionally there is displayed a plot with input data, so we could see amplitude of input signal.

All data are presented on OLED display.

Below there is diagram with flow:



Program was written in C with usage of ArduinoFFT and U8g2 libraries. Below there is source:

#include <Arduino.h>
#include <U8g2lib.h>
#include <arduinoFFT.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>

U8G2_SH1107_64X128_F_4W_HW_SPI u8g2(U8G2_R1, /* cs=*/ 14, /* dc=*/ 27, /* reset=*/ 33);

arduinoFFT FFT = arduinoFFT();
hw_timer_t *timer = NULL;
bool getSample;
const byte maxSamples = 128;
const word samplingFrequency = 2000;
double vReal[maxSamples];
double vImag[maxSamples];

void timerInterrupt() {
  if (!getSample) {
    getSample = true;

void setup() {
  getSample = false;
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &timerInterrupt, true);
  timerAlarmWrite(timer, 1000000/samplingFrequency, true);

void loop() {
  word adcData[maxSamples];
  byte sampleCount = 0;
  bool adcDataReady = false;
  do {
    if (getSample && !adcDataReady) {
      adcData[sampleCount] = analogRead(35);
      if (sampleCount >= maxSamples) {
        adcDataReady = true;
        sampleCount = 0;
      } else {
        getSample = false;

    if (adcDataReady) {
      char displayText[16];
      for (byte i = 0; i < maxSamples; i++) {
        vReal[i] = double(adcData[i]);
        vImag[i] = 0;
      FFT.Windowing(vReal, maxSamples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
      FFT.Compute(vReal, vImag, maxSamples, FFT_FORWARD);
      FFT.ComplexToMagnitude(vReal, vImag, maxSamples);
      word peak = FFT.MajorPeak(vReal, maxSamples, samplingFrequency);
      adcDataReady = false;
      getSample = false;
      snprintf (displayText, 8, "%dHz", peak);
      u8g2.drawStr(65, 10, displayText);
      word r = 1 << 12;
      r = r / 54;
      for (byte i = 0; i < maxSamples; i++) {
        u8g2.drawPixel(i, 54-(adcData[i] / r));
  } while (true);


Below there is short video presentation. We could see here a two different LED light sources with different flicker (high and low).

More details about light flicker in LED lamps you could find in this document:

LED flicker


The interesting improvement could be added measurement of light spectrum with additional sensor.