mirror of https://github.com/arendst/Tasmota.git
Merge pull request #8432 from device111/development
Support for VEML6075 and initial Support for VEML7700
This commit is contained in:
commit
2b798ff194
|
@ -69,4 +69,6 @@ Index | Define | Driver | Device | Address(es) | Description
|
|||
45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor
|
||||
46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor
|
||||
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
|
|
@ -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)
|
|
@ -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; }
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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.
|
|
@ -0,0 +1,7 @@
|
|||
# Adafruit Bus IO Library [![Build Status](https://travis-ci.com/adafruit/Adafruit_BusIO.svg?branch=master)](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() {
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
||||
}
|
|
@ -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=*
|
|
@ -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**
|
|
@ -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.
|
|
@ -0,0 +1,8 @@
|
|||
# osx
|
||||
.DS_Store
|
||||
|
||||
# doxygen
|
||||
Doxyfile*
|
||||
doxygen_sqlite3.db
|
||||
html
|
||||
*.tmp
|
|
@ -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)
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,16 @@
|
|||
Adafruit_VEML7700 [![Build Status](https://travis-ci.com/adafruit/Adafruit_VEML7700.svg?branch=master)](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);
|
||||
}
|
|
@ -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=*
|
|
@ -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.
|
|
@ -586,6 +586,16 @@
|
|||
// Commands xsns_02_analog.ino
|
||||
#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
|
||||
|
|
|
@ -516,6 +516,8 @@
|
|||
// #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_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_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
|
||||
|
|
|
@ -563,10 +563,13 @@ void GetFeatures(void)
|
|||
#ifdef USE_THERMOSTAT
|
||||
feature6 |= 0x00000400; // xdrv_39_heating.ino
|
||||
#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 |= 0x00004000;
|
||||
// feature6 |= 0x00008000;
|
||||
|
|
|
@ -83,6 +83,8 @@
|
|||
#define USE_BME680 // Add additional support for BME680 sensor using Bosch BME680 library (+4k code)
|
||||
#define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code)
|
||||
#define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code)
|
||||
// #define USE_VEML6075 // Add I2C code for VEML6075 UVA/UVB/UVINDEX Sensor (+2k1 code)
|
||||
// #define USE_VEML7700 // Add I2C code for VEML7700 Ambient Light sensor (+4k5 code)
|
||||
#define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code)
|
||||
#define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
|
||||
//#define USE_INA226 // Enable INA226 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+2k3 code)
|
||||
|
|
|
@ -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
|
|
@ -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…
Reference in New Issue