Browse Source

Support for BH1750 luminosity sensor

fastled
Xose Pérez 6 years ago
parent
commit
ad62a6ad74
6 changed files with 1945 additions and 1751 deletions
  1. +34
    -5
      code/espurna/config/sensors.h
  2. BIN
      code/espurna/data/index.html.gz
  3. +9
    -0
      code/espurna/sensor.ino
  4. +155
    -0
      code/espurna/sensors/BH1750Sensor.h
  5. +1744
    -1743
      code/espurna/static/index.html.gz.h
  6. +3
    -3
      code/html/custom.js

+ 34
- 5
code/espurna/config/sensors.h View File

@ -57,6 +57,7 @@
#define SENSOR_MHZ19_ID 0x14 #define SENSOR_MHZ19_ID 0x14
#define SENSOR_SI7021_ID 0x15 #define SENSOR_SI7021_ID 0x15
#define SENSOR_SHT3X_I2C_ID 0x16 #define SENSOR_SHT3X_I2C_ID 0x16
#define SENSOR_BH1750_ID 0x17
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Magnitudes // Magnitudes
@ -81,8 +82,9 @@
#define MAGNITUDE_PM2dot5 16 #define MAGNITUDE_PM2dot5 16
#define MAGNITUDE_PM10 17 #define MAGNITUDE_PM10 17
#define MAGNITUDE_CO2 18 #define MAGNITUDE_CO2 18
#define MAGNITUDE_LUX 19
#define MAGNITUDE_MAX 19
#define MAGNITUDE_MAX 20
// ============================================================================= // =============================================================================
// Specific data for each sensor // Specific data for each sensor
@ -102,6 +104,27 @@
#define ADC_VCC_ENABLED 0 #define ADC_VCC_ENABLED 0
#endif #endif
//------------------------------------------------------------------------------
// BH1750
// Enable support by passing BH1750_SUPPORT=1 build flag
// http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf
//------------------------------------------------------------------------------
#ifndef BH1750_SUPPORT
#define BH1750_SUPPORT 0
#endif
#ifndef BH1750_ADDRESS
#define BH1750_ADDRESS 0x00 // 0x00 means auto
#endif
#define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE
#if BH1750_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// BME280/BMP280 // BME280/BMP280
// Enable support by passing BMX280_SUPPORT=1 build flag // Enable support by passing BMX280_SUPPORT=1 build flag
@ -415,7 +438,7 @@
// Sensor helpers configuration // Sensor helpers configuration
// ============================================================================= // =============================================================================
#if ANALOG_SUPPORT || BMX280_SUPPORT || DALLAS_SUPPORT \
#if ANALOG_SUPPORT || BH1750_SUPPORT || BMX280_SUPPORT || DALLAS_SUPPORT \
|| DHT_SUPPORT || DIGITAL_SUPPORT || ECH1560_SUPPORT \ || DHT_SUPPORT || DIGITAL_SUPPORT || ECH1560_SUPPORT \
|| EMON_ADC121_SUPPORT || EMON_ADS1X15_SUPPORT \ || EMON_ADC121_SUPPORT || EMON_ADS1X15_SUPPORT \
|| EMON_ANALOG_SUPPORT || EVENTS_SUPPORT || HLW8012_SUPPORT \ || EMON_ANALOG_SUPPORT || EVENTS_SUPPORT || HLW8012_SUPPORT \
@ -474,7 +497,7 @@ PROGMEM const unsigned char magnitude_decimals[] = {
3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0
0, 0
}; };
PROGMEM const char magnitude_unknown_topic[] = "unknown"; PROGMEM const char magnitude_unknown_topic[] = "unknown";
@ -496,6 +519,7 @@ PROGMEM const char magnitude_analog_topic[] = "analog";
PROGMEM const char magnitude_digital_topic[] = "digital"; PROGMEM const char magnitude_digital_topic[] = "digital";
PROGMEM const char magnitude_events_topic[] = "events"; PROGMEM const char magnitude_events_topic[] = "events";
PROGMEM const char magnitude_co2_topic[] = "co2"; PROGMEM const char magnitude_co2_topic[] = "co2";
PROGMEM const char magnitude_lux_topic[] = "lux";
PROGMEM const char* const magnitude_topics[] = { PROGMEM const char* const magnitude_topics[] = {
magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic, magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic,
@ -504,7 +528,7 @@ PROGMEM const char* const magnitude_topics[] = {
magnitude_power_factor_topic, magnitude_energy_topic, magnitude_energy_delta_topic, magnitude_power_factor_topic, magnitude_energy_topic, magnitude_energy_delta_topic,
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic, magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic, magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic,
magnitude_co2_topic
magnitude_co2_topic, magnitude_lux_topic
}; };
PROGMEM const char magnitude_empty[] = ""; PROGMEM const char magnitude_empty[] = "";
@ -518,6 +542,7 @@ PROGMEM const char magnitude_watts[] = "W";
PROGMEM const char magnitude_joules[] = "J"; PROGMEM const char magnitude_joules[] = "J";
PROGMEM const char magnitude_ugm3[] = "µg/m3"; PROGMEM const char magnitude_ugm3[] = "µg/m3";
PROGMEM const char magnitude_ppm[] = "ppm"; PROGMEM const char magnitude_ppm[] = "ppm";
PROGMEM const char magnitude_lux[] = "lux";
PROGMEM const char* const magnitude_units[] = { PROGMEM const char* const magnitude_units[] = {
magnitude_empty, magnitude_celsius, magnitude_percentage, magnitude_empty, magnitude_celsius, magnitude_percentage,
@ -526,7 +551,7 @@ PROGMEM const char* const magnitude_units[] = {
magnitude_percentage, magnitude_joules, magnitude_joules, magnitude_percentage, magnitude_joules, magnitude_joules,
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty,
magnitude_ppm
magnitude_ppm, magnitude_lux
}; };
#include "../sensors/BaseSensor.h" #include "../sensors/BaseSensor.h"
@ -535,6 +560,10 @@ PROGMEM const char* const magnitude_units[] = {
#include "../sensors/AnalogSensor.h" #include "../sensors/AnalogSensor.h"
#endif #endif
#if BH1750_SUPPORT
#include "../sensors/BH1750Sensor.h"
#endif
#if BMX280_SUPPORT #if BMX280_SUPPORT
#include <SparkFunBME280.h> #include <SparkFunBME280.h>
#include "../sensors/BMX280Sensor.h" #include "../sensors/BMX280Sensor.h"


BIN
code/espurna/data/index.html.gz View File


+ 9
- 0
code/espurna/sensor.ino View File

@ -210,6 +210,15 @@ void _sensorInit() {
} }
#endif #endif
#if BH1750_SUPPORT
{
BH1750Sensor * sensor = new BH1750Sensor();
sensor->setAddress(BH1750_ADDRESS);
sensor->setMode(BH1750_MODE);
_sensors.push_back(sensor);
}
#endif
#if BMX280_SUPPORT #if BMX280_SUPPORT
{ {
BMX280Sensor * sensor = new BMX280Sensor(); BMX280Sensor * sensor = new BMX280Sensor();


+ 155
- 0
code/espurna/sensors/BH1750Sensor.h View File

@ -0,0 +1,155 @@
// -----------------------------------------------------------------------------
// BH1750 Liminosity sensor over I2C
// Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
// -----------------------------------------------------------------------------
#if SENSOR_SUPPORT && BH1750_SUPPORT
#pragma once
#include "Arduino.h"
#include "I2CSensor.h"
#if I2C_USE_BRZO
#include <brzo_i2c.h>
#else
#include <Wire.h>
#endif
#define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
#define BH1750_CONTINUOUS_HIGH_RES_MODE_2 0x11 // Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
#define BH1750_CONTINUOUS_LOW_RES_MODE 0x13 // Start measurement at 4lx resolution. Measurement time is approx 16ms.
#define BH1750_ONE_TIME_HIGH_RES_MODE 0x20 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_HIGH_RES_MODE_2 0x21 // Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_LOW_RES_MODE 0x23 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
class BH1750Sensor : public I2CSensor {
public:
// ---------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------
BH1750Sensor(): I2CSensor() {
_sensor_id = SENSOR_BH1750_ID;
_count = 1;
}
// ---------------------------------------------------------------------
void setMode(unsigned char mode) {
if (_mode == mode) return;
_mode = mode;
_dirty = true;
}
// ---------------------------------------------------------------------
unsigned char getMode() {
return _mode;
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
// Initialization method, must be idempotent
void begin() {
if (!_dirty) return;
_dirty = false;
// I2C auto-discover
unsigned char addresses[] = {0x23, 0x5C};
_address = _begin_i2c(_address, sizeof(addresses), addresses);
if (_address == 0) return;
// Configure
_configure();
delay(10);
}
// Descriptive name of the sensor
String description() {
char buffer[25];
snprintf(buffer, sizeof(buffer), "BH1750 @ I2C (0x%02X)", _address);
return String(buffer);
}
// Type for slot # index
unsigned char type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_LUX;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return _read();
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}
protected:
void _configure() {
#if I2C_USE_BRZO
uint8_t buffer[1] = {_mode};
brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY);
brzo_i2c_write(buffer, 1, false);
brzo_i2c_end_transaction();
#else
Wire.beginTransmission(_address);
Wire.write(_mode);
Wire.endTransmission();
#endif
}
double _read() {
double level;
uint8_t buffer[2];
// For one-shot modes reconfigure sensor & wait for conversion
if (_mode & 0x20) {
_configure();
// According to datasheet
// conversion time is ~16ms for low resolution
// and ~120 for high resolution
// but more time is needed
unsigned long wait = (_mode & 0x02) ? 24 : 180;
unsigned long start = millis();
while (millis() - start < wait) delay(1);
}
#if I2C_USE_BRZO
brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY);
brzo_i2c_read(buffer, 2, false);
brzo_i2c_end_transaction();
#else
Wire.beginTransmission(_address);
Wire.requestFrom(_address, (unsigned char) 2);
buffer[0] = Wire.read();
buffer[1] = Wire.read();
Wire.endTransmission();
#endif
level = buffer[0] * 256 + buffer[1];
return level / 1.2;
}
unsigned char _mode;
};
#endif // SENSOR_SUPPORT && SI7021_SUPPORT

+ 1744
- 1743
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 3
- 3
code/html/custom.js View File

@ -33,7 +33,7 @@ function sensorName(id) {
"DHT", "Dallas", "Emon Analog", "Emon ADC121", "Emon ADS1X15", "DHT", "Dallas", "Emon Analog", "Emon ADC121", "Emon ADS1X15",
"HLW8012", "V9261F", "ECH1560", "Analog", "Digital", "HLW8012", "V9261F", "ECH1560", "Analog", "Digital",
"Events", "PMSX003", "BMX280", "MHZ19", "SI7021", "Events", "PMSX003", "BMX280", "MHZ19", "SI7021",
"SHT3X I2C"
"SHT3X I2C", "BH1750"
]; ];
if (1 <= id && id <= names.length) return names[id-1]; if (1 <= id && id <= names.length) return names[id-1];
return null; return null;
@ -45,7 +45,7 @@ function magnitudeType(type) {
"Current", "Voltage", "Active Power", "Apparent Power", "Current", "Voltage", "Active Power", "Apparent Power",
"Reactive Power", "Power Factor", "Energy", "Energy (delta)", "Reactive Power", "Power Factor", "Energy", "Energy (delta)",
"Analog", "Digital", "Events", "Analog", "Digital", "Events",
"PM1.0", "PM2.5", "PM10", "CO2"
"PM1.0", "PM2.5", "PM10", "CO2", "Lux"
]; ];
if (1 <= type && type <= types.length) return types[type-1]; if (1 <= type && type <= types.length) return types[type-1];
return null; return null;
@ -54,7 +54,7 @@ function magnitudeType(type) {
function magnitudeError(error) { function magnitudeError(error) {
var errors = [ var errors = [
"OK", "Out of Range", "Warming Up", "Timeout", "Wrong ID", "OK", "Out of Range", "Warming Up", "Timeout", "Wrong ID",
"CRC Error", "I2C Error"
"CRC Error", "I2C Error", "GPIO Error"
]; ];
if (0 <= error && error < errors.length) return errors[error]; if (0 <= error && error < errors.length) return errors[error];
return "Error " + error; return "Error " + error;


Loading…
Cancel
Save