Merge pull request #3603 from tonhuisman/feature/p114-move-p130-veml6075-from-pluginplayground

[P114] Move VEML6075 (P130) from PluginPlayground
This commit is contained in:
TD-er
2021-05-14 15:39:37 +02:00
committed by GitHub
11 changed files with 454 additions and 2 deletions
+99
View File
@@ -0,0 +1,99 @@
.. include:: ../Plugin/_plugin_substitutions_p11x.repl
.. _P114_page:
|P114_typename|
==================================================
|P114_shortinfo|
Plugin details
--------------
Type: |P114_type|
Name: |P114_name|
Status: |P114_status|
GitHub: |P114_github|_
Maintainer: |P114_maintainer|
Used libraries: |P114_usedlibraries|
Description
-----------
This I2C sensor with 2 resolutions (normal/high dynamic) offers UVA (365 +/-10 nm) and UVB (330 +/-10 nm) measurement and a calculated UVIndex value. Output result for UV is in irradiance, watt per square metre. The maximum value that can me measured is 65535, as the chip provides 16 bit values.
NB: If the unit is over-exposed, possibly the measurement could exceed the maximum returned value of 65535, and the calculated UVIndex value will *not* be correct.
NB2: When measuring outside UV exposure, the sensor should also be outside, as f.e. window glass filters out most UV radiance, and measurements will be (very) inaccurate.
Configuration
--------------
.. image:: P114_DeviceConfiguration.png
**Name** A unique name should be entered here.
**Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources.
I2C Options
^^^^^^^^^^^^
The available settings here depend on the build used. At least the **Force Slow I2C speed** option is available, but selections for the I2C Multiplexer can also be shown. For details see the :ref:`Hardware_page`
**I2C Address**: The address the device is using. Depending on the board used, when available a SDO pin, or soldering a 0 ohm resistor on a different location, can be used to select the used address. If that address selection is not available, then an I2C multiplexer (in a matching ESPEasy build) can be used to use multiple sensors on a single ESPEasy unit.
Device Settings
^^^^^^^^^^^^^^^^
**Integration Time**: The integration time setting of the sensor determines the accuracy of the measurement. There are 5 options available:
.. image:: P114_IntegrationTime.png
*50 ms* The default value, using an integration time of 50 msec.
*100ms*
*200ms*
*400ms*
*800ms*
Usually a higher integration time results in a more accurate measurement.
**Dynamic Setting**: This determines the dynamic setting:
.. image:: P114_DynamicSetting.png
*Normal Dynamic*
*High Dynamic* For better response to changing conditions during measurement.
The Data Acquisition, Send to Controller and Interval settings are standard available configuration items. Send to Controller only when one or more Controllers are configured.
**Interval** By default, Interval will be set to 60 sec. The minimum value allowed is 1 sec. but for measuring UV values, that don't change very quickly, reasonable values should be between 10 and 300 sec.
Values
^^^^^^
The measured values are available in ``UVA``, ``UVB`` and ``UCIndex``. A formula can be set to recalculate. The number of decimals is by default set to 2, and can be set to 0 for ``UVA`` and ``UVB``, as no decimals are provided from the measurement. ``UVIndex`` value is often used without decimals, but can be set as desired.
.. Events
.. ~~~~~~
.. .. include:: P114_events.repl
Change log
----------
.. versionchanged:: 2.0
|added| 2021-04-24 Moved to main repository as Plugin 114 UV - VEML6075 UVA/UVB Sensor from the ESPEasyPluginPlayground (P130).
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

