【搬运】M5Stick+TSL250R检查LED光源-Arduino中文社区 - Powered by Discuz! Archiver

vany5921 发表于 2020-4-3 12:01

【搬运】M5Stick+TSL250R检查LED光源

其基本思想是创建一个简单的设备,可以比较光源(如LED灯泡)的质量。
我使用了TSL250R集成电路,包括光电二极管和带有配置反馈回路的运算放大器。该集成电路是输出电压与光强成正比的光学传感器。我把这个传感器放在M5Stick开发板的外壳里,直接连接到ESP32模块。传感器的输出与35号GPIO相连。
输出数据由ESP32板的硬件定时器触发的ADC采样。采样后,计算出FFT和闪烁百分比值。基于FFT得到最大峰值的频率。此外,还显示一个带有输入数据的绘图。在此基础上,我们可以看到输入信号的形状和幅度。所有数据都显示在OLED显示屏上。
程序用C语言编写,使用了ArduinoFFT和U8g2库。
参考电路


测量传感器输出的峰值和平均值。应用一些平均值来降低噪声。

对于正弦波信号,闪烁百分比可通过以下公式计算:
% Flicker = (peak-peak value)/ (2*average value)
如果灯光闪烁波形不是正弦波形,则可根据以下公式计算闪烁百分比:
% Flicker = (max value - min value)/(max value + min value)
以下是一些LED的测试结果:


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

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif

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;
double vImag;

word adcData;
byte sampleCount;
bool adcDataReady;

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

void setup() {
u8g2.begin();
u8g2.setFont(u8g2_font_5x7_tr);
analogReadResolution(12);
getSample = false;
adcDataReady = false;
sampleCount = 0;
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &timerInterrupt, true);
timerAlarmWrite(timer, 1000000 / samplingFrequency, true);
timerAlarmEnable(timer);
}

void readData(void)
{
if (getSample && !adcDataReady) {
    adcData = analogRead(35);
    sampleCount++;
    if (sampleCount >= maxSamples) {
      adcDataReady = true;
      sampleCount = 0;
    } else {
      getSample = false;
    }
}
}

word getFrequency(void)
{
for (byte i = 0; i < maxSamples; i++) {
    vReal = double(adcData);
    vImag = 0;
}
FFT.Windowing(vReal, maxSamples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, maxSamples, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, maxSamples);
return FFT.MajorPeak(vReal, maxSamples, samplingFrequency);
}

word getFlicker(void)
{
word flicker = 0;
word minVal = 65535, maxVal = 0;
for (byte i = 0; i < maxSamples; i++)
{
    if (minVal > adcData) {
      minVal = adcData;
    }
    if (maxVal < adcData) {
      maxVal = adcData;
    }
}
if ((minVal + maxVal) != 0) {
    flicker = ((maxVal - minVal) / (maxVal + minVal)) * 100;
}
return flicker;
}

void drawPlot(void)
{
word r = 1 << 12;
r = r / 54;
for (byte i = 0; i < maxSamples; i++) {
    u8g2.drawPixel(i, 54 - (adcData / r));
}
}

void loop() {
readData();
Frequency:
if (adcDataReady) {
    char displayText;
    word frequency = getFrequency();
    word flicker = getFlicker();
    u8g2.clearBuffer();
    snprintf (displayText, 19, "F:%dHz", frequency);
    u8g2.drawStr(10, 8, displayText);
    snprintf (displayText, 19, "Flicker:%d%%", flicker);
    u8g2.drawStr(60, 8, displayText);
    u8g2.drawLine(0, 10, 163, 10);
    drawPlot();
    u8g2.sendBuffer();
    adcDataReady = false;
    getSample = false;
    delay(100);
}
}


页: [1]
查看完整版本: 【搬运】M5Stick+TSL250R检查LED光源