-
Notifications
You must be signed in to change notification settings - Fork 317
/
_P213_VEML6070
152 lines (130 loc) · 4.55 KB
/
_P213_VEML6070
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
145
146
147
148
149
150
151
152
//#######################################################################################################
//#################### Plugin 213 VEML6070 Ultraviolet Sensor #######################
//#################### based on Adafruit Library #######################
//#######################################################################################################
#define PLUGIN_213
#define PLUGIN_ID_213 213
#define PLUGIN_NAME_213 "UV - VEML6070"
#define PLUGIN_VALUENAME1_213 "UV"
// See also VEML6070 data sheet:http://www.vishay.com/docs/84277/veml6070.pdf
//
////////////////////////////
// VEML6070 Registers/addresses //
////////////////////////////
#define VEML6070_ADDR_ARA 0x19 >> 1 // shift by one to get correct register addresses
#define VEML6070_ADDR_CMD 0x70 >> 1
#define VEML6070_ADDR_DATA_LSB 0x71 >> 1
#define VEML6070_ADDR_DATA_MSB 0x73 >> 1
// really unusual way of getting data, your read from two different addrs!
#define VEML6070_ADDR_H 0x39
#define VEML6070_ADDR_L 0x38
// VEML6070 command register bits
#define VEML6070_CMD_DISABLE 0x01
#define VEML6070_CMD_WDM 0x02
// three different integration times
typedef enum veml6070_integrationtime {
VEML6070_HALF_T,
VEML6070_1_T,
VEML6070_2_T,
VEML6070_4_T,
} veml6070_integrationtime_t;
bool Plugin_213_begin(veml6070_integrationtime_t itime);
uint16_t Plugin_213_readUV();
uint16_t Plugin_213_convert_to_risk_level(uint16_t uvs_step);
boolean Plugin_213(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_213;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_213);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_213));
break;
}
case PLUGIN_READ:
{
if (!Plugin_213_begin(VEML6070_1_T)) {
String log = F("VEML6070: No available!");
addLog(LOG_LEVEL_INFO, log);
UserVar[event->BaseVarIndex] = NAN;
success = false;
} else {
String s = "";
uint16_t uv;
uv = Plugin_213_readUV();
if (isnan(uv) || uv == (-1) || uv == 65535) {
String log = F("VEML6070: no data read!");
addLog(LOG_LEVEL_INFO, log);
UserVar[event->BaseVarIndex] = NAN;
success = false;
} else {
UserVar[event->BaseVarIndex] = uv;
String log = F("VEML6070: UV: ");
log += UserVar[event->BaseVarIndex];
addLog(LOG_LEVEL_INFO, log);
success = true;
}
}
break;
}
}
return success;
}
//**************************************************************************/
// Check VEML6070 presence
//**************************************************************************/
bool Plugin_213_begin(veml6070_integrationtime_t itime) {
byte error;
Wire.begin();
Wire.beginTransmission(VEML6070_ADDR_L);
Wire.write((itime << 2) | VEML6070_CMD_WDM);
error = Wire.endTransmission();
delay(500);
return (error == 0);
}
/*
Die Sonnenleistung berechne ich mit einer Simplen Formel
WATT = ((uv.readUV() * 2.5) / 187) * 10;
Allerdings benutze ich einen VEML6070 UV Sensor via I2C.
Kann aber nicht bestätigen ob dieser Wert auch stimmt aber laut meinem Gefühl könnte es schon hinkommen.
*/
// UV = uv.readUV()/684.75;
//Â Â WATT = ((uv.readUV() * 2.5) / 187) * 10;
uint16_t Plugin_213_readUV() {
if (Wire.requestFrom(VEML6070_ADDR_H, 1) != 1) return -1;
uint16_t uvi = Wire.read();
uvi <<= 8;
if (Wire.requestFrom(VEML6070_ADDR_L, 1) != 1) return -1;
uvi |= Wire.read();
return uvi;
}
uint16_t Plugin_213_convert_to_risk_level(uint16_t uvs_step) {
uint16_t risk_level_mapping_table[4] = {2241, 4482, 5976, 8217};
uint16_t i;
for (i = 0; i < 4; i++) {
if (uvs_step <= risk_level_mapping_table[i]) {
break;
}
}
return i;
}