+1
View File
@@ -137,6 +137,7 @@ There are different released versions of ESP Easy:
":ref:`P110_page`","|P110_status|","P110"
":ref:`P111_page`","|P111_status|","P111"
":ref:`P113_page`","|P113_status|","P113"
":ref:`P114_page`","|P114_status|","P114"
":ref:`P115_page`","|P115_status|","P115"
+1 -1
View File
@@ -15,7 +15,7 @@
.. |Plugin_Hardware| replace:: :ref:`P046_page`
.. |Plugin_Keypad| replace:: :ref:`P058_page`, :ref:`P061_page`, :ref:`P062_page`, :ref:`P063_page`
.. |Plugin_Light_Color| replace:: :ref:`P050_page`, :ref:`P066_page`
.. |Plugin_Light_UV| replace:: :ref:`P084_page`, :ref:`P107_page`
.. |Plugin_Light_UV| replace:: :ref:`P084_page`, :ref:`P107_page`, :ref:`P114_page`
.. |Plugin_Light_Lux| replace:: :ref:`P010_page`, :ref:`P015_page`, :ref:`P074_page`
.. |Plugin_Motor| replace:: :ref:`P048_page`, :ref:`P079_page`
.. |Plugin_Notify| replace:: :ref:`P055_page`, :ref:`P065_page`
@@ -37,6 +37,19 @@
.. |P113_compileinfo| replace:: `.`
.. |P113_usedlibraries| replace:: `https://github.com/sparkfun/SparkFun_VL53L1X_Arduino_Library (local copy)`
.. |P114_name| replace:: :cyan:`VEML6075`
.. |P114_type| replace:: :cyan:`UV`
.. |P114_typename| replace:: :cyan:`UV - VEML6075`
.. |P114_porttype| replace:: `.`
.. |P114_status| replace:: :yellow:`TESTING D`
.. |P114_github| replace:: P114_VEML6075.ino
.. _P114_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P114_VEML6075.ino
.. |P114_usedby| replace:: `.`
.. |P114_shortinfo| replace:: `UVA/UVB Sensor`
.. |P114_maintainer| replace:: `TD-er, clumsy-stefan, tonhuisman`
.. |P114_compileinfo| replace:: `.`
.. |P114_usedlibraries| replace:: `.`
.. |P115_name| replace:: :cyan:`MAX1704x`
.. |P115_type| replace:: :cyan:`Energy`
.. |P115_typename| replace:: :cyan:`Energy - MAX1704x`
+170
View File
@@ -0,0 +1,170 @@
#include "_Plugin_Helper.h"
#ifdef USES_P114
// #######################################################################################################
// ########################### Plugin 114 VEML6075 I2C UVA/UVB Sensor ###############################
// #######################################################################################################
// ###################################### stefan@clumsy.ch ##########################################
// #######################################################################################################
# define PLUGIN_114
# define PLUGIN_ID_114 114
# define PLUGIN_NAME_114 "UV - VEML6075 UVA/UVB Sensor [TESTING]"
# define PLUGIN_VALUENAME1_114 "UVA"
# define PLUGIN_VALUENAME2_114 "UVB"
# define PLUGIN_VALUENAME3_114 "UVIndex"
# include "./src/PluginStructs/P114_data_struct.h"
boolean Plugin_114(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_114;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_TRIPLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 3;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_114);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_114));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_114));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_114));
break;
}
case PLUGIN_WEBFORM_SHOW_I2C_PARAMS:
{
int optionValues[2] = { 0x10, 0x11 };
addFormSelectorI2C(F("plugin_114_veml6075_i2c"), 2, optionValues, PCONFIG(0));
addFormNote(F("SDO Low=0x10, High=0x11"));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
{
String optionsMode2[5];
optionsMode2[0] = F("50 ms");
optionsMode2[1] = F("100 ms");
optionsMode2[2] = F("200 ms");
optionsMode2[3] = F("400 ms");
optionsMode2[4] = F("800 ms");
int optionValuesMode2[5];
optionValuesMode2[0] = IT_50;
optionValuesMode2[1] = IT_100;
optionValuesMode2[2] = IT_200;
optionValuesMode2[3] = IT_400;
optionValuesMode2[4] = IT_800;
addFormSelector(F("Integration Time"), F("plugin_114_veml6075_it"), 5, optionsMode2, optionValuesMode2, PCONFIG(1));
}
{
String optionsMode3[2];
optionsMode3[0] = F("Normal Dynamic");
optionsMode3[1] = F("High Dynamic");
int optionValuesMode3[2];
optionValuesMode3[0] = 0;
optionValuesMode3[1] = 1;
addFormSelector(F("Dynamic Setting"), F("plugin_114_veml6075_hd"), 2, optionsMode3, optionValuesMode3, PCONFIG(2));
}
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
PCONFIG(0) = getFormItemInt(F("plugin_114_veml6075_i2c"));
PCONFIG(1) = getFormItemInt(F("plugin_114_veml6075_it"));
PCONFIG(2) = getFormItemInt(F("plugin_114_veml6075_hd"));
success = true;
break;
}
case PLUGIN_INIT:
{
initPluginTaskData(event->TaskIndex, new (std::nothrow) P114_data_struct(PCONFIG(0), PCONFIG(1), PCONFIG(2) == 1));
P114_data_struct *P114_data =
static_cast<P114_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr == P114_data) {
return success;
}
success = true;
break;
}
case PLUGIN_READ:
{
P114_data_struct *P114_data =
static_cast<P114_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr == P114_data) {
return success;
}
String log;
float UVA = 0.0f;
float UVB = 0.0f;
float UVIndex = 0.0f;
if (P114_data->read_sensor(UVA, UVB, UVIndex)) {
UserVar[event->BaseVarIndex] = UVA;
UserVar[event->BaseVarIndex + 1] = UVB;
UserVar[event->BaseVarIndex + 2] = UVIndex;
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
log.reserve(130);
log = F("VEML6075: Address: 0x");
log += String(PCONFIG(0), HEX);
log += F(" / Integration Time: ");
log += PCONFIG(1);
log += F(" / Dynamic Mode: ");
log += PCONFIG(2);
log += F(" / divisor: ");
log += String(pow(2, PCONFIG(1) - 1));
log += F(" / UVA: ");
log += UserVar[event->BaseVarIndex];
log += F(" / UVB: ");
log += UserVar[event->BaseVarIndex + 1];
log += F(" / UVIndex: ");
log += UserVar[event->BaseVarIndex + 2];
addLog(LOG_LEVEL_INFO, log);
}
success = true;
}
break;
}
}
return success;
}
#endif // ifdef USES_P114
+1 -1
View File
@@ -1369,7 +1369,7 @@ To create/register a plugin, you have to :
#define USES_P113 // VL53L1X
#endif
#ifndef USES_P114
#define USES_P114 //
#define USES_P114 // VEML6075 UVA/UVB sensor
#endif
#ifndef USES_P115
#define USES_P115 //
+106
View File
@@ -0,0 +1,106 @@
#include "../PluginStructs/P114_data_struct.h"
#ifdef USES_P114
// **************************************************************************/
// Constructor
// **************************************************************************/
P114_data_struct::P114_data_struct(uint8_t i2c_addr, uint8_t integration_time, bool highDensity)
: i2cAddress(i2c_addr), IT(integration_time), HD(highDensity) {}
// **************************************************************************/
// Initialize sensor and read data from VEML6075
// **************************************************************************/
bool P114_data_struct::read_sensor(float& _UVA, float& _UVB, float& _UVIndex) {
if (!initialised) {
initialised = init_sensor(); // Check id device is present
}
String log;
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
log.reserve(40);
log = F("VEML6075: i2caddress: 0x");
log += String(i2cAddress, HEX);
addLog(LOG_LEVEL_DEBUG, log);
log = F("VEML6075: initialized: ");
log += String(initialised ? F("true") : F("false"));
addLog(LOG_LEVEL_DEBUG, log);
}
if (initialised) {
for (int j = 0; j < 5; j++) {
UVData[j] = I2C_read16_LE_reg(i2cAddress, VEML6075_UVA_DATA + j);
}
// Calculate the UV Index, valid in open air not behind glass!
UVAComp = (UVData[0] - UVData[1]) - ACoef * (UVData[3] - UVData[1]) - BCoef * (UVData[4] - UVData[1]);
UVBComp = (UVData[2] - UVData[1]) - CCoef * (UVData[3] - UVData[1]) - DCoef * (UVData[4] - UVData[1]);
_UVIndex = ((UVBComp * UVBresponsivity) + (UVAComp * UVAresponsivity)) / 2.;
_UVA = UVData[0] / pow(2, IT - 1); // UVA light sensitivity increases linear with integration time
_UVB = UVData[2] / pow(2, IT - 1); // UVB light sensitivity increases linear with integration time
// float UVASensitivity = 0.93/((float) (IT + 1)); // UVA light sensitivity increases with integration time
// float UVBSensitivity = 2.10/((float) (IT + 1)); // UVB light sensitivity increases with integration time
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
log = F("VEML6075: IT raw: 0x");
log += String(IT + 1, HEX);
addLog(LOG_LEVEL_DEBUG, log);
}
return true;
}
return false;
}
// **************************************************************************/
// Check VEML6075 presence and initialize
// **************************************************************************/
bool P114_data_struct::init_sensor() {
uint16_t deviceID = I2C_readS16_LE_reg(i2cAddress, VEML6075_UV_ID);
String log;
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
log.reserve(60);
log = F("VEML6075: ID: 0x");
log += String(deviceID, HEX);
log += F(" / checked Address: 0x");
log += String(i2cAddress, HEX);
log += F(" / 0x");
log += String(VEML6075_UV_ID, HEX);
addLog(LOG_LEVEL_DEBUG, log);
}
if (deviceID != 0x26) {
log.reserve(60);
log = F("VEML6075: wrong deviceID: ");
log += String(deviceID, HEX);
addLog(LOG_LEVEL_ERROR, log);
return false;
} else {
log.reserve(60);
// log = F("VEML6075: found deviceID: 0x");
// log += String(deviceID, HEX);
if (!I2C_write16_LE_reg(i2cAddress, VEML6075_UV_CONF, (IT << 4) | (HD << 3))) { // Bit 3 must be 0, bit 0 is 0 for run and 1 for
// shutdown, LS Byte
log = F("VEML6075: setup failed!!");
log += F(" / CONF: ");
log += String(static_cast<uint16_t>(IT << 4) | (HD << 3), BIN);
addLog(LOG_LEVEL_ERROR, log);
return false;
} else if (loglevelActiveFor(LOG_LEVEL_INFO)) {
log = F("VEML6075: sensor initialised / CONF: ");
log += String((uint16_t)(IT << 4) | (HD << 3), BIN);
addLog(LOG_LEVEL_INFO, log);
}
}
return true;
}
#endif // ifdef USES_P114
+63
View File
@@ -0,0 +1,63 @@
#ifndef PLUGINSTRUCTS_P114_DATA_STRUCT_H
#define PLUGINSTRUCTS_P114_DATA_STRUCT_H
#include "../../_Plugin_Helper.h"
#ifdef USES_P114
////////////////////////////
// VEML6075 Command Codes //
////////////////////////////
# define VEML6075_UV_CONF 0x00 // command codes
# define VEML6075_UVA_DATA 0x07 // 2 bytes
# define VEML6075_UVDUMMY_DATA 0x08
# define VEML6075_UVB_DATA 0x09
# define VEML6075_UVCOMP1_DATA 0x0A
# define VEML6075_UVCOMP2_DATA 0x0B
# define VEML6075_UV_ID 0x0C // should retrn 0x26
// Calculation factors
# define ACoef 3.33f
# define BCoef 2.5f
# define CCoef 3.66f
# define DCoef 2.75f
# define UVAresponsivity 0.0011f
# define UVBresponsivity 0.00125f
enum IT {
IT_50 = 0, // 50 ms
IT_100 = 1, // 100 ms
IT_200 = 2, // 200 ms
IT_400 = 3, // 400 ms
IT_800 = 4 // 800 ms
};
struct P114_data_struct : public PluginTaskData_base {
public:
P114_data_struct(uint8_t i2c_addr,
uint8_t integration_time,
bool highDensity);
bool read_sensor(float& _UVA,
float& _UVB,
float& _UVIndex);
private:
bool init_sensor();
uint8_t i2cAddress;
// Specify VEML6075 Integration time
uint8_t IT;
bool HD;
uint16_t UVData[5] = { 0, 0, 0, 0, 0 }; // UVA, Dummy, UVB, UVComp1, UVComp2
float UVAComp;
float UVBComp;
bool initialised;
};
#endif // ifdef USES_P114
#endif // ifndef PLUGINSTRUCTS_P114_DATA_STRUCT_H