guowenxue
2019-08-03 e6e79ca02d323e9a10f115ade7ba6ac9c0d7a3f0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*********************************************************************************
 *      Copyright:  (C) 2019 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  tsl2561.c
 *    Description:  This file is the Lux sensor TSL2561 API functions on RaspberryPi,
 *                  which connected to I2C-1
 *
 *        Version:  1.0.0(04/07/19)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "04/07/19 17:39:38"
 *                 
 ********************************************************************************/
 
#include <wiringPi.h>
#include <wiringPiI2C.h> 
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
#include <time.h>
 
#include "tsl2561.h"
 
 
int tsl_fd = -1;
 
static const int  regs_addr[REG_COUNT]={DATA0LOW, DATA0HIGH, DATA1LOW, DATA1HIGH};
 
int tsl2561_init(void)
{
    if(tsl_fd > 0)
        return 0;
 
    tsl_fd = wiringPiI2CSetup(TSL2561_I2C_ADDR);
    if(tsl_fd < 0)
    {
        printf("TSL2561 I2C setup failure: %s\n", strerror(errno));
    }
    else
    {
        printf("TSL2561 initialise ok, tsl_fd=%d\n", tsl_fd);
    }
 
 
    return tsl_fd;
}
 
 
int tsl2561_get_lux(void)
{
    int                 i;
    int                 reg_data[REG_COUNT];
 
    int                 chn0_data = 0;
    int                 chn1_data = 0;
 
    double              div = 0.0;
    double              lux = 0.0;
 
    /* Power up TSL2561 */
    wiringPiI2CWrite(tsl_fd, CONTROL_REG);
    wiringPiI2CWrite(tsl_fd, POWER_UP);
 
    delay(410);  /* t(CONV) MAX 400ms */
 
    /* Read register Channel0 and channel1 data from register */
    for(i=0; i<REG_COUNT; i++)
    {
        wiringPiI2CWrite(tsl_fd, regs_addr[i]);
        reg_data[i] = wiringPiI2CRead(tsl_fd);
        //printf("write and read register: 0x%0x->%d\n", regs_addr[i], reg_data[i]);
    }
 
    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 */
 
    if( chn0_data<=0 || chn1_data<0 )
    {
        //printf("TSL2561 get date chn0_data[%d] chn1_data[%d]\n", chn0_data, chn1_data);
        lux = 0.0;
        goto OUT;
    }
 
    div = (double)chn1_data / (double)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 )
        lux = 0.0;
 
OUT:
    printf("TSLl2561 get lux: %.3f\n", lux);
 
    wiringPiI2CWrite(tsl_fd, CONTROL_REG);
    wiringPiI2CWrite(tsl_fd, POWER_DOWN);
}
 
void print_datime(void)
{
    time_t         tmp;
    struct tm     *p;
 
    time(&tmp);
 
    p=localtime(&tmp);
 
 
    printf("%d-%02d-%02d %02d:%02d:%02d\t", (p->tm_year+1900),(p->tm_mon+1), 
            p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
 
}
 
int main(int argc, char **argv)
{
    int            interval = 1;
 
    if( argc >= 2 )
    {
        interval = atoi(argv[1]);
    }
 
    tsl2561_init();
 
    while(1)
    {
        print_datime();
        tsl2561_get_lux();
        sleep(interval);
    }
 
}