From 98766aaabcb1fa74123247a52e72a453b6da59f8 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Sat, 22 Nov 2025 20:44:51 +0800
Subject: [PATCH] Update TSL2561 to sample for 5 times
---
project/lightd/hal/tsl2561.c | 128 +++++++++++++++++++++++++++++++++---------
1 files changed, 100 insertions(+), 28 deletions(-)
diff --git a/project/lightd/hal/tsl2561.c b/project/lightd/hal/tsl2561.c
index b912433..96a166a 100644
--- a/project/lightd/hal/tsl2561.c
+++ b/project/lightd/hal/tsl2561.c
@@ -37,8 +37,8 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include "util_proc.h"
#include "logger.h"
+#include "utils.h"
#include "tsl2561.h"
@@ -142,16 +142,16 @@
return 0;
}
-int tsl2561_get_lux(float *lux)
+int tsl2561_sample_lux(float *lux)
{
int i, fd;
int rv = 0;
char *dev = TSL2561_I2CDEV;
- float div = 0.0;
unsigned char reg_data[REG_COUNT];
- int chn0_data = 0;
- int chn1_data = 0;
+ int ch0_data = 0;
+ int ch1_data = 0;
+ float ratio = 0.0;
if( !lux )
{
@@ -174,39 +174,111 @@
{
rv = tsl2561_readreg(fd, regs_addr[i], ®_data[i]);
if( rv < 0)
- goto failed;
+ {
+ log_error("TSL2561 read register failed\n");
+ goto cleanup;
+ }
}
- chn0_data = reg_data[1]*256 + reg_data[0]; /* Channel0 = DATA0HIGH<<8 + DATA0LOW */
- chn1_data = reg_data[3]*256 + reg_data[2]; /* channel1 = DATA1HIGH<<8 + DATA1LOW */
+ rv = 0;
+ ch0_data = (reg_data[1]<<8) + reg_data[0]; /* 通道0:可见光+红外 */
+ ch1_data = (reg_data[3]<<8) + reg_data[2]; /* 通道1:仅红外 */
- if( chn0_data<=0 || chn1_data<0 )
- {
- rv = -2;
+
+ /* 根据datasheet,饱和时光照强度很大 */
+ if (ch0_data == 0xFFFF || ch1_data == 0xFFFF) {
+ *lux = 50000.0;
goto cleanup;
}
- div = (float)chn1_data / (float)chn0_data;
-
- if( div>0 && div<=0.5 )
- *lux = 0.304*chn0_data-0.062*chn0_data*pow(div,1.4);
-
- else if( div>0.5 && div<=0.61 )
- *lux = 0.0224*chn0_data-0.031*chn1_data;
-
- else if( div>0.61 && div<=0.8 )
- *lux = 0.0128*chn0_data-0.0153*chn1_data;
-
- else if( div>0.8 && div<=1.3 )
- *lux = 0.00146*chn0_data-0.00112*chn1_data;
-
- else if( div>1.3 )
+ if (ch0_data == 0) { /* 无光照 */
*lux = 0.0;
+ goto cleanup;
+ }
+
+ ratio = (float)ch1_data / (float)ch0_data;
+
+ if (ratio >= 0 && ratio <= 0.50) {
+ *lux = 0.0304f * ch0_data - 0.062f * ch0_data * powf(ratio, 1.4f);
+ }
+ else if (ratio <= 0.61) {
+ *lux = 0.0224f * ch0_data - 0.031f * ch1_data;
+ }
+ else if (ratio <= 0.80) {
+ *lux = 0.0128f * ch0_data - 0.0153f * ch1_data;
+ }
+ else if (ratio <= 1.30) {
+ *lux = 0.00146f * ch0_data - 0.00112f * ch1_data;
+ }
+ else { /* 超出有效范围 */
+ *lux = 0.0;
+ }
+
+ if (*lux < 0) { /* 确保结果非负 */
+ *lux = 0.0;
+ }
cleanup:
tsl2561_power(fd, OFF);
-
-failed:
close(fd);
return rv;
}
+
+/**
+ * @brief 采样TSL2561光照强度数据
+ * @param lux 输出参数,存储计算后的光照强度值
+ * @return int 0成功,-1失败
+ */
+#define SAMPLE_COUNT 5
+int tsl2561_get_lux(float *lux)
+{
+ float samples[SAMPLE_COUNT];
+ float current_lux, temp;
+ int valid_samples = 0;
+ int i,j;
+
+ if (!lux) {
+ log_error("Invalid input argument\n");
+ return -1;
+ }
+
+ /* 采样N次数据 */
+ for (i=0; i<SAMPLE_COUNT; i++)
+ {
+ if (tsl2561_sample_lux(¤t_lux) == 0) {
+ samples[valid_samples++] = current_lux;
+ }
+
+ if (i < SAMPLE_COUNT-1) {
+ msleep(100);
+ }
+ }
+
+ if (valid_samples == 0)
+ {
+ log_error("All TSL2561 samples failed\n");
+ return -2;
+ }
+
+ /* 只有一个有效采样,直接使用 */
+ if (valid_samples == 1)
+ {
+ *lux = samples[0];
+ return 0;
+ }
+
+ /* 对采样值进行排序 */
+ for (i=0; i<valid_samples-1; i++) {
+ for (j = i + 1; j < valid_samples; j++) {
+ if (samples[i] > samples[j]) {
+ temp = samples[i];
+ samples[i] = samples[j];
+ samples[j] = temp;
+ }
+ }
+ }
+
+ /* 取中位数 */
+ *lux = samples[valid_samples / 2];
+ return 0;
+}
--
Gitblit v1.9.1