mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-18 16:26:31 +00:00
Support for VEML6075 and VEML 7700
Add support for VEML6075. -Shows UVA, UVB, UVIndex supported Commands are: | Command | Description | |----------------|------------------| |VEML6075power | Power up/down | |VEML6075dynamic | HD Mode | |VEML6075inttime | Integration Time | Add initial Support for VEML7700 (#8260) - the implementation based on Adafruit VEML7700 Libary. - Shows Illuminance and White Content of Light.
This commit is contained in:
parent
bfb0c343a0
commit
47a8df84be
@ -69,4 +69,6 @@ Index | Define | Driver | Device | Address(es) | Description
|
|||||||
45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor
|
45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor
|
||||||
46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor
|
46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor
|
||||||
47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED
|
47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED
|
||||||
48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor
|
48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor
|
||||||
|
49 | USE_VEML6075 | xsns_68 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor
|
||||||
|
50 | USE_VEML7700 | xsns_69 | VEML7700 | 0x10 | Ambient light intensity sensor
|
23
lib/Adafruit_BusIO/.travis.yml
Normal file
23
lib/Adafruit_BusIO/.travis.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
language: c
|
||||||
|
sudo: false
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- ~/arduino_ide
|
||||||
|
- ~/.arduino15/packages/
|
||||||
|
git:
|
||||||
|
depth: false
|
||||||
|
quiet: true
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- PRETTYNAME="Adafruit BusIO Library"
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
|
||||||
|
|
||||||
|
script:
|
||||||
|
- build_main_platforms
|
||||||
|
|
||||||
|
# Generate and deploy documentation
|
||||||
|
after_success:
|
||||||
|
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
|
||||||
|
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
|
258
lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp
Normal file
258
lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over an I2C Device (which defines the bus and address)
|
||||||
|
* @param i2cdevice The I2CDevice to use for underlying I2C access
|
||||||
|
* @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits
|
||||||
|
* @param width The width of the register data itself, defaults to 1 byte
|
||||||
|
* @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST
|
||||||
|
* @param address_width The width of the register address itself, defaults to 1 byte
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
|
||||||
|
uint8_t width, uint8_t bitorder, uint8_t address_width) {
|
||||||
|
_i2cdevice = i2cdevice;
|
||||||
|
_spidevice = NULL;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_bitorder = bitorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over an SPI Device (which defines the bus and CS pin)
|
||||||
|
* @param spidevice The SPIDevice to use for underlying I2C access
|
||||||
|
* @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits
|
||||||
|
* @param type The method we use to read/write data to SPI (which is not as well defined as I2C)
|
||||||
|
* @param width The width of the register data itself, defaults to 1 byte
|
||||||
|
* @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST
|
||||||
|
* @param address_width The width of the register address itself, defaults to 1 byte
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
|
||||||
|
Adafruit_BusIO_SPIRegType type,
|
||||||
|
uint8_t width, uint8_t bitorder, uint8_t address_width) {
|
||||||
|
_spidevice = spidevice;
|
||||||
|
_spiregtype = type;
|
||||||
|
_i2cdevice = NULL;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_bitorder = bitorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over an I2C or SPI Device. This is a handy function because we
|
||||||
|
* can pass in NULL for the unused interface, allowing libraries to mass-define all the registers
|
||||||
|
* @param i2cdevice The I2CDevice to use for underlying I2C access, if NULL we use SPI
|
||||||
|
* @param spidevice The SPIDevice to use for underlying I2C access, if NULL we use I2C
|
||||||
|
* @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits
|
||||||
|
* @param type The method we use to read/write data to SPI (which is not as well defined as I2C)
|
||||||
|
* @param width The width of the register data itself, defaults to 1 byte
|
||||||
|
* @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST
|
||||||
|
* @param address_width The width of the register address itself, defaults to 1 byte
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice,
|
||||||
|
Adafruit_BusIO_SPIRegType type, uint16_t reg_addr,
|
||||||
|
uint8_t width, uint8_t bitorder, uint8_t address_width) {
|
||||||
|
_spidevice = spidevice;
|
||||||
|
_i2cdevice = i2cdevice;
|
||||||
|
_spiregtype = type;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_bitorder = bitorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer of data to the register location
|
||||||
|
* @param buffer Pointer to data to write
|
||||||
|
* @param len Number of bytes to write
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
|
||||||
|
|
||||||
|
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)};
|
||||||
|
|
||||||
|
if (_i2cdevice) {
|
||||||
|
return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
|
||||||
|
}
|
||||||
|
if (_spidevice) {
|
||||||
|
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
|
||||||
|
addrbuffer[0] &= ~0x80;
|
||||||
|
}
|
||||||
|
return _spidevice->write( buffer, len, addrbuffer, _addrwidth);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write up to 4 bytes of data to the register location
|
||||||
|
* @param value Data to write
|
||||||
|
* @param numbytes How many bytes from 'value' to write
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) {
|
||||||
|
if (numbytes == 0) {
|
||||||
|
numbytes = _width;
|
||||||
|
}
|
||||||
|
if (numbytes > 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<numbytes; i++) {
|
||||||
|
if (_bitorder == LSBFIRST) {
|
||||||
|
_buffer[i] = value & 0xFF;
|
||||||
|
} else {
|
||||||
|
_buffer[numbytes-i-1] = value & 0xFF;
|
||||||
|
}
|
||||||
|
value >>= 8;
|
||||||
|
}
|
||||||
|
return write(_buffer, numbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read data from the register location. This does not do any error checking!
|
||||||
|
* @return Returns 0xFFFFFFFF on failure, value otherwise
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BusIO_Register::read(void) {
|
||||||
|
if (! read(_buffer, _width)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t value = 0;
|
||||||
|
|
||||||
|
for (int i=0; i < _width; i++) {
|
||||||
|
value <<= 8;
|
||||||
|
if (_bitorder == LSBFIRST) {
|
||||||
|
value |= _buffer[_width-i-1];
|
||||||
|
} else {
|
||||||
|
value |= _buffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read a buffer of data from the register location
|
||||||
|
* @param buffer Pointer to data to read into
|
||||||
|
* @param len Number of bytes to read
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
|
||||||
|
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)};
|
||||||
|
|
||||||
|
if (_i2cdevice) {
|
||||||
|
return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
|
||||||
|
}
|
||||||
|
if (_spidevice) {
|
||||||
|
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
|
||||||
|
addrbuffer[0] |= 0x80;
|
||||||
|
}
|
||||||
|
return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read 2 bytes of data from the register location
|
||||||
|
* @param value Pointer to uint16_t variable to read into
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::read(uint16_t *value) {
|
||||||
|
if (! read(_buffer, 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_bitorder == LSBFIRST) {
|
||||||
|
*value = _buffer[1];
|
||||||
|
*value <<= 8;
|
||||||
|
*value |= _buffer[0];
|
||||||
|
} else {
|
||||||
|
*value = _buffer[0];
|
||||||
|
*value <<= 8;
|
||||||
|
*value |= _buffer[1];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read 1 byte of data from the register location
|
||||||
|
* @param value Pointer to uint8_t variable to read into
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::read(uint8_t *value) {
|
||||||
|
if (! read(_buffer, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = _buffer[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Pretty printer for this register
|
||||||
|
* @param s The Stream to print to, defaults to &Serial
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::print(Stream *s) {
|
||||||
|
uint32_t val = read();
|
||||||
|
s->print("0x"); s->print(val, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Pretty printer for this register
|
||||||
|
* @param s The Stream to print to, defaults to &Serial
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::println(Stream *s) {
|
||||||
|
print(s);
|
||||||
|
s->println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a slice of the register that we can address without touching other bits
|
||||||
|
* @param reg The Adafruit_BusIO_Register which defines the bus/register
|
||||||
|
* @param bits The number of bits wide we are slicing
|
||||||
|
* @param shift The number of bits that our bit-slice is shifted from LSB
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) {
|
||||||
|
_register = reg;
|
||||||
|
_bits = bits;
|
||||||
|
_shift = shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read 4 bytes of data from the register
|
||||||
|
* @return data The 4 bytes to read
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BusIO_RegisterBits::read(void) {
|
||||||
|
uint32_t val = _register->read();
|
||||||
|
val >>= _shift;
|
||||||
|
return val & ((1 << (_bits)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write 4 bytes of data to the register
|
||||||
|
* @param data The 4 bytes to write
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_RegisterBits::write(uint32_t data) {
|
||||||
|
uint32_t val = _register->read();
|
||||||
|
|
||||||
|
// mask off the data before writing
|
||||||
|
uint32_t mask = (1 << (_bits)) - 1;
|
||||||
|
data &= mask;
|
||||||
|
|
||||||
|
mask <<= _shift;
|
||||||
|
val &= ~mask; // remove the current data at that spot
|
||||||
|
val |= data << _shift; // and add in the new data
|
||||||
|
|
||||||
|
_register->write(val, _register->width());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The width of the register data, helpful for doing calculations
|
||||||
|
* @returns The data width used when initializing the register
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_BusIO_Register::width(void) { return _width; }
|
69
lib/Adafruit_BusIO/Adafruit_BusIO_Register.h
Normal file
69
lib/Adafruit_BusIO/Adafruit_BusIO_Register.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Adafruit_BusIO_Register_h
|
||||||
|
#define Adafruit_BusIO_Register_h
|
||||||
|
|
||||||
|
typedef enum _Adafruit_BusIO_SPIRegType {
|
||||||
|
ADDRBIT8_HIGH_TOREAD = 0,
|
||||||
|
} Adafruit_BusIO_SPIRegType;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The class which defines a device register (a location to read/write data from)
|
||||||
|
*/
|
||||||
|
class Adafruit_BusIO_Register {
|
||||||
|
public:
|
||||||
|
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
|
||||||
|
uint8_t width=1, uint8_t bitorder=LSBFIRST,
|
||||||
|
uint8_t address_width=1);
|
||||||
|
Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
|
||||||
|
Adafruit_BusIO_SPIRegType type,
|
||||||
|
uint8_t width=1, uint8_t bitorder=LSBFIRST,
|
||||||
|
uint8_t address_width=1);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
|
||||||
|
Adafruit_SPIDevice *spidevice,
|
||||||
|
Adafruit_BusIO_SPIRegType type,
|
||||||
|
uint16_t reg_addr,
|
||||||
|
uint8_t width=1, uint8_t bitorder=LSBFIRST,
|
||||||
|
uint8_t address_width=1);
|
||||||
|
|
||||||
|
bool read(uint8_t *buffer, uint8_t len);
|
||||||
|
bool read(uint8_t *value);
|
||||||
|
bool read(uint16_t *value);
|
||||||
|
uint32_t read(void);
|
||||||
|
bool write(uint8_t *buffer, uint8_t len);
|
||||||
|
bool write(uint32_t value, uint8_t numbytes=0);
|
||||||
|
|
||||||
|
uint8_t width(void);
|
||||||
|
|
||||||
|
void print(Stream *s=&Serial);
|
||||||
|
void println(Stream *s=&Serial);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Adafruit_I2CDevice *_i2cdevice;
|
||||||
|
Adafruit_SPIDevice *_spidevice;
|
||||||
|
Adafruit_BusIO_SPIRegType _spiregtype;
|
||||||
|
uint16_t _address;
|
||||||
|
uint8_t _width, _addrwidth, _bitorder;
|
||||||
|
uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The class which defines a slice of bits from within a device register (a location to read/write data from)
|
||||||
|
*/
|
||||||
|
class Adafruit_BusIO_RegisterBits {
|
||||||
|
public:
|
||||||
|
Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift);
|
||||||
|
void write(uint32_t value);
|
||||||
|
uint32_t read(void);
|
||||||
|
private:
|
||||||
|
Adafruit_BusIO_Register *_register;
|
||||||
|
uint8_t _bits, _shift;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //BusIO_Register_h
|
213
lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp
Normal file
213
lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
//#define DEBUG_SERIAL Serial
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create an I2C device at a given address
|
||||||
|
* @param addr The 7-bit I2C address for the device
|
||||||
|
* @param theWire The I2C bus to use, defaults to &Wire
|
||||||
|
*/
|
||||||
|
Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
|
||||||
|
_addr = addr;
|
||||||
|
_wire = theWire;
|
||||||
|
_begun = false;
|
||||||
|
#ifdef ARDUINO_ARCH_SAMD
|
||||||
|
_maxBufferSize = 250; // as defined in Wire.h's RingBuffer
|
||||||
|
#else
|
||||||
|
_maxBufferSize = 32;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initializes and does basic address detection
|
||||||
|
* @param addr_detect Whether we should attempt to detect the I2C address with a scan.
|
||||||
|
* 99% of sensors/devices don't mind but once in a while, they spaz on a scan!
|
||||||
|
* @return True if I2C initialized and a device with the addr found
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::begin(bool addr_detect) {
|
||||||
|
_wire->begin();
|
||||||
|
_begun = true;
|
||||||
|
|
||||||
|
if (addr_detect) {
|
||||||
|
return detected();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Scans I2C for the address - note will give a false-positive
|
||||||
|
* if there's no pullups on I2C
|
||||||
|
* @return True if I2C initialized and a device with the addr found
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::detected(void) {
|
||||||
|
// Init I2C if not done yet
|
||||||
|
if (!_begun && !begin()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A basic scanner, see if it ACK's
|
||||||
|
_wire->beginTransmission(_addr);
|
||||||
|
if (_wire->endTransmission () == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer or two to the I2C device. Cannot be more than maxBufferSize() bytes.
|
||||||
|
* @param buffer Pointer to buffer of data to write
|
||||||
|
* @param len Number of bytes from buffer to write
|
||||||
|
* @param prefix_buffer Pointer to optional array of data to write before buffer.
|
||||||
|
* Cannot be more than maxBufferSize() bytes.
|
||||||
|
* @param prefix_len Number of bytes from prefix buffer to write
|
||||||
|
* @param stop Whether to send an I2C STOP signal on write
|
||||||
|
* @return True if write was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop, uint8_t *prefix_buffer, size_t prefix_len) {
|
||||||
|
if ((len+prefix_len) > maxBufferSize()) {
|
||||||
|
// currently not guaranteed to work if more than 32 bytes!
|
||||||
|
// we will need to find out if some platforms have larger
|
||||||
|
// I2C buffer sizes :/
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_wire->beginTransmission(_addr);
|
||||||
|
|
||||||
|
// Write the prefix data (usually an address)
|
||||||
|
if ((prefix_len != 0) && (prefix_buffer != NULL)) {
|
||||||
|
if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the data itself
|
||||||
|
if (_wire->write(buffer, len) != len) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tI2CDevice Wrote: "));
|
||||||
|
if ((prefix_len != 0) && (prefix_buffer != NULL)) {
|
||||||
|
for (uint16_t i=0; i<prefix_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint16_t i=0; i<len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print("Stop: "); DEBUG_SERIAL.println(stop);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_wire->endTransmission(stop) == 0) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println("Sent!");
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println("Failed to send!");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read from I2C into a buffer from the I2C device.
|
||||||
|
* Cannot be more than maxBufferSize() bytes.
|
||||||
|
* @param buffer Pointer to buffer of data to read into
|
||||||
|
* @param len Number of bytes from buffer to read.
|
||||||
|
* @param stop Whether to send an I2C STOP signal on read
|
||||||
|
* @return True if read was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
|
||||||
|
if (len > maxBufferSize()) {
|
||||||
|
// currently not guaranteed to work if more than 32 bytes!
|
||||||
|
// we will need to find out if some platforms have larger
|
||||||
|
// I2C buffer sizes :/
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice could not read such a large buffer"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
|
||||||
|
if (recv != len) {
|
||||||
|
// Not enough data available to fulfill our obligation!
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
|
||||||
|
DEBUG_SERIAL.println(recv);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i=0; i<len; i++) {
|
||||||
|
buffer[i] = _wire->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tI2CDevice Read: "));
|
||||||
|
for (uint16_t i=0; i<len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write some data, then read some data from I2C into another buffer.
|
||||||
|
* Cannot be more than maxBufferSize() bytes. The buffers can point to
|
||||||
|
* same/overlapping locations.
|
||||||
|
* @param write_buffer Pointer to buffer of data to write from
|
||||||
|
* @param write_len Number of bytes from buffer to write.
|
||||||
|
* @param read_buffer Pointer to buffer of data to read into.
|
||||||
|
* @param read_len Number of bytes from buffer to read.
|
||||||
|
* @param stop Whether to send an I2C STOP signal between the write and read
|
||||||
|
* @return True if write & read was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, bool stop) {
|
||||||
|
if (! write(write_buffer, write_len, stop)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return read(read_buffer, read_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Returns the 7-bit address of this device
|
||||||
|
* @return The 7-bit address of this device
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_I2CDevice::address(void) {
|
||||||
|
return _addr;
|
||||||
|
}
|
29
lib/Adafruit_BusIO/Adafruit_I2CDevice.h
Normal file
29
lib/Adafruit_BusIO/Adafruit_I2CDevice.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#ifndef Adafruit_I2CDevice_h
|
||||||
|
#define Adafruit_I2CDevice_h
|
||||||
|
|
||||||
|
///< The class which defines how we will talk to this device over I2C
|
||||||
|
class Adafruit_I2CDevice {
|
||||||
|
public:
|
||||||
|
Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire=&Wire);
|
||||||
|
uint8_t address(void);
|
||||||
|
bool begin(bool addr_detect=true);
|
||||||
|
bool detected(void);
|
||||||
|
|
||||||
|
bool read(uint8_t *buffer, size_t len, bool stop=true);
|
||||||
|
bool write(uint8_t *buffer, size_t len, bool stop=true, uint8_t *prefix_buffer=NULL, size_t prefix_len=0);
|
||||||
|
bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, bool stop=false);
|
||||||
|
|
||||||
|
/*! @brief How many bytes we can read in a transaction
|
||||||
|
* @return The size of the Wire receive/transmit buffer */
|
||||||
|
uint16_t maxBufferSize() { return _maxBufferSize; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _addr;
|
||||||
|
TwoWire *_wire;
|
||||||
|
bool _begun;
|
||||||
|
uint16_t _maxBufferSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Adafruit_I2CDevice_h
|
8
lib/Adafruit_BusIO/Adafruit_I2CRegister.h
Normal file
8
lib/Adafruit_BusIO/Adafruit_I2CRegister.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "Adafruit_BusIO_Register.h"
|
||||||
|
#ifndef _ADAFRUIT_I2C_REGISTER_H_
|
||||||
|
#define _ADAFRUIT_I2C_REGISTER_H_
|
||||||
|
|
||||||
|
typedef Adafruit_BusIO_Register Adafruit_I2CRegister;
|
||||||
|
typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits;
|
||||||
|
|
||||||
|
#endif
|
301
lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp
Normal file
301
lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
//#define DEBUG_SERIAL Serial
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create an SPI device with the given CS pin and settins
|
||||||
|
* @param cspin The arduino pin number to use for chip select
|
||||||
|
* @param freq The SPI clock frequency to use, defaults to 1MHz
|
||||||
|
* @param dataOrder The SPI data order to use for bits within each byte, defaults to SPI_BITORDER_MSBFIRST
|
||||||
|
* @param dataMode The SPI mode to use, defaults to SPI_MODE0
|
||||||
|
* @param theSPI The SPI bus to use, defaults to &theSPI
|
||||||
|
*/
|
||||||
|
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq, BitOrder dataOrder, uint8_t dataMode, SPIClass *theSPI) {
|
||||||
|
_cs = cspin;
|
||||||
|
_sck = _mosi = _miso = -1;
|
||||||
|
_spi = theSPI;
|
||||||
|
_begun = false;
|
||||||
|
_spiSetting = new SPISettings(freq, dataOrder, dataMode);
|
||||||
|
_freq = freq;
|
||||||
|
_dataOrder = dataOrder;
|
||||||
|
_dataMode = dataMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create an SPI device with the given CS pin and settins
|
||||||
|
* @param cspin The arduino pin number to use for chip select
|
||||||
|
* @param sckpin The arduino pin number to use for SCK
|
||||||
|
* @param misopin The arduino pin number to use for MISO, set to -1 if not used
|
||||||
|
* @param mosipin The arduino pin number to use for MOSI, set to -1 if not used
|
||||||
|
* @param freq The SPI clock frequency to use, defaults to 1MHz
|
||||||
|
* @param dataOrder The SPI data order to use for bits within each byte, defaults to SPI_BITORDER_MSBFIRST
|
||||||
|
* @param dataMode The SPI mode to use, defaults to SPI_MODE0
|
||||||
|
*/
|
||||||
|
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin, int8_t misopin, int8_t mosipin,
|
||||||
|
uint32_t freq, BitOrder dataOrder, uint8_t dataMode) {
|
||||||
|
_cs = cspin;
|
||||||
|
_sck = sckpin;
|
||||||
|
_miso = misopin;
|
||||||
|
_mosi = mosipin;
|
||||||
|
_freq = freq;
|
||||||
|
_dataOrder = dataOrder;
|
||||||
|
_dataMode = dataMode;
|
||||||
|
_begun = false;
|
||||||
|
_spiSetting = new SPISettings(freq, dataOrder, dataMode);
|
||||||
|
_spi = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initializes SPI bus and sets CS pin high
|
||||||
|
* @return Always returns true because there's no way to test success of SPI init
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::begin(void) {
|
||||||
|
pinMode(_cs, OUTPUT);
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
if (_spi) { // hardware SPI
|
||||||
|
_spi->begin();
|
||||||
|
} else {
|
||||||
|
pinMode(_sck, OUTPUT);
|
||||||
|
|
||||||
|
if (_dataMode==SPI_MODE0) {
|
||||||
|
digitalWrite(_sck, HIGH);
|
||||||
|
} else {
|
||||||
|
digitalWrite(_sck, LOW);
|
||||||
|
}
|
||||||
|
if (_mosi != -1) {
|
||||||
|
pinMode(_mosi, OUTPUT);
|
||||||
|
digitalWrite(_mosi, HIGH);
|
||||||
|
}
|
||||||
|
if (_miso != -1) {
|
||||||
|
pinMode(_miso, INPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_begun = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Transfer (send/receive) one byte over hard/soft SPI
|
||||||
|
* @param buffer The buffer to send and receive at the same time
|
||||||
|
* @param len The number of bytes to transfer
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
|
||||||
|
if (_spi) {
|
||||||
|
// hardware SPI is easy
|
||||||
|
_spi->transfer(buffer, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for softSPI we'll do it by hand
|
||||||
|
for (size_t i=0; i<len; i++) {
|
||||||
|
// software SPI
|
||||||
|
uint8_t reply = 0;
|
||||||
|
uint8_t send = buffer[i];
|
||||||
|
|
||||||
|
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
|
||||||
|
// LSB is rare, if it happens we'll just flip the bits around for them
|
||||||
|
uint8_t temp = 0;
|
||||||
|
for (uint8_t b=0; b<8; b++) {
|
||||||
|
temp |= ((send >> b) & 0x1) << (7-b);
|
||||||
|
}
|
||||||
|
send = temp;
|
||||||
|
}
|
||||||
|
for (int b=7; b>=0; b--) {
|
||||||
|
reply <<= 1;
|
||||||
|
if (_dataMode == SPI_MODE0) {
|
||||||
|
digitalWrite(_sck, LOW);
|
||||||
|
digitalWrite(_mosi, send & (1<<b));
|
||||||
|
digitalWrite(_sck, HIGH);
|
||||||
|
if ((_miso != -1) && digitalRead(_miso)) {
|
||||||
|
reply |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_dataMode == SPI_MODE1) {
|
||||||
|
digitalWrite(_sck, HIGH);
|
||||||
|
digitalWrite(_mosi, send & (1<<b));
|
||||||
|
digitalWrite(_sck, LOW);
|
||||||
|
if ((_miso != -1) && digitalRead(_miso)) {
|
||||||
|
reply |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
|
||||||
|
// LSB is rare, if it happens we'll just flip the bits around for them
|
||||||
|
uint8_t temp = 0;
|
||||||
|
for (uint8_t b=0; b<8; b++) {
|
||||||
|
temp |= ((reply >> b) & 0x1) << (7-b);
|
||||||
|
}
|
||||||
|
reply = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = reply;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Transfer (send/receive) one byte over hard/soft SPI
|
||||||
|
* @param send The byte to send
|
||||||
|
* @return The byte received while transmitting
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
|
||||||
|
uint8_t data = send;
|
||||||
|
transfer(&data, 1);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer or two to the SPI device.
|
||||||
|
* @param buffer Pointer to buffer of data to write
|
||||||
|
* @param len Number of bytes from buffer to write
|
||||||
|
* @param prefix_buffer Pointer to optional array of data to write before buffer.
|
||||||
|
* @param prefix_len Number of bytes from prefix buffer to write
|
||||||
|
* @return Always returns true because there's no way to test success of SPI writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer, size_t prefix_len) {
|
||||||
|
if (_spi) {
|
||||||
|
_spi->beginTransaction(*_spiSetting);
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
// do the writing
|
||||||
|
for (size_t i=0; i<prefix_len; i++) {
|
||||||
|
transfer(prefix_buffer[i]);
|
||||||
|
}
|
||||||
|
for (size_t i=0; i<len; i++) {
|
||||||
|
transfer(buffer[i]);
|
||||||
|
}
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
if (_spi) {
|
||||||
|
_spi->endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
|
||||||
|
if ((prefix_len != 0) && (prefix_buffer != NULL)) {
|
||||||
|
for (uint16_t i=0; i<prefix_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint16_t i=0; i<len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read from SPI into a buffer from the SPI device.
|
||||||
|
* @param buffer Pointer to buffer of data to read into
|
||||||
|
* @param len Number of bytes from buffer to read.
|
||||||
|
* @param sendvalue The 8-bits of data to write when doing the data read, defaults to 0xFF
|
||||||
|
* @return Always returns true because there's no way to test success of SPI writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
|
||||||
|
memset(buffer, sendvalue, len); // clear out existing buffer
|
||||||
|
if (_spi) {
|
||||||
|
_spi->beginTransaction(*_spiSetting);
|
||||||
|
}
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
transfer(buffer, len);
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
if (_spi) {
|
||||||
|
_spi->endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
|
||||||
|
for (uint16_t i=0; i<len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write some data, then read some data from SPI into another buffer. The buffers can point to same/overlapping locations. This does not transmit-receive at the same time!
|
||||||
|
* @param write_buffer Pointer to buffer of data to write from
|
||||||
|
* @param write_len Number of bytes from buffer to write.
|
||||||
|
* @param read_buffer Pointer to buffer of data to read into.
|
||||||
|
* @param read_len Number of bytes from buffer to read.
|
||||||
|
* @param sendvalue The 8-bits of data to write when doing the data read, defaults to 0xFF
|
||||||
|
* @return Always returns true because there's no way to test success of SPI writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, uint8_t sendvalue) {
|
||||||
|
if (_spi) {
|
||||||
|
_spi->beginTransaction(*_spiSetting);
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(_cs, LOW);
|
||||||
|
// do the writing
|
||||||
|
for (size_t i=0; i<write_len; i++) {
|
||||||
|
transfer(write_buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
|
||||||
|
for (uint16_t i=0; i<write_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(write_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (write_len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// do the reading
|
||||||
|
for (size_t i=0; i<read_len; i++) {
|
||||||
|
read_buffer[i] = transfer(sendvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
|
||||||
|
for (uint16_t i=0; i<read_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(read_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (read_len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
|
||||||
|
if (_spi) {
|
||||||
|
_spi->endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
62
lib/Adafruit_BusIO/Adafruit_SPIDevice.h
Normal file
62
lib/Adafruit_BusIO/Adafruit_SPIDevice.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
#ifndef Adafruit_SPIDevice_h
|
||||||
|
#define Adafruit_SPIDevice_h
|
||||||
|
|
||||||
|
// some modern SPI definitions don't have BitOrder enum
|
||||||
|
#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || defined(ESP8266) || defined(TEENSYDUINO)
|
||||||
|
typedef enum _BitOrder {
|
||||||
|
SPI_BITORDER_MSBFIRST = MSBFIRST,
|
||||||
|
SPI_BITORDER_LSBFIRST = LSBFIRST,
|
||||||
|
} BitOrder;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// some modern SPI definitions don't have BitOrder enum and have different SPI mode defines
|
||||||
|
#if defined(ESP32)
|
||||||
|
typedef enum _BitOrder {
|
||||||
|
SPI_BITORDER_MSBFIRST = SPI_MSBFIRST,
|
||||||
|
SPI_BITORDER_LSBFIRST = SPI_LSBFIRST,
|
||||||
|
} BitOrder;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST
|
||||||
|
#if defined(ARDUINO_ARCH_SAMD) || defined(__SAM3X8E__) || defined(NRF52_SERIES) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32) || defined(ARDUINO_ARCH_MEGAAVR) || defined(_STM32_DEF_)
|
||||||
|
#define SPI_BITORDER_MSBFIRST MSBFIRST
|
||||||
|
#define SPI_BITORDER_LSBFIRST LSBFIRST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///< The class which defines how we will talk to this device over SPI
|
||||||
|
class Adafruit_SPIDevice {
|
||||||
|
public:
|
||||||
|
Adafruit_SPIDevice(int8_t cspin,
|
||||||
|
uint32_t freq=1000000,
|
||||||
|
BitOrder dataOrder=SPI_BITORDER_MSBFIRST,
|
||||||
|
uint8_t dataMode=SPI_MODE0,
|
||||||
|
SPIClass *theSPI=&SPI);
|
||||||
|
|
||||||
|
Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi,
|
||||||
|
uint32_t freq=1000000,
|
||||||
|
BitOrder dataOrder=SPI_BITORDER_MSBFIRST,
|
||||||
|
uint8_t dataMode=SPI_MODE0);
|
||||||
|
|
||||||
|
bool begin(void);
|
||||||
|
bool read(uint8_t *buffer, size_t len, uint8_t sendvalue=0xFF);
|
||||||
|
bool write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer=NULL, size_t prefix_len=0);
|
||||||
|
bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, uint8_t sendvalue=0xFF);
|
||||||
|
|
||||||
|
uint8_t transfer(uint8_t send);
|
||||||
|
void transfer(uint8_t *buffer, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SPIClass *_spi;
|
||||||
|
SPISettings *_spiSetting;
|
||||||
|
uint32_t _freq;
|
||||||
|
BitOrder _dataOrder;
|
||||||
|
uint8_t _dataMode;
|
||||||
|
|
||||||
|
int8_t _cs, _sck, _mosi, _miso;
|
||||||
|
bool _begun;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Adafruit_SPIDevice_h
|
21
lib/Adafruit_BusIO/LICENSE
Normal file
21
lib/Adafruit_BusIO/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017 Adafruit Industries
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
7
lib/Adafruit_BusIO/README.md
Normal file
7
lib/Adafruit_BusIO/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Adafruit Bus IO Library [](https://travis-ci.com/adafruit/Adafruit_BusIO)
|
||||||
|
|
||||||
|
This is a helper libary to abstract away I2C & SPI transactions and registers
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||||
|
|
||||||
|
MIT license, all text above must be included in any redistribution
|
@ -0,0 +1,21 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
|
||||||
|
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C address detection test");
|
||||||
|
|
||||||
|
if (!i2c_dev.begin()) {
|
||||||
|
Serial.print("Did not find device at 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
Serial.print("Device found on address 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
41
lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino
Normal file
41
lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x60
|
||||||
|
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C device read and write test");
|
||||||
|
|
||||||
|
if (!i2c_dev.begin()) {
|
||||||
|
Serial.print("Did not find device at 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
Serial.print("Device found on address 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
|
||||||
|
uint8_t buffer[32];
|
||||||
|
// Try to read 32 bytes
|
||||||
|
i2c_dev.read(buffer, 32);
|
||||||
|
Serial.print("Read: ");
|
||||||
|
for (uint8_t i=0; i<32; i++) {
|
||||||
|
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
// read a register by writing first, then reading
|
||||||
|
buffer[0] = 0x0C; // we'll reuse the same buffer
|
||||||
|
i2c_dev.write_then_read(buffer, 1, buffer, 2, false);
|
||||||
|
Serial.print("Write then Read: ");
|
||||||
|
for (uint8_t i=0; i<2; i++) {
|
||||||
|
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
38
lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino
Normal file
38
lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x60
|
||||||
|
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C device register test");
|
||||||
|
|
||||||
|
if (!i2c_dev.begin()) {
|
||||||
|
Serial.print("Did not find device at 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
Serial.print("Device found on address 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST);
|
||||||
|
uint16_t id;
|
||||||
|
id_reg.read(&id);
|
||||||
|
Serial.print("ID register = 0x"); Serial.println(id, HEX);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST);
|
||||||
|
uint16_t thresh;
|
||||||
|
thresh_reg.read(&thresh);
|
||||||
|
Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX);
|
||||||
|
|
||||||
|
thresh_reg.write(~thresh);
|
||||||
|
|
||||||
|
Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
|
||||||
|
// Define which interface to use by setting the unused interface to NULL!
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x5D
|
||||||
|
Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C or SPI device register test");
|
||||||
|
|
||||||
|
if (spi_dev && !spi_dev->begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i2c_dev) {
|
||||||
|
if (i2c_dev->begin()) {
|
||||||
|
Serial.print("Device found on I2C address 0x");
|
||||||
|
Serial.println(i2c_dev->address(), HEX);
|
||||||
|
} else {
|
||||||
|
Serial.print("Did not find I2C device at 0x");
|
||||||
|
Serial.println(i2c_dev->address(), HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F);
|
||||||
|
uint8_t id;
|
||||||
|
id_reg.read(&id);
|
||||||
|
Serial.print("ID register = 0x"); Serial.println(id, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
29
lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino
Normal file
29
lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
|
||||||
|
//Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI device mode test");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Serial.println("\n\nTransfer test");
|
||||||
|
for (uint16_t x=0; x<=0xFF; x++) {
|
||||||
|
uint8_t i = x;
|
||||||
|
Serial.print("0x"); Serial.print(i, HEX);
|
||||||
|
spi_dev.read(&i, 1, i);
|
||||||
|
Serial.print("/"); Serial.print(i, HEX);
|
||||||
|
Serial.print(", ");
|
||||||
|
delay(25);
|
||||||
|
}
|
||||||
|
}
|
39
lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino
Normal file
39
lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI device read and write test");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buffer[32];
|
||||||
|
|
||||||
|
// Try to read 32 bytes
|
||||||
|
spi_dev.read(buffer, 32);
|
||||||
|
Serial.print("Read: ");
|
||||||
|
for (uint8_t i=0; i<32; i++) {
|
||||||
|
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
// read a register by writing first, then reading
|
||||||
|
buffer[0] = 0x8F; // we'll reuse the same buffer
|
||||||
|
spi_dev.write_then_read(buffer, 1, buffer, 2, false);
|
||||||
|
Serial.print("Write then Read: ");
|
||||||
|
for (uint8_t i=0; i<2; i++) {
|
||||||
|
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
34
lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino
Normal file
34
lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI device register test");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD);
|
||||||
|
uint8_t id;
|
||||||
|
id_reg.read(&id);
|
||||||
|
Serial.print("ID register = 0x"); Serial.println(id, HEX);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST);
|
||||||
|
uint16_t thresh;
|
||||||
|
thresh_reg.read(&thresh);
|
||||||
|
Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX);
|
||||||
|
|
||||||
|
thresh_reg.write(~thresh);
|
||||||
|
|
||||||
|
Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
9
lib/Adafruit_BusIO/library.properties
Normal file
9
lib/Adafruit_BusIO/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=Adafruit BusIO
|
||||||
|
version=1.0.10
|
||||||
|
author=Adafruit
|
||||||
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
|
sentence=This is a library for abstracting away UART, I2C and SPI interfacing
|
||||||
|
paragraph=This is a library for abstracting away UART, I2C and SPI interfacing
|
||||||
|
category=Signal Input/Output
|
||||||
|
url=https://github.com/adafruit/Adafruit_BusIO
|
||||||
|
architectures=*
|
46
lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md
vendored
Normal file
46
lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||||
|
improve the speed of resolution please review the following guidelines and
|
||||||
|
common troubleshooting steps below before creating the issue:
|
||||||
|
|
||||||
|
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||||
|
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||||
|
something isn't working as expected. In many cases the problem is a common issue
|
||||||
|
that you will more quickly receive help from the forum community. GitHub issues
|
||||||
|
are meant for known defects in the code. If you don't know if there is a defect
|
||||||
|
in the code then start with troubleshooting on the forum first.
|
||||||
|
|
||||||
|
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||||
|
check all of the steps and commands to run have been followed. Consult the
|
||||||
|
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||||
|
|
||||||
|
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||||
|
|
||||||
|
- For uploading sketches or communicating with the board make sure you're using
|
||||||
|
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||||
|
very hard to tell the difference between a data and charge cable! Try using the
|
||||||
|
cable with other devices or swapping to another cable to confirm it is not
|
||||||
|
the problem.
|
||||||
|
|
||||||
|
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||||
|
your board and plug in an external power supply. In many cases just
|
||||||
|
plugging a board into your computer is not enough to power it and other
|
||||||
|
peripherals.
|
||||||
|
|
||||||
|
- **Double check all soldering joints and connections.** Flakey connections
|
||||||
|
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||||
|
|
||||||
|
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||||
|
guarantee a clone board will have the same functionality and work as expected
|
||||||
|
with this code and don't support them.
|
||||||
|
|
||||||
|
If you're sure this issue is a defect in the code and checked the steps above
|
||||||
|
please fill in the following fields to provide enough troubleshooting information.
|
||||||
|
You may delete the guideline and text above to just leave the following details:
|
||||||
|
|
||||||
|
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||||
|
|
||||||
|
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||||
|
VERSION HERE**
|
||||||
|
|
||||||
|
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||||
|
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
26
lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||||
|
Before you open the request please review the following guidelines and tips to
|
||||||
|
help it be more easily integrated:
|
||||||
|
|
||||||
|
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||||
|
of the code were modified.** This will help us understand any risks of integrating
|
||||||
|
the code.
|
||||||
|
|
||||||
|
- **Describe any known limitations with your change.** For example if the change
|
||||||
|
doesn't apply to a supported platform of the library please mention it.
|
||||||
|
|
||||||
|
- **Please run any tests or examples that can exercise your modified code.** We
|
||||||
|
strive to not break users of the code and running tests/examples helps with this
|
||||||
|
process.
|
||||||
|
|
||||||
|
Thank you again for contributing! We will try to test and integrate the change
|
||||||
|
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||||
|
can't immediately respond to every request. There is no need to bump or check in
|
||||||
|
on a pull request (it will clutter the discussion of the request).
|
||||||
|
|
||||||
|
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||||
|
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||||
|
priorities of the pull request. Don't fret, the open source community thrives on
|
||||||
|
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||||
|
|
||||||
|
After reviewing the guidelines above you can delete this text from the pull request.
|
8
lib/Adafruit_VEML7700/.gitignore
vendored
Normal file
8
lib/Adafruit_VEML7700/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# osx
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# doxygen
|
||||||
|
Doxyfile*
|
||||||
|
doxygen_sqlite3.db
|
||||||
|
html
|
||||||
|
*.tmp
|
26
lib/Adafruit_VEML7700/.travis.yml
Normal file
26
lib/Adafruit_VEML7700/.travis.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
language: c
|
||||||
|
sudo: false
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- ~/arduino_ide
|
||||||
|
- ~/.arduino15/packages/
|
||||||
|
git:
|
||||||
|
depth: false
|
||||||
|
quiet: true
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- PRETTYNAME="Adafruit VEML7700 Arduino Library"
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
|
||||||
|
|
||||||
|
install:
|
||||||
|
- arduino --install-library "Adafruit BusIO"
|
||||||
|
|
||||||
|
script:
|
||||||
|
- build_main_platforms
|
||||||
|
|
||||||
|
# Generate and deploy documentation
|
||||||
|
after_success:
|
||||||
|
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
|
||||||
|
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
|
322
lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp
Normal file
322
lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*!
|
||||||
|
* @file Adafruit_VEML7700.cpp
|
||||||
|
*
|
||||||
|
* @mainpage Adafruit VEML7700 I2C Lux Sensor
|
||||||
|
*
|
||||||
|
* @section intro_sec Introduction
|
||||||
|
*
|
||||||
|
* I2C Driver for the VEML7700 I2C Lux sensor
|
||||||
|
*
|
||||||
|
* This is a library for the Adafruit VEML7700 breakout:
|
||||||
|
* http://www.adafruit.com/
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing products from
|
||||||
|
* Adafruit!
|
||||||
|
*
|
||||||
|
* @section author Author
|
||||||
|
*
|
||||||
|
* Limor Fried (Adafruit Industries)
|
||||||
|
*
|
||||||
|
* @section license License
|
||||||
|
*
|
||||||
|
* BSD (see license.txt)
|
||||||
|
*
|
||||||
|
* @section HISTORY
|
||||||
|
*
|
||||||
|
* v1.0 - First release
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#include "Adafruit_VEML7700.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Instantiates a new VEML7700 class
|
||||||
|
*/
|
||||||
|
Adafruit_VEML7700::Adafruit_VEML7700(void) {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Setups the hardware for talking to the VEML7700
|
||||||
|
* @param theWire An optional pointer to an I2C interface
|
||||||
|
* @return True if initialization was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
boolean Adafruit_VEML7700::begin(TwoWire *theWire) {
|
||||||
|
i2c_dev = new Adafruit_I2CDevice(VEML7700_I2CADDR_DEFAULT, theWire);
|
||||||
|
|
||||||
|
if (!i2c_dev->begin()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALS_Config = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_CONFIG, 2, LSBFIRST);
|
||||||
|
ALS_HighThreshold = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_THREHOLD_HIGH, 2, LSBFIRST);
|
||||||
|
ALS_LowThreshold = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_THREHOLD_LOW, 2, LSBFIRST);
|
||||||
|
Power_Saving = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_POWER_SAVE, 2, LSBFIRST);
|
||||||
|
ALS_Data = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_DATA, 2, LSBFIRST);
|
||||||
|
White_Data = new Adafruit_I2CRegister(i2c_dev, VEML7700_WHITE_DATA, 2, LSBFIRST);
|
||||||
|
Interrupt_Status = new Adafruit_I2CRegister(i2c_dev, VEML7700_INTERRUPTSTATUS, 2, LSBFIRST);
|
||||||
|
|
||||||
|
ALS_Shutdown = new Adafruit_I2CRegisterBits(ALS_Config, 1, 0); // # bits, bit_shift
|
||||||
|
ALS_Interrupt_Enable = new Adafruit_I2CRegisterBits(ALS_Config, 1, 1);
|
||||||
|
ALS_Persistence = new Adafruit_I2CRegisterBits(ALS_Config, 2, 4);
|
||||||
|
ALS_Integration_Time = new Adafruit_I2CRegisterBits(ALS_Config, 4, 6);
|
||||||
|
ALS_Gain = new Adafruit_I2CRegisterBits(ALS_Config, 2, 11);
|
||||||
|
PowerSave_Enable = new Adafruit_I2CRegisterBits(Power_Saving, 1, 0);
|
||||||
|
PowerSave_Mode = new Adafruit_I2CRegisterBits(Power_Saving, 2, 1);
|
||||||
|
|
||||||
|
enable(false);
|
||||||
|
interruptEnable(false);
|
||||||
|
setPersistence(VEML7700_PERS_1);
|
||||||
|
setGain(VEML7700_GAIN_1);
|
||||||
|
setIntegrationTime(VEML7700_IT_100MS);
|
||||||
|
powerSaveEnable(false);
|
||||||
|
enable(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Adafruit_VEML7700::normalize_resolution(float value) {
|
||||||
|
// adjust for gain (1x is normalized)
|
||||||
|
switch (getGain()) {
|
||||||
|
case VEML7700_GAIN_2:
|
||||||
|
value /= 2.0; break;
|
||||||
|
case VEML7700_GAIN_1_4:
|
||||||
|
value *= 4; break;
|
||||||
|
case VEML7700_GAIN_1_8:
|
||||||
|
value *= 8; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust for integrationtime (100ms is normalized)
|
||||||
|
switch (getIntegrationTime()) {
|
||||||
|
case VEML7700_IT_25MS:
|
||||||
|
value *= 4; break;
|
||||||
|
case VEML7700_IT_50MS:
|
||||||
|
value *= 2; break;
|
||||||
|
case VEML7700_IT_200MS:
|
||||||
|
value /= 2.0; break;
|
||||||
|
case VEML7700_IT_400MS:
|
||||||
|
value /= 4.0; break;
|
||||||
|
case VEML7700_IT_800MS:
|
||||||
|
value /= 8.0; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read the calibrated lux value. See app note lux table on page 5
|
||||||
|
* @returns Floating point Lux data (ALS multiplied by 0.0576)
|
||||||
|
*/
|
||||||
|
float Adafruit_VEML7700::readLux() {
|
||||||
|
return ( normalize_resolution(ALS_Data->read()) * 0.0576); // see app note lux table on page 5
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read the lux value with correction for non-linearity at high-lux settings
|
||||||
|
* @returns Floating point Lux data (ALS multiplied by 0.0576 and corrected for high-lux settings)
|
||||||
|
*/
|
||||||
|
float Adafruit_VEML7700::readLuxNormalized() {
|
||||||
|
float lux = readLux();
|
||||||
|
|
||||||
|
// user-provided correction for non-linearities at high lux/white values:
|
||||||
|
// https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346
|
||||||
|
if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){
|
||||||
|
lux = 6.0135e-13*pow(lux,4) - 9.3924e-9*pow(lux,3) + 8.1488e-5*pow(lux,2) + 1.0023*lux;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lux;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read the raw ALS data
|
||||||
|
* @returns 16-bit data value from the ALS register
|
||||||
|
*/
|
||||||
|
uint16_t Adafruit_VEML7700::readALS() {
|
||||||
|
return ALS_Data->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read the white light data
|
||||||
|
* @returns Floating point 'white light' data multiplied by 0.0576
|
||||||
|
*/
|
||||||
|
float Adafruit_VEML7700::readWhite() {
|
||||||
|
// white_corrected= 2E-15*pow(VEML_white,4) + 4E-12*pow(VEML_white,3) + 9E-06*pow(VEML_white,)2 + 1.0179*VEML_white - 11.052;
|
||||||
|
return normalize_resolution(White_Data->read()) * 0.0576; // Unclear if this is the right multiplier
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read the 'white light' value with correction for non-linearity at high-lux settings
|
||||||
|
* @returns Floating point 'white light' data multiplied by 0.0576 and corrected for high-lux settings
|
||||||
|
*/
|
||||||
|
float Adafruit_VEML7700::readWhiteNormalized() {
|
||||||
|
float white = readWhite();
|
||||||
|
|
||||||
|
// user-provided correction for non-linearities at high lux values:
|
||||||
|
// https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346
|
||||||
|
if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){
|
||||||
|
white = 2E-15*pow(white,4) + 4E-12*pow(white,3) + 9E-06*pow(white,2) + 1.0179*white - 11.052;
|
||||||
|
}
|
||||||
|
|
||||||
|
return white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Enable or disable the sensor
|
||||||
|
* @param enable The flag to enable/disable
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::enable(bool enable) {
|
||||||
|
ALS_Shutdown->write(!enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Ask if the interrupt is enabled
|
||||||
|
* @returns True if enabled, false otherwise
|
||||||
|
*/
|
||||||
|
bool Adafruit_VEML7700::enabled(void) {
|
||||||
|
return !ALS_Shutdown->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Enable or disable the interrupt
|
||||||
|
* @param enable The flag to enable/disable
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::interruptEnable(bool enable) {
|
||||||
|
ALS_Interrupt_Enable->write(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Ask if the interrupt is enabled
|
||||||
|
* @returns True if enabled, false otherwise
|
||||||
|
*/
|
||||||
|
bool Adafruit_VEML7700::interruptEnabled(void) {
|
||||||
|
return ALS_Interrupt_Enable->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set the ALS IRQ persistance setting
|
||||||
|
* @param pers Persistance constant, can be VEML7700_PERS_1, VEML7700_PERS_2,
|
||||||
|
* VEML7700_PERS_4 or VEML7700_PERS_8
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::setPersistence(uint8_t pers) {
|
||||||
|
ALS_Persistence->write(pers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Get the ALS IRQ persistance setting
|
||||||
|
* @returns Persistance constant, can be VEML7700_PERS_1, VEML7700_PERS_2,
|
||||||
|
* VEML7700_PERS_4 or VEML7700_PERS_8
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_VEML7700::getPersistence(void) {
|
||||||
|
return ALS_Persistence->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set ALS integration time
|
||||||
|
* @param it Can be VEML7700_IT_100MS, VEML7700_IT_200MS, VEML7700_IT_400MS,
|
||||||
|
* VEML7700_IT_800MS, VEML7700_IT_50MS or VEML7700_IT_25MS
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::setIntegrationTime(uint8_t it) {
|
||||||
|
ALS_Integration_Time->write(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Get ALS integration time
|
||||||
|
* @returns IT index, can be VEML7700_IT_100MS, VEML7700_IT_200MS, VEML7700_IT_400MS,
|
||||||
|
* VEML7700_IT_800MS, VEML7700_IT_50MS or VEML7700_IT_25MS
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_VEML7700::getIntegrationTime(void) {
|
||||||
|
return ALS_Integration_Time->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set ALS gain
|
||||||
|
* @param gain Can be VEML7700_GAIN_1, VEML7700_GAIN_2, VEML7700_GAIN_1_8 or VEML7700_GAIN_1_4
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::setGain(uint8_t gain) {
|
||||||
|
ALS_Gain->write(gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Get ALS gain
|
||||||
|
* @returns Gain index, can be VEML7700_GAIN_1, VEML7700_GAIN_2, VEML7700_GAIN_1_8 or VEML7700_GAIN_1_4
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_VEML7700::getGain(void) {
|
||||||
|
return ALS_Gain->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Enable power save mode
|
||||||
|
* @param enable True if power save should be enabled
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::powerSaveEnable(bool enable) {
|
||||||
|
PowerSave_Enable->write(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Check if power save mode is enabled
|
||||||
|
* @returns True if power save is enabled
|
||||||
|
*/
|
||||||
|
bool Adafruit_VEML7700::powerSaveEnabled(void) {
|
||||||
|
return PowerSave_Enable->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Assign the power save register data
|
||||||
|
* @param mode The 16-bit data to write to VEML7700_ALS_POWER_SAVE
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::setPowerSaveMode(uint8_t mode) {
|
||||||
|
PowerSave_Mode->write(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Retrieve the power save register data
|
||||||
|
* @return 16-bit data from VEML7700_ALS_POWER_SAVE
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_VEML7700::getPowerSaveMode(void) {
|
||||||
|
return PowerSave_Mode->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Assign the low threshold register data
|
||||||
|
* @param value The 16-bit data to write to VEML7700_ALS_THREHOLD_LOW
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::setLowThreshold(uint16_t value) {
|
||||||
|
ALS_LowThreshold->write(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Retrieve the low threshold register data
|
||||||
|
* @return 16-bit data from VEML7700_ALS_THREHOLD_LOW
|
||||||
|
*/
|
||||||
|
uint16_t Adafruit_VEML7700::getLowThreshold(void) {
|
||||||
|
return ALS_LowThreshold->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Assign the high threshold register data
|
||||||
|
* @param value The 16-bit data to write to VEML7700_ALS_THREHOLD_HIGH
|
||||||
|
*/
|
||||||
|
void Adafruit_VEML7700::setHighThreshold(uint16_t value) {
|
||||||
|
ALS_HighThreshold->write(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Retrieve the high threshold register data
|
||||||
|
* @return 16-bit data from VEML7700_ALS_THREHOLD_HIGH
|
||||||
|
*/
|
||||||
|
uint16_t Adafruit_VEML7700::getHighThreshold(void) {
|
||||||
|
return ALS_HighThreshold->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Retrieve the interrupt status register data
|
||||||
|
* @return 16-bit data from VEML7700_INTERRUPTSTATUS
|
||||||
|
*/
|
||||||
|
uint16_t Adafruit_VEML7700::interruptStatus(void) {
|
||||||
|
return Interrupt_Status->read();
|
||||||
|
}
|
113
lib/Adafruit_VEML7700/Adafruit_VEML7700.h
Normal file
113
lib/Adafruit_VEML7700/Adafruit_VEML7700.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*!
|
||||||
|
* @file Adafruit_VEML7700.h
|
||||||
|
*
|
||||||
|
* I2C Driver for VEML7700 Lux sensor
|
||||||
|
*
|
||||||
|
* This is a library for the Adafruit VEML7700 breakout:
|
||||||
|
* http://www.adafruit.com/
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
*please support Adafruit and open-source hardware by purchasing products from
|
||||||
|
* Adafruit!
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* BSD license (see license.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ADAFRUIT_VEML7700_H
|
||||||
|
#define _ADAFRUIT_VEML7700_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
#include <Adafruit_I2CRegister.h>
|
||||||
|
|
||||||
|
#define VEML7700_I2CADDR_DEFAULT 0x10 ///< I2C address
|
||||||
|
|
||||||
|
#define VEML7700_ALS_CONFIG 0x00 ///< Light configuration register
|
||||||
|
#define VEML7700_ALS_THREHOLD_HIGH 0x01 ///< Light high threshold for irq
|
||||||
|
#define VEML7700_ALS_THREHOLD_LOW 0x02 ///< Light low threshold for irq
|
||||||
|
#define VEML7700_ALS_POWER_SAVE 0x03 ///< Power save regiester
|
||||||
|
#define VEML7700_ALS_DATA 0x04 ///< The light data output
|
||||||
|
#define VEML7700_WHITE_DATA 0x05 ///< The white light data output
|
||||||
|
#define VEML7700_INTERRUPTSTATUS 0x06 ///< What IRQ (if any)
|
||||||
|
|
||||||
|
#define VEML7700_INTERRUPT_HIGH 0x4000 ///< Interrupt status for high threshold
|
||||||
|
#define VEML7700_INTERRUPT_LOW 0x8000 ///< Interrupt status for low threshold
|
||||||
|
|
||||||
|
#define VEML7700_GAIN_1 0x00 ///< ALS gain 1x
|
||||||
|
#define VEML7700_GAIN_2 0x01 ///< ALS gain 2x
|
||||||
|
#define VEML7700_GAIN_1_8 0x02 ///< ALS gain 1/8x
|
||||||
|
#define VEML7700_GAIN_1_4 0x03 ///< ALS gain 1/4x
|
||||||
|
|
||||||
|
#define VEML7700_IT_100MS 0x00 ///< ALS intetgration time 100ms
|
||||||
|
#define VEML7700_IT_200MS 0x01 ///< ALS intetgration time 200ms
|
||||||
|
#define VEML7700_IT_400MS 0x02 ///< ALS intetgration time 400ms
|
||||||
|
#define VEML7700_IT_800MS 0x03 ///< ALS intetgration time 800ms
|
||||||
|
#define VEML7700_IT_50MS 0x08 ///< ALS intetgration time 50ms
|
||||||
|
#define VEML7700_IT_25MS 0x0C ///< ALS intetgration time 25ms
|
||||||
|
|
||||||
|
#define VEML7700_PERS_1 0x00 ///< ALS irq persisance 1 sample
|
||||||
|
#define VEML7700_PERS_2 0x01 ///< ALS irq persisance 2 samples
|
||||||
|
#define VEML7700_PERS_4 0x02 ///< ALS irq persisance 4 samples
|
||||||
|
#define VEML7700_PERS_8 0x03 ///< ALS irq persisance 8 samples
|
||||||
|
|
||||||
|
#define VEML7700_POWERSAVE_MODE1 0x00 ///< Power saving mode 1
|
||||||
|
#define VEML7700_POWERSAVE_MODE2 0x01 ///< Power saving mode 2
|
||||||
|
#define VEML7700_POWERSAVE_MODE3 0x02 ///< Power saving mode 3
|
||||||
|
#define VEML7700_POWERSAVE_MODE4 0x03 ///< Power saving mode 4
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Class that stores state and functions for interacting with
|
||||||
|
* VEML7700 Temp Sensor
|
||||||
|
*/
|
||||||
|
class Adafruit_VEML7700 {
|
||||||
|
public:
|
||||||
|
Adafruit_VEML7700();
|
||||||
|
boolean begin(TwoWire *theWire = &Wire);
|
||||||
|
|
||||||
|
void enable(bool enable);
|
||||||
|
bool enabled(void);
|
||||||
|
|
||||||
|
void interruptEnable(bool enable);
|
||||||
|
bool interruptEnabled(void);
|
||||||
|
void setPersistence(uint8_t pers);
|
||||||
|
uint8_t getPersistence(void);
|
||||||
|
void setIntegrationTime(uint8_t it);
|
||||||
|
uint8_t getIntegrationTime(void);
|
||||||
|
void setGain(uint8_t gain);
|
||||||
|
uint8_t getGain(void);
|
||||||
|
void powerSaveEnable(bool enable);
|
||||||
|
bool powerSaveEnabled(void);
|
||||||
|
void setPowerSaveMode(uint8_t mode);
|
||||||
|
uint8_t getPowerSaveMode(void);
|
||||||
|
|
||||||
|
void setLowThreshold(uint16_t value);
|
||||||
|
uint16_t getLowThreshold(void);
|
||||||
|
void setHighThreshold(uint16_t value);
|
||||||
|
uint16_t getHighThreshold(void);
|
||||||
|
uint16_t interruptStatus(void);
|
||||||
|
|
||||||
|
|
||||||
|
float readLux();
|
||||||
|
float readLuxNormalized();
|
||||||
|
|
||||||
|
uint16_t readALS();
|
||||||
|
float readWhite();
|
||||||
|
float readWhiteNormalized();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Adafruit_I2CRegister *ALS_Config, *ALS_Data, *White_Data,
|
||||||
|
*ALS_HighThreshold, *ALS_LowThreshold, *Power_Saving, *Interrupt_Status;
|
||||||
|
Adafruit_I2CRegisterBits *ALS_Shutdown, *ALS_Interrupt_Enable,
|
||||||
|
*ALS_Persistence, *ALS_Integration_Time, *ALS_Gain,
|
||||||
|
*PowerSave_Enable, *PowerSave_Mode;
|
||||||
|
|
||||||
|
float normalize_resolution(float value);
|
||||||
|
|
||||||
|
Adafruit_I2CDevice *i2c_dev;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
16
lib/Adafruit_VEML7700/README.md
Normal file
16
lib/Adafruit_VEML7700/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Adafruit_VEML7700 [](https://travis-ci.com/adafruit/Adafruit_VEML7700)
|
||||||
|
================
|
||||||
|
|
||||||
|
This is the Adafruit VEML7700 Lux sensor library
|
||||||
|
|
||||||
|
Tested and works great with the [Adafruit VEML7700 Breakout Board](http://www.adafruit.com/)
|
||||||
|
|
||||||
|
This chip uses I2C to communicate, 2 pins are required to interface
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Kevin Townsend/Limor Fried for Adafruit Industries.
|
||||||
|
BSD license, check license.txt for more information
|
||||||
|
All text above must be included in any redistribution
|
@ -0,0 +1,58 @@
|
|||||||
|
#include "Adafruit_VEML7700.h"
|
||||||
|
|
||||||
|
Adafruit_VEML7700 veml = Adafruit_VEML7700();
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) { delay(10); }
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("Adafruit VEML7700 Test");
|
||||||
|
|
||||||
|
if (!veml.begin()) {
|
||||||
|
Serial.println("Sensor not found");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
Serial.println("Sensor found");
|
||||||
|
|
||||||
|
veml.setGain(VEML7700_GAIN_1);
|
||||||
|
veml.setIntegrationTime(VEML7700_IT_800MS);
|
||||||
|
|
||||||
|
Serial.print(F("Gain: "));
|
||||||
|
switch (veml.getGain()) {
|
||||||
|
case VEML7700_GAIN_1: Serial.println("1"); break;
|
||||||
|
case VEML7700_GAIN_2: Serial.println("2"); break;
|
||||||
|
case VEML7700_GAIN_1_4: Serial.println("1/4"); break;
|
||||||
|
case VEML7700_GAIN_1_8: Serial.println("1/8"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print(F("Integration Time (ms): "));
|
||||||
|
switch (veml.getIntegrationTime()) {
|
||||||
|
case VEML7700_IT_25MS: Serial.println("25"); break;
|
||||||
|
case VEML7700_IT_50MS: Serial.println("50"); break;
|
||||||
|
case VEML7700_IT_100MS: Serial.println("100"); break;
|
||||||
|
case VEML7700_IT_200MS: Serial.println("200"); break;
|
||||||
|
case VEML7700_IT_400MS: Serial.println("400"); break;
|
||||||
|
case VEML7700_IT_800MS: Serial.println("800"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//veml.powerSaveEnable(true);
|
||||||
|
//veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4);
|
||||||
|
|
||||||
|
veml.setLowThreshold(10000);
|
||||||
|
veml.setHighThreshold(20000);
|
||||||
|
veml.interruptEnable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Serial.print("Lux: "); Serial.println(veml.readLux());
|
||||||
|
Serial.print("White: "); Serial.println(veml.readWhite());
|
||||||
|
Serial.print("Raw ALS: "); Serial.println(veml.readALS());
|
||||||
|
|
||||||
|
uint16_t irq = veml.interruptStatus();
|
||||||
|
if (irq & VEML7700_INTERRUPT_LOW) {
|
||||||
|
Serial.println("** Low threshold");
|
||||||
|
}
|
||||||
|
if (irq & VEML7700_INTERRUPT_HIGH) {
|
||||||
|
Serial.println("** High threshold");
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
}
|
9
lib/Adafruit_VEML7700/library.properties
Normal file
9
lib/Adafruit_VEML7700/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=Adafruit VEML7700 Library
|
||||||
|
version=1.0.0
|
||||||
|
author=Adafruit
|
||||||
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
|
sentence=Arduino library for the VEML7700 sensors in the Adafruit shop
|
||||||
|
paragraph=Arduino library for the VEML7700 sensors in the Adafruit shop
|
||||||
|
category=Sensors
|
||||||
|
url=https://github.com/adafruit/Adafruit_VEML7700
|
||||||
|
architectures=*
|
26
lib/Adafruit_VEML7700/license.txt
Normal file
26
lib/Adafruit_VEML7700/license.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Software License Agreement (BSD License)
|
||||||
|
|
||||||
|
Copyright (c) 2012, Adafruit Industries
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the copyright holders nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -585,6 +585,16 @@
|
|||||||
// Commands xsns_02_analog.ino
|
// Commands xsns_02_analog.ino
|
||||||
#define D_CMND_ADCPARAM "AdcParam"
|
#define D_CMND_ADCPARAM "AdcParam"
|
||||||
|
|
||||||
|
// xsns_70_veml6075.ino
|
||||||
|
#define D_JSON_UVA_INTENSITY "UvaIntensity"
|
||||||
|
#define D_JSON_UVB_INTENSITY "UvbItensity"
|
||||||
|
#define D_CMND_VEML6075_POWER "power"
|
||||||
|
#define D_CMND_VEML6075_DYNAMIC "dynamic"
|
||||||
|
#define D_CMND_VEML6075_INTTIME "inttime"
|
||||||
|
|
||||||
|
// xsns_71_veml7700.ino
|
||||||
|
#define D_JSON_WHITE_CONTENT "WhiteContent"
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
// Log message prefix
|
// Log message prefix
|
||||||
|
@ -516,6 +516,8 @@
|
|||||||
// #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code)
|
// #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code)
|
||||||
// #define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code)
|
// #define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code)
|
||||||
// #define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code)
|
// #define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code)
|
||||||
|
// #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code)
|
||||||
|
// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code)
|
||||||
|
|
||||||
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
|
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
|
||||||
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
|
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
|
||||||
|
@ -563,10 +563,13 @@ void GetFeatures(void)
|
|||||||
#ifdef USE_THERMOSTAT
|
#ifdef USE_THERMOSTAT
|
||||||
feature6 |= 0x00000400; // xdrv_39_heating.ino
|
feature6 |= 0x00000400; // xdrv_39_heating.ino
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_VEML6075
|
||||||
|
feature6 |= 0x00000800; // xsns_70_veml6075.ino
|
||||||
|
#endif
|
||||||
|
#ifdef USE_VEML7700
|
||||||
|
feature6 |= 0x00001000; // xsns_71_veml7700.ino
|
||||||
|
#endif
|
||||||
|
|
||||||
// feature6 |= 0x00000800;
|
|
||||||
|
|
||||||
// feature6 |= 0x00001000;
|
|
||||||
// feature6 |= 0x00002000;
|
// feature6 |= 0x00002000;
|
||||||
// feature6 |= 0x00004000;
|
// feature6 |= 0x00004000;
|
||||||
// feature6 |= 0x00008000;
|
// feature6 |= 0x00008000;
|
||||||
|
306
tasmota/xsns_70_veml6075.ino
Normal file
306
tasmota/xsns_70_veml6075.ino
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
xsns_70_veml6075.ino - VEML6075 Franklin Lightning Sensor support for Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2020 Martin Wagner
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
#ifdef USE_VEML6075
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* VEML6075 UVA/UVB/UVINDEX Sensor
|
||||||
|
*
|
||||||
|
* I2C Address: 0x10
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#define XSNS_70 70
|
||||||
|
#define XI2C_49 49 // See I2CDEVICES.md
|
||||||
|
|
||||||
|
|
||||||
|
#define VEML6075_ADDR 0x10 // I2C address
|
||||||
|
#define VEML6075_CHIP_ID 0x26 // Manufacture ID
|
||||||
|
|
||||||
|
// I2C register
|
||||||
|
#define VEML6075_REG_CONF 0x00 // Configuration register
|
||||||
|
#define VEML6075_REG_UVA 0x07 // UVA band raw measurement
|
||||||
|
#define VEML6075_REG_DARK 0x08 // Dark current (?) measurement
|
||||||
|
#define VEML6075_REG_UVB 0x09 // UVB band raw measurement
|
||||||
|
#define VEML6075_REG_UVCOMP1 0x0A // UV1 compensation value
|
||||||
|
#define VEML6075_REG_UVCOMP2 0x0B // UV2 compensation value
|
||||||
|
#define VEML6075_REG_ID 0x0C // ID Register
|
||||||
|
|
||||||
|
// global constants for Calc
|
||||||
|
#define VEML6075_DEFAULT_UVA_A_COEFF 2.22 // Default for no coverglass
|
||||||
|
#define VEML6075_DEFAULT_UVA_B_COEFF 1.33 // Default for no coverglass
|
||||||
|
#define VEML6075_DEFAULT_UVB_C_COEFF 2.95 // Default for no coverglass
|
||||||
|
#define VEML6075_DEFAULT_UVB_D_COEFF 1.74 // Default for no coverglass
|
||||||
|
#define UVA_RESPONSIVITY_100MS_UNCOVERED 0.001461 // Default for no coverglass
|
||||||
|
#define UVB_RESPONSIVITY_100MS_UNCOVERED 0.002591 // Default for no coverglass
|
||||||
|
|
||||||
|
const float UVA_RESPONSIVITY[] PROGMEM =
|
||||||
|
{
|
||||||
|
UVA_RESPONSIVITY_100MS_UNCOVERED / 0.5016286645, // 50ms
|
||||||
|
UVA_RESPONSIVITY_100MS_UNCOVERED, // 100ms
|
||||||
|
UVA_RESPONSIVITY_100MS_UNCOVERED / 2.039087948, // 200ms
|
||||||
|
UVA_RESPONSIVITY_100MS_UNCOVERED / 3.781758958, // 400ms
|
||||||
|
UVA_RESPONSIVITY_100MS_UNCOVERED / 7.371335505 // 800ms
|
||||||
|
};
|
||||||
|
|
||||||
|
const float UVB_RESPONSIVITY[] PROGMEM =
|
||||||
|
{
|
||||||
|
UVB_RESPONSIVITY_100MS_UNCOVERED / 0.5016286645, // 50ms
|
||||||
|
UVB_RESPONSIVITY_100MS_UNCOVERED, // 100ms
|
||||||
|
UVB_RESPONSIVITY_100MS_UNCOVERED / 2.039087948, // 200ms
|
||||||
|
UVB_RESPONSIVITY_100MS_UNCOVERED / 3.781758958, // 400ms
|
||||||
|
UVB_RESPONSIVITY_100MS_UNCOVERED / 7.371335505 // 800ms
|
||||||
|
};
|
||||||
|
|
||||||
|
// http and json defines
|
||||||
|
#define D_NAME_VEML6075 "VEML6075"
|
||||||
|
#define D_UVA_INTENSITY "UVA intensity"
|
||||||
|
#define D_UVB_INTENSITY "UVB intensity"
|
||||||
|
|
||||||
|
const char HTTP_SNS_UVA[] PROGMEM = "{s}%s " D_UVA_INTENSITY "{m}%d " D_UNIT_WATT_METER_QUADRAT "{e}";
|
||||||
|
const char HTTP_SNS_UVB[] PROGMEM = "{s}%s " D_UVB_INTENSITY "{m}%d " D_UNIT_WATT_METER_QUADRAT "{e}";
|
||||||
|
const char HTTP_SNS_UVINDEX[] PROGMEM = "{s}%s " D_UV_INDEX "{m}%s {e}";
|
||||||
|
const char JSON_SNS_VEML6075[] PROGMEM = ",\"%s\":{\"" D_JSON_UVA_INTENSITY "\":%d,\"" D_JSON_UVB_INTENSITY "\":%d,\"" D_JSON_UV_INDEX "\":%s}";
|
||||||
|
const char S_JSON_VEML6075_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_VEML6075 "\":{\"%s\":%d}}";
|
||||||
|
|
||||||
|
const char kVEML6075_Commands[] PROGMEM = D_CMND_VEML6075_POWER "|" D_CMND_VEML6075_DYNAMIC "|" D_CMND_VEML6075_INTTIME;
|
||||||
|
|
||||||
|
enum VEML6075_Commands { // commands for Console
|
||||||
|
CMND_VEML6075_PWR,
|
||||||
|
CMND_VEML6075_SET_HD,
|
||||||
|
CMND_VEML6075_SET_UVIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
// global variables
|
||||||
|
struct VEML6075STRUCT
|
||||||
|
{
|
||||||
|
char types[9] = D_NAME_VEML6075;
|
||||||
|
uint8_t address = VEML6075_ADDR;
|
||||||
|
uint8_t inttime = 0;
|
||||||
|
uint16_t uva = 0;
|
||||||
|
uint16_t uvb = 0;
|
||||||
|
uint16_t uva_raw = 0;
|
||||||
|
uint16_t uvb_raw = 0;
|
||||||
|
uint16_t comp1 = 0;
|
||||||
|
uint16_t comp2 = 0;
|
||||||
|
uint16_t conf = 0;
|
||||||
|
float uvi = 0.0f;
|
||||||
|
} veml6075_sensor;
|
||||||
|
|
||||||
|
uint8_t veml6075_active = 0;
|
||||||
|
|
||||||
|
// typedef of config register
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint8_t pwr:1; // Shut Down
|
||||||
|
uint8_t forded_auto:1; // Auto or forced
|
||||||
|
uint8_t forced_trigger:1; // Trigger forced mode
|
||||||
|
uint8_t hd:1; // High dynamic
|
||||||
|
uint8_t inttime:3; // Integration Time
|
||||||
|
uint8_t spare7:1; // spare
|
||||||
|
};
|
||||||
|
uint16_t config;
|
||||||
|
} veml6075configRegister;
|
||||||
|
|
||||||
|
veml6075configRegister veml6075Config;
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
uint16_t VEML6075read16 (uint8_t reg) {
|
||||||
|
uint16_t swap = I2cRead16(VEML6075_ADDR, reg);
|
||||||
|
uint16_t ret = ((swap & 0xFF) << 8) | (swap >> 8);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075write16 (uint8_t reg, uint16_t val) {
|
||||||
|
uint16_t swap = ((val & 0xFF) << 8) | (val >> 8);
|
||||||
|
I2cWrite16(VEML6075_ADDR, reg, swap);
|
||||||
|
}
|
||||||
|
|
||||||
|
float VEML6075calcUVA (void) {
|
||||||
|
float uva_calc = veml6075_sensor.uva_raw - (VEML6075_DEFAULT_UVA_A_COEFF * veml6075_sensor.comp1) - (VEML6075_DEFAULT_UVA_B_COEFF * veml6075_sensor.comp2);
|
||||||
|
return uva_calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
float VEML6075calcUVB (void) {
|
||||||
|
float uvb_calc = veml6075_sensor.uvb_raw - (VEML6075_DEFAULT_UVB_C_COEFF * veml6075_sensor.comp1) - (VEML6075_DEFAULT_UVB_D_COEFF * veml6075_sensor.comp2);
|
||||||
|
return uvb_calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
float VEML6075calcUVI (void) {
|
||||||
|
float uvi_calc = ((veml6075_sensor.uva * UVA_RESPONSIVITY[veml6075_sensor.inttime]) + (veml6075_sensor.uvb * UVB_RESPONSIVITY[veml6075_sensor.inttime])) / 2;
|
||||||
|
return uvi_calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075SetHD(uint8_t val){
|
||||||
|
veml6075Config.hd = val;
|
||||||
|
VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t VEML6075ReadHD(void){
|
||||||
|
veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF);
|
||||||
|
return veml6075Config.hd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075SetUvIt(uint8_t val){
|
||||||
|
veml6075Config.inttime = val;
|
||||||
|
VEML6075Pwr(1);
|
||||||
|
VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config);
|
||||||
|
VEML6075Pwr(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t VEML6075GetUvIt(void){
|
||||||
|
veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF);
|
||||||
|
return veml6075Config.inttime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075Pwr(uint8_t val){
|
||||||
|
veml6075Config.pwr = val;
|
||||||
|
VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t VEML6075GetPwr(void){
|
||||||
|
veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF);
|
||||||
|
return veml6075Config.pwr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075ReadData(void)
|
||||||
|
{
|
||||||
|
veml6075_sensor.uva_raw = VEML6075read16 (VEML6075_REG_UVA);
|
||||||
|
veml6075_sensor.uvb_raw = VEML6075read16 (VEML6075_REG_UVB);
|
||||||
|
veml6075_sensor.comp1 = VEML6075read16 (VEML6075_REG_UVCOMP1);
|
||||||
|
veml6075_sensor.comp2 = VEML6075read16 (VEML6075_REG_UVCOMP2);
|
||||||
|
veml6075_sensor.inttime = VEML6075GetUvIt();
|
||||||
|
veml6075_sensor.uva = VEML6075calcUVA();
|
||||||
|
veml6075_sensor.uvb = VEML6075calcUVB();
|
||||||
|
veml6075_sensor.uvi = VEML6075calcUVI();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VEML6075init(void)
|
||||||
|
{
|
||||||
|
uint8_t id = VEML6075read16 (VEML6075_REG_ID);
|
||||||
|
if(id == VEML6075_CHIP_ID) // Sensor id
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075Detect(void) {
|
||||||
|
if (I2cActive(veml6075_sensor.address)) return;
|
||||||
|
|
||||||
|
if (VEML6075init()) {
|
||||||
|
I2cSetActiveFound(veml6075_sensor.address, veml6075_sensor.types);
|
||||||
|
VEML6075write16 (VEML6075_REG_CONF, 0x10); // set default
|
||||||
|
veml6075_active = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075EverySecond(void) {
|
||||||
|
VEML6075ReadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VEML6075Cmd(void) {
|
||||||
|
char command[CMDSZ];
|
||||||
|
uint8_t name_len = strlen(D_NAME_VEML6075);
|
||||||
|
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_VEML6075), name_len)) {
|
||||||
|
uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kVEML6075_Commands);
|
||||||
|
switch (command_code) {
|
||||||
|
case CMND_VEML6075_PWR:
|
||||||
|
if (XdrvMailbox.data_len) {
|
||||||
|
if (2 >= XdrvMailbox.payload) {
|
||||||
|
VEML6075Pwr(XdrvMailbox.payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075GetPwr());
|
||||||
|
break;
|
||||||
|
case CMND_VEML6075_SET_HD:
|
||||||
|
if (XdrvMailbox.data_len) {
|
||||||
|
if (2 >= XdrvMailbox.payload) {
|
||||||
|
VEML6075SetHD(XdrvMailbox.payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075ReadHD());
|
||||||
|
break;
|
||||||
|
case CMND_VEML6075_SET_UVIT:
|
||||||
|
if (XdrvMailbox.data_len) {
|
||||||
|
if (4 >= XdrvMailbox.payload) {
|
||||||
|
VEML6075SetUvIt(XdrvMailbox.payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075GetUvIt());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML6075Show(bool json)
|
||||||
|
{
|
||||||
|
char s_uvindex[FLOATSZ];
|
||||||
|
dtostrfd(veml6075_sensor.uvi,1, s_uvindex);
|
||||||
|
|
||||||
|
if (json) {
|
||||||
|
ResponseAppend_P(JSON_SNS_VEML6075, D_NAME_VEML6075, veml6075_sensor.uva, veml6075_sensor.uvb, s_uvindex);
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
} else {
|
||||||
|
WSContentSend_PD(HTTP_SNS_UVA, D_NAME_VEML6075, veml6075_sensor.uva);
|
||||||
|
WSContentSend_PD(HTTP_SNS_UVB, D_NAME_VEML6075, veml6075_sensor.uvb);
|
||||||
|
WSContentSend_PD(HTTP_SNS_UVINDEX, D_NAME_VEML6075 ,s_uvindex);
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool Xsns70(uint8_t function)
|
||||||
|
{
|
||||||
|
if (!I2cEnabled(XI2C_49)) { return false; }
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (FUNC_INIT == function) {
|
||||||
|
VEML6075Detect();
|
||||||
|
}
|
||||||
|
else if (veml6075_active) {
|
||||||
|
switch (function) {
|
||||||
|
case FUNC_EVERY_SECOND:
|
||||||
|
VEML6075EverySecond();
|
||||||
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = VEML6075Cmd();
|
||||||
|
break;
|
||||||
|
case FUNC_JSON_APPEND:
|
||||||
|
VEML6075Show(1);
|
||||||
|
break;
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
case FUNC_WEB_SENSOR:
|
||||||
|
VEML6075Show(0);
|
||||||
|
break;
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_VEML6075
|
||||||
|
#endif // USE_I2C
|
117
tasmota/xsns_71_veml7700.ino
Normal file
117
tasmota/xsns_71_veml7700.ino
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
xsns_71_VEML7700.ino - VEML7700 Franklin Lightning Sensor support for Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2020 Martin Wagner
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
#ifdef USE_VEML7700
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* VEML7700 ALS Sensor
|
||||||
|
* Using the Adafruit VEML7700 Libary
|
||||||
|
* I2C Address: 0x10
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#define XSNS_71 71
|
||||||
|
#define XI2C_50 50 // See I2CDEVICES.md
|
||||||
|
|
||||||
|
#include "Adafruit_VEML7700.h"
|
||||||
|
Adafruit_VEML7700 veml7700 = Adafruit_VEML7700(); //create object copy
|
||||||
|
|
||||||
|
#define D_NAME_VEML7700 "VEML7700"
|
||||||
|
#define D_WHITE_CONTENT "White content"
|
||||||
|
|
||||||
|
const char HTTP_SNS_LUX[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX " {e}";
|
||||||
|
const char HTTP_SNS_WHITE[] PROGMEM = "{s}%s " D_WHITE_CONTENT "{m}%d {e}";
|
||||||
|
const char JSON_SNS_VEML7700[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_WHITE_CONTENT "\":%d}";
|
||||||
|
|
||||||
|
struct VEML7700STRUCT
|
||||||
|
{
|
||||||
|
char types[9] = D_NAME_VEML7700;
|
||||||
|
uint8_t address = VEML7700_I2CADDR_DEFAULT;
|
||||||
|
uint16_t lux = 0;
|
||||||
|
uint16_t white = 0;
|
||||||
|
} veml7700_sensor;
|
||||||
|
|
||||||
|
uint8_t veml7700_active = 0;
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
void VEML7700Detect(void) {
|
||||||
|
if (I2cActive(veml7700_sensor.address)) return;
|
||||||
|
if (veml7700.begin()) {
|
||||||
|
I2cSetActiveFound(veml7700_sensor.address, veml7700_sensor.types);
|
||||||
|
veml7700_active = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML7700EverySecond(void) {
|
||||||
|
veml7700_sensor.lux = (uint16_t) veml7700.readLux();
|
||||||
|
veml7700_sensor.white = (uint16_t) veml7700.readWhite();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEML7700Show(bool json)
|
||||||
|
{
|
||||||
|
if (json) {
|
||||||
|
ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux, veml7700_sensor.white);
|
||||||
|
|
||||||
|
#ifdef USE_DOMOTICZ
|
||||||
|
if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux);
|
||||||
|
#endif // USE_DOMOTICZ
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
} else {
|
||||||
|
WSContentSend_PD(HTTP_SNS_LUX, D_NAME_VEML7700, veml7700_sensor.lux);
|
||||||
|
WSContentSend_PD(HTTP_SNS_WHITE, D_NAME_VEML7700, veml7700_sensor.white);
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool Xsns71(uint8_t function)
|
||||||
|
{
|
||||||
|
if (!I2cEnabled(XI2C_50)) { return false; }
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (FUNC_INIT == function) {
|
||||||
|
VEML7700Detect();
|
||||||
|
}
|
||||||
|
else if (veml7700_active) {
|
||||||
|
switch (function) {
|
||||||
|
case FUNC_EVERY_SECOND:
|
||||||
|
VEML7700EverySecond();
|
||||||
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
//result = VEML7700Cmd();
|
||||||
|
break;
|
||||||
|
case FUNC_JSON_APPEND:
|
||||||
|
VEML7700Show(1);
|
||||||
|
break;
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
case FUNC_WEB_SENSOR:
|
||||||
|
VEML7700Show(0);
|
||||||
|
break;
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_VEML7700
|
||||||
|
#endif // USE_I2C
|
Loading…
x
Reference in New Issue
Block a user