5.9.1 20171107
 * Add external sensor function pointer interface to
enable easy sensor addition
 * Add support for ADS1115 to be enabled in
user_config.h and needs libraries i2cdevlib-Core and i2cdevlib-ADS1115
(#338, #660)
 * Fix Backup Configuration file download failure by
defining proper file size (#1115)
 * Fix Exception 26 and empty console
screen after usage of command WakeupDuration (#1133)
 * Fix some changed
iTead web links in README.md (#1137)
This commit is contained in:
arendst 2017-11-07 16:25:11 +01:00
parent e08d96acc2
commit fe2d7c63ec
37 changed files with 3994 additions and 687 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
Current version is **5.9.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
Current version is **5.9.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
### ATTENTION All versions
@ -33,23 +33,23 @@ See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki) for more information.
See [Community](https://groups.google.com/d/forum/sonoffusers) for forum and more user experience.
The following devices are supported:
- [iTead Sonoff Basic](http://sonoff.itead.cc/en/products/sonoff/sonoff-basic)
- [iTead Sonoff RF](http://sonoff.itead.cc/en/products/sonoff/sonoff-rf)
- [iTead Sonoff SV](https://www.itead.cc/sonoff-sv.html)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff_th.jpg" width="250" align="right" />
- [iTead Sonoff TH10/TH16 with temperature sensor](http://sonoff.itead.cc/en/products/sonoff/sonoff-th)
- [iTead Sonoff Dual](http://sonoff.itead.cc/en/products/sonoff/sonoff-dual)
- [iTead Sonoff Pow](http://sonoff.itead.cc/en/products/sonoff/sonoff-pow)
- [iTead Sonoff 4CH](http://sonoff.itead.cc/en/products/sonoff/sonoff-4ch)
- [iTead Sonoff 4CH Pro](http://sonoff.itead.cc/en/products/sonoff/sonoff-4ch-pro)
- [iTead S20 Smart Socket](http://sonoff.itead.cc/en/products/residential/s20-socket)
- [iTead Slampher](http://sonoff.itead.cc/en/products/residential/slampher-rf)
- [iTead Sonoff Touch](http://sonoff.itead.cc/en/products/residential/sonoff-touch)
- [iTead Sonoff T1](http://sonoff.itead.cc/en/products/residential/sonoff-t1)
- [iTead Sonoff SC](http://sonoff.itead.cc/en/products/residential/sonoff-sc)
- [iTead Sonoff Led](http://sonoff.itead.cc/en/products/appliances/sonoff-led)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff4ch.jpg" height="250" align="right" />
- [iTead Sonoff BN-SZ01 Ceiling Led](http://sonoff.itead.cc/en/products/appliances/bn-sz01)
- [iTead Sonoff B1](http://sonoff.itead.cc/en/products/residential/sonoff-b1)
- [iTead Sonoff RF Bridge 433](http://sonoff.itead.cc/en/products/appliances/sonoff-rf-bridge-433)
- [iTead Sonoff Basic](https://www.itead.cc/smart-home/sonoff-wifi-wireless-switch-1.html)
- [iTead Sonoff RF](https://www.itead.cc/smart-home/sonoff-rf.html)
- [iTead Sonoff SV](https://www.itead.cc/smart-home/sonoff-sv.html)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff_th.jpg" width="250" align="right" />
- [iTead Sonoff TH10/TH16 with temperature sensor](https://www.itead.cc/smart-home/sonoff-th.html)
- [iTead Sonoff Dual](https://www.itead.cc/smart-home/sonoff-dual.html)
- [iTead Sonoff Pow](https://www.itead.cc/smart-home/sonoff-pow.html)
- [iTead Sonoff 4CH](https://www.itead.cc/smart-home/sonoff-4ch.html)
- [iTead Sonoff 4CH Pro](https://www.itead.cc/smart-home/sonoff-4ch-pro.html)
- [iTead S20 Smart Socket](https://www.itead.cc/smart-socket.html)
- [iTead Slampher](https://www.itead.cc/slampher.html)
- [iTead Sonoff Touch](https://www.itead.cc/sonoff-touch-eu-local.html)
- [iTead Sonoff T1](https://www.itead.cc/sonoff-t1.html)
- [iTead Sonoff SC](https://www.itead.cc/sonoff-sc.html)
- [iTead Sonoff Led](https://www.itead.cc/sonoff-led.html)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff4ch.jpg" height="250" align="right" />
- [iTead Sonoff BN-SZ01 Ceiling Led](https://www.itead.cc/bn-sz01.html)
- [iTead Sonoff B1](https://www.itead.cc/sonoff-b1.html)
- [iTead Sonoff RF Bridge 433](https://www.itead.cc/sonoff-rf-bridge-433.html)
- [iTead Sonoff Dev](https://www.itead.cc/sonoff-dev.html)
- [iTead 1 Channel Switch 5V / 12V](https://www.itead.cc/smart-home/inching-self-locking-wifi-wireless-switch.html)
- [iTead Motor Clockwise/Anticlockwise](https://www.itead.cc/smart-home/motor-reversing-wifi-wireless-switch.html)

View File

@ -0,0 +1,40 @@
{
"name": "I2Cdevlib-ADS1115",
"repository": {
"url": "https://github.com/jrowberg/i2cdevlib.git",
"type": "git"
},
"platforms": [
"atmelavr"
],
"frameworks": [
"arduino"
],
"dependencies": {
"frameworks": "arduino",
"name": "I2Cdevlib-Core"
},
"export": {
"include": "Arduino/ADS1115"
},
"version": "3b4c8bda90",
"authors": [
{
"maintainer": false,
"name": "Jeff Rowberg",
"url": "https://github.com/jrowberg",
"email": "jeff@rowberg.net"
}
],
"keywords": [
"i2c",
"comparator",
"reference",
"pga",
"oscillator",
"mux",
"i2cdevlib"
],
"id": 95,
"description": "ADS1115 is 16-Bit ADC with Integrated MUX, PGA, Comparator, Oscillator, and Reference"
}

View File

@ -0,0 +1,649 @@
// I2Cdev library collection - ADS1115 I2C device class
// Based on Texas Instruments ADS1113/4/5 datasheet, May 2009 (SBAS444B, revised October 2009)
// Note that the ADS1115 uses 16-bit registers, not 8-bit registers.
// 8/2/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-05 - Add debug information. Rename methods to match datasheet.
// 2011-11-06 - added getVoltage, F. Farzanegan
// 2011-10-29 - added getDifferentialx() methods, F. Farzanegan
// 2011-08-02 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
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.
===============================================
*/
#include "ADS1115.h"
/** Default constructor, uses default I2C address.
* @see ADS1115_DEFAULT_ADDRESS
*/
ADS1115::ADS1115() {
devAddr = ADS1115_DEFAULT_ADDRESS;
}
/** Specific address constructor.
* @param address I2C address
* @see ADS1115_DEFAULT_ADDRESS
* @see ADS1115_ADDRESS_ADDR_GND
* @see ADS1115_ADDRESS_ADDR_VDD
* @see ADS1115_ADDRESS_ADDR_SDA
* @see ADS1115_ADDRESS_ADDR_SDL
*/
ADS1115::ADS1115(uint8_t address) {
devAddr = address;
}
/** Power on and prepare for general usage.
* This device is ready to use automatically upon power-up. It defaults to
* single-shot read mode, P0/N1 mux, 2.048v gain, 128 samples/sec, default
* comparator with hysterysis, active-low polarity, non-latching comparator,
* and comparater-disabled operation.
*/
void ADS1115::initialize() {
setMultiplexer(ADS1115_MUX_P0_N1);
setGain(ADS1115_PGA_2P048);
setMode(ADS1115_MODE_SINGLESHOT);
setRate(ADS1115_RATE_128);
setComparatorMode(ADS1115_COMP_MODE_HYSTERESIS);
setComparatorPolarity(ADS1115_COMP_POL_ACTIVE_LOW);
setComparatorLatchEnabled(ADS1115_COMP_LAT_NON_LATCHING);
setComparatorQueueMode(ADS1115_COMP_QUE_DISABLE);
}
/** Verify the I2C connection.
* Make sure the device is connected and responds as expected.
* @return True if connection is valid, false otherwise
*/
bool ADS1115::testConnection() {
return I2Cdev::readWord(devAddr, ADS1115_RA_CONVERSION, buffer) == 1;
}
/** Poll the operational status bit until the conversion is finished
* Retry at most 'max_retries' times
* conversion is finished, then return true;
* @see ADS1115_CFG_OS_BIT
* @return True if data is available, false otherwise
*/
bool ADS1115::pollConversion(uint16_t max_retries) {
for(uint16_t i = 0; i < max_retries; i++) {
if (isConversionReady()) return true;
}
return false;
}
/** Read differential value based on current MUX configuration.
* The default MUX setting sets the device to get the differential between the
* AIN0 and AIN1 pins. There are 8 possible MUX settings, but if you are using
* all four input pins as single-end voltage sensors, then the default option is
* not what you want; instead you will need to set the MUX to compare the
* desired AIN* pin with GND. There are shortcut methods (getConversion*) to do
* this conveniently, but you can also do it manually with setMultiplexer()
* followed by this method.
*
* In single-shot mode, this register may not have fresh data. You need to write
* a 1 bit to the MSB of the CONFIG register to trigger a single read/conversion
* before this will be populated with fresh data. This technique is not as
* effortless, but it has enormous potential to save power by only running the
* comparison circuitry when needed.
*
* @param triggerAndPoll If true (and only in singleshot mode) the conversion trigger
* will be executed and the conversion results will be polled.
* @return 16-bit signed differential value
* @see getConversionP0N1();
* @see getConversionPON3();
* @see getConversionP1N3();
* @see getConversionP2N3();
* @see getConversionP0GND();
* @see getConversionP1GND();
* @see getConversionP2GND();
* @see getConversionP3GND);
* @see setMultiplexer();
* @see ADS1115_RA_CONVERSION
* @see ADS1115_MUX_P0_N1
* @see ADS1115_MUX_P0_N3
* @see ADS1115_MUX_P1_N3
* @see ADS1115_MUX_P2_N3
* @see ADS1115_MUX_P0_NG
* @see ADS1115_MUX_P1_NG
* @see ADS1115_MUX_P2_NG
* @see ADS1115_MUX_P3_NG
*/
int16_t ADS1115::getConversion(bool triggerAndPoll) {
if (triggerAndPoll && devMode == ADS1115_MODE_SINGLESHOT) {
triggerConversion();
pollConversion(I2CDEV_DEFAULT_READ_TIMEOUT);
}
I2Cdev::readWord(devAddr, ADS1115_RA_CONVERSION, buffer);
return buffer[0];
}
/** Get AIN0/N1 differential.
* This changes the MUX setting to AIN0/N1 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP0N1() {
if (muxMode != ADS1115_MUX_P0_N1) setMultiplexer(ADS1115_MUX_P0_N1);
return getConversion();
}
/** Get AIN0/N3 differential.
* This changes the MUX setting to AIN0/N3 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP0N3() {
if (muxMode != ADS1115_MUX_P0_N3) setMultiplexer(ADS1115_MUX_P0_N3);
return getConversion();
}
/** Get AIN1/N3 differential.
* This changes the MUX setting to AIN1/N3 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP1N3() {
if (muxMode != ADS1115_MUX_P1_N3) setMultiplexer(ADS1115_MUX_P1_N3);
return getConversion();
}
/** Get AIN2/N3 differential.
* This changes the MUX setting to AIN2/N3 if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP2N3() {
if (muxMode != ADS1115_MUX_P2_N3) setMultiplexer(ADS1115_MUX_P2_N3);
return getConversion();
}
/** Get AIN0/GND differential.
* This changes the MUX setting to AIN0/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP0GND() {
if (muxMode != ADS1115_MUX_P0_NG) setMultiplexer(ADS1115_MUX_P0_NG);
return getConversion();
}
/** Get AIN1/GND differential.
* This changes the MUX setting to AIN1/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP1GND() {
if (muxMode != ADS1115_MUX_P1_NG) setMultiplexer(ADS1115_MUX_P1_NG);
return getConversion();
}
/** Get AIN2/GND differential.
* This changes the MUX setting to AIN2/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP2GND() {
if (muxMode != ADS1115_MUX_P2_NG) setMultiplexer(ADS1115_MUX_P2_NG);
return getConversion();
}
/** Get AIN3/GND differential.
* This changes the MUX setting to AIN3/GND if necessary, triggers a new
* measurement (also only if necessary), then gets the differential value
* currently in the CONVERSION register.
* @return 16-bit signed differential value
* @see getConversion()
*/
int16_t ADS1115::getConversionP3GND() {
if (muxMode != ADS1115_MUX_P3_NG) setMultiplexer(ADS1115_MUX_P3_NG);
return getConversion();
}
/** Get the current voltage reading
* Read the current differential and return it multiplied
* by the constant for the current gain. mV is returned to
* increase the precision of the voltage
* @param triggerAndPoll If true (and only in singleshot mode) the conversion trigger
* will be executed and the conversion results will be polled.
*/
float ADS1115::getMilliVolts(bool triggerAndPoll) {
switch (pgaMode) {
case ADS1115_PGA_6P144:
return (getConversion(triggerAndPoll) * ADS1115_MV_6P144);
break;
case ADS1115_PGA_4P096:
return (getConversion(triggerAndPoll) * ADS1115_MV_4P096);
break;
case ADS1115_PGA_2P048:
return (getConversion(triggerAndPoll) * ADS1115_MV_2P048);
break;
case ADS1115_PGA_1P024:
return (getConversion(triggerAndPoll) * ADS1115_MV_1P024);
break;
case ADS1115_PGA_0P512:
return (getConversion(triggerAndPoll) * ADS1115_MV_0P512);
break;
case ADS1115_PGA_0P256:
case ADS1115_PGA_0P256B:
case ADS1115_PGA_0P256C:
return (getConversion(triggerAndPoll) * ADS1115_MV_0P256);
break;
}
}
/**
* Return the current multiplier for the PGA setting.
*
* This may be directly retreived by using getMilliVolts(),
* but this causes an independent read. This function could
* be used to average a number of reads from the getConversion()
* getConversionx() functions and cut downon the number of
* floating-point calculations needed.
*
*/
float ADS1115::getMvPerCount() {
switch (pgaMode) {
case ADS1115_PGA_6P144:
return ADS1115_MV_6P144;
break;
case ADS1115_PGA_4P096:
return ADS1115_MV_4P096;
break;
case ADS1115_PGA_2P048:
return ADS1115_MV_2P048;
break;
case ADS1115_PGA_1P024:
return ADS1115_MV_1P024;
break;
case ADS1115_PGA_0P512:
return ADS1115_MV_0P512;
break;
case ADS1115_PGA_0P256:
case ADS1115_PGA_0P256B:
case ADS1115_PGA_0P256C:
return ADS1115_MV_0P256;
break;
}
}
// CONFIG register
/** Get operational status.
* @return Current operational status (false for active conversion, true for inactive)
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_OS_BIT
*/
bool ADS1115::isConversionReady() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_OS_BIT, buffer);
return buffer[0];
}
/** Trigger a new conversion.
* Writing to this bit will only have effect while in power-down mode (no conversions active).
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_OS_BIT
*/
void ADS1115::triggerConversion() {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_OS_BIT, 1);
}
/** Get multiplexer connection.
* @return Current multiplexer connection setting
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MUX_BIT
* @see ADS1115_CFG_MUX_LENGTH
*/
uint8_t ADS1115::getMultiplexer() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MUX_BIT, ADS1115_CFG_MUX_LENGTH, buffer);
muxMode = (uint8_t)buffer[0];
return muxMode;
}
/** Set multiplexer connection. Continous mode may fill the conversion register
* with data before the MUX setting has taken effect. A stop/start of the conversion
* is done to reset the values.
* @param mux New multiplexer connection setting
* @see ADS1115_MUX_P0_N1
* @see ADS1115_MUX_P0_N3
* @see ADS1115_MUX_P1_N3
* @see ADS1115_MUX_P2_N3
* @see ADS1115_MUX_P0_NG
* @see ADS1115_MUX_P1_NG
* @see ADS1115_MUX_P2_NG
* @see ADS1115_MUX_P3_NG
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MUX_BIT
* @see ADS1115_CFG_MUX_LENGTH
*/
void ADS1115::setMultiplexer(uint8_t mux) {
if (I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MUX_BIT, ADS1115_CFG_MUX_LENGTH, mux)) {
muxMode = mux;
if (devMode == ADS1115_MODE_CONTINUOUS) {
// Force a stop/start
setMode(ADS1115_MODE_SINGLESHOT);
getConversion();
setMode(ADS1115_MODE_CONTINUOUS);
}
}
}
/** Get programmable gain amplifier level.
* @return Current programmable gain amplifier level
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_PGA_BIT
* @see ADS1115_CFG_PGA_LENGTH
*/
uint8_t ADS1115::getGain() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_PGA_BIT, ADS1115_CFG_PGA_LENGTH, buffer);
pgaMode=(uint8_t)buffer[0];
return pgaMode;
}
/** Set programmable gain amplifier level.
* Continous mode may fill the conversion register
* with data before the gain setting has taken effect. A stop/start of the conversion
* is done to reset the values.
* @param gain New programmable gain amplifier level
* @see ADS1115_PGA_6P144
* @see ADS1115_PGA_4P096
* @see ADS1115_PGA_2P048
* @see ADS1115_PGA_1P024
* @see ADS1115_PGA_0P512
* @see ADS1115_PGA_0P256
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_PGA_BIT
* @see ADS1115_CFG_PGA_LENGTH
*/
void ADS1115::setGain(uint8_t gain) {
if (I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_PGA_BIT, ADS1115_CFG_PGA_LENGTH, gain)) {
pgaMode = gain;
if (devMode == ADS1115_MODE_CONTINUOUS) {
// Force a stop/start
setMode(ADS1115_MODE_SINGLESHOT);
getConversion();
setMode(ADS1115_MODE_CONTINUOUS);
}
}
}
/** Get device mode.
* @return Current device mode
* @see ADS1115_MODE_CONTINUOUS
* @see ADS1115_MODE_SINGLESHOT
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MODE_BIT
*/
bool ADS1115::getMode() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MODE_BIT, buffer);
devMode = buffer[0];
return devMode;
}
/** Set device mode.
* @param mode New device mode
* @see ADS1115_MODE_CONTINUOUS
* @see ADS1115_MODE_SINGLESHOT
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_MODE_BIT
*/
void ADS1115::setMode(bool mode) {
if (I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_MODE_BIT, mode)) {
devMode = mode;
}
}
/** Get data rate.
* @return Current data rate
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_DR_BIT
* @see ADS1115_CFG_DR_LENGTH
*/
uint8_t ADS1115::getRate() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_DR_BIT, ADS1115_CFG_DR_LENGTH, buffer);
return (uint8_t)buffer[0];
}
/** Set data rate.
* @param rate New data rate
* @see ADS1115_RATE_8
* @see ADS1115_RATE_16
* @see ADS1115_RATE_32
* @see ADS1115_RATE_64
* @see ADS1115_RATE_128
* @see ADS1115_RATE_250
* @see ADS1115_RATE_475
* @see ADS1115_RATE_860
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_DR_BIT
* @see ADS1115_CFG_DR_LENGTH
*/
void ADS1115::setRate(uint8_t rate) {
I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_DR_BIT, ADS1115_CFG_DR_LENGTH, rate);
}
/** Get comparator mode.
* @return Current comparator mode
* @see ADS1115_COMP_MODE_HYSTERESIS
* @see ADS1115_COMP_MODE_WINDOW
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_MODE_BIT
*/
bool ADS1115::getComparatorMode() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_MODE_BIT, buffer);
return buffer[0];
}
/** Set comparator mode.
* @param mode New comparator mode
* @see ADS1115_COMP_MODE_HYSTERESIS
* @see ADS1115_COMP_MODE_WINDOW
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_MODE_BIT
*/
void ADS1115::setComparatorMode(bool mode) {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_MODE_BIT, mode);
}
/** Get comparator polarity setting.
* @return Current comparator polarity setting
* @see ADS1115_COMP_POL_ACTIVE_LOW
* @see ADS1115_COMP_POL_ACTIVE_HIGH
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_POL_BIT
*/
bool ADS1115::getComparatorPolarity() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_POL_BIT, buffer);
return buffer[0];
}
/** Set comparator polarity setting.
* @param polarity New comparator polarity setting
* @see ADS1115_COMP_POL_ACTIVE_LOW
* @see ADS1115_COMP_POL_ACTIVE_HIGH
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_POL_BIT
*/
void ADS1115::setComparatorPolarity(bool polarity) {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_POL_BIT, polarity);
}
/** Get comparator latch enabled value.
* @return Current comparator latch enabled value
* @see ADS1115_COMP_LAT_NON_LATCHING
* @see ADS1115_COMP_LAT_LATCHING
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_LAT_BIT
*/
bool ADS1115::getComparatorLatchEnabled() {
I2Cdev::readBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_LAT_BIT, buffer);
return buffer[0];
}
/** Set comparator latch enabled value.
* @param enabled New comparator latch enabled value
* @see ADS1115_COMP_LAT_NON_LATCHING
* @see ADS1115_COMP_LAT_LATCHING
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_LAT_BIT
*/
void ADS1115::setComparatorLatchEnabled(bool enabled) {
I2Cdev::writeBitW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_LAT_BIT, enabled);
}
/** Get comparator queue mode.
* @return Current comparator queue mode
* @see ADS1115_COMP_QUE_ASSERT1
* @see ADS1115_COMP_QUE_ASSERT2
* @see ADS1115_COMP_QUE_ASSERT4
* @see ADS1115_COMP_QUE_DISABLE
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_QUE_BIT
* @see ADS1115_CFG_COMP_QUE_LENGTH
*/
uint8_t ADS1115::getComparatorQueueMode() {
I2Cdev::readBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_QUE_BIT, ADS1115_CFG_COMP_QUE_LENGTH, buffer);
return (uint8_t)buffer[0];
}
/** Set comparator queue mode.
* @param mode New comparator queue mode
* @see ADS1115_COMP_QUE_ASSERT1
* @see ADS1115_COMP_QUE_ASSERT2
* @see ADS1115_COMP_QUE_ASSERT4
* @see ADS1115_COMP_QUE_DISABLE
* @see ADS1115_RA_CONFIG
* @see ADS1115_CFG_COMP_QUE_BIT
* @see ADS1115_CFG_COMP_QUE_LENGTH
*/
void ADS1115::setComparatorQueueMode(uint8_t mode) {
I2Cdev::writeBitsW(devAddr, ADS1115_RA_CONFIG, ADS1115_CFG_COMP_QUE_BIT, ADS1115_CFG_COMP_QUE_LENGTH, mode);
}
// *_THRESH registers
/** Get low threshold value.
* @return Current low threshold value
* @see ADS1115_RA_LO_THRESH
*/
int16_t ADS1115::getLowThreshold() {
I2Cdev::readWord(devAddr, ADS1115_RA_LO_THRESH, buffer);
return buffer[0];
}
/** Set low threshold value.
* @param threshold New low threshold value
* @see ADS1115_RA_LO_THRESH
*/
void ADS1115::setLowThreshold(int16_t threshold) {
I2Cdev::writeWord(devAddr, ADS1115_RA_LO_THRESH, threshold);
}
/** Get high threshold value.
* @return Current high threshold value
* @see ADS1115_RA_HI_THRESH
*/
int16_t ADS1115::getHighThreshold() {
I2Cdev::readWord(devAddr, ADS1115_RA_HI_THRESH, buffer);
return buffer[0];
}
/** Set high threshold value.
* @param threshold New high threshold value
* @see ADS1115_RA_HI_THRESH
*/
void ADS1115::setHighThreshold(int16_t threshold) {
I2Cdev::writeWord(devAddr, ADS1115_RA_HI_THRESH, threshold);
}
/** Configures ALERT/RDY pin as a conversion ready pin.
* It does this by setting the MSB of the high threshold register to '1' and the MSB
* of the low threshold register to '0'. COMP_POL and COMP_QUE bits will be set to '0'.
* Note: ALERT/RDY pin requires a pull up resistor.
*/
void ADS1115::setConversionReadyPinMode() {
I2Cdev::writeBitW(devAddr, ADS1115_RA_HI_THRESH, 15, 1);
I2Cdev::writeBitW(devAddr, ADS1115_RA_LO_THRESH, 15, 0);
setComparatorPolarity(0);
setComparatorQueueMode(0);
}
// Create a mask between two bits
unsigned createMask(unsigned a, unsigned b) {
unsigned mask = 0;
for (unsigned i=a; i<=b; i++)
mask |= 1 << i;
return mask;
}
uint16_t shiftDown(uint16_t extractFrom, int places) {
return (extractFrom >> places);
}
uint16_t getValueFromBits(uint16_t extractFrom, int high, int length) {
int low= high-length +1;
uint16_t mask = createMask(low ,high);
return shiftDown(extractFrom & mask, low);
}
/** Show all the config register settings
*/
void ADS1115::showConfigRegister() {
I2Cdev::readWord(devAddr, ADS1115_RA_CONFIG, buffer);
uint16_t configRegister =buffer[0];
#ifdef ADS1115_SERIAL_DEBUG
Serial.print("Register is:");
Serial.println(configRegister,BIN);
Serial.print("OS:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_OS_BIT,1), BIN);
Serial.print("MUX:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_MUX_BIT,ADS1115_CFG_MUX_LENGTH), BIN);
Serial.print("PGA:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_PGA_BIT,ADS1115_CFG_PGA_LENGTH), BIN);
Serial.print("MODE:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_MODE_BIT,1), BIN);
Serial.print("DR:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_DR_BIT,ADS1115_CFG_DR_LENGTH), BIN);
Serial.print("CMP_MODE:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_MODE_BIT,1), BIN);
Serial.print("CMP_POL:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_POL_BIT,1), BIN);
Serial.print("CMP_LAT:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_LAT_BIT,1), BIN);
Serial.print("CMP_QUE:\t");
Serial.println(getValueFromBits(configRegister,
ADS1115_CFG_COMP_QUE_BIT,ADS1115_CFG_COMP_QUE_LENGTH), BIN);
#endif
};

View File

@ -0,0 +1,200 @@
// I2Cdev library collection - ADS1115 I2C device class header file
// Based on Texas Instruments ADS1113/4/5 datasheet, May 2009 (SBAS444B, revised October 2009)
// Note that the ADS1115 uses 16-bit registers, not 8-bit registers.
// 8/2/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-05 - Add debug information. Clean up Single Shot implementation
// 2011-10-29 - added getDifferentialx() methods, F. Farzanegan
// 2011-08-02 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
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.
===============================================
*/
#ifndef _ADS1115_H_
#define _ADS1115_H_
#include "I2Cdev.h"
// -----------------------------------------------------------------------------
// Arduino-style "Serial.print" debug constant (uncomment to enable)
// -----------------------------------------------------------------------------
//#define ADS1115_SERIAL_DEBUG
#define ADS1115_ADDRESS_ADDR_GND 0x48 // address pin low (GND)
#define ADS1115_ADDRESS_ADDR_VDD 0x49 // address pin high (VCC)
#define ADS1115_ADDRESS_ADDR_SDA 0x4A // address pin tied to SDA pin
#define ADS1115_ADDRESS_ADDR_SCL 0x4B // address pin tied to SCL pin
#define ADS1115_DEFAULT_ADDRESS ADS1115_ADDRESS_ADDR_GND
#define ADS1115_RA_CONVERSION 0x00
#define ADS1115_RA_CONFIG 0x01
#define ADS1115_RA_LO_THRESH 0x02
#define ADS1115_RA_HI_THRESH 0x03
#define ADS1115_CFG_OS_BIT 15
#define ADS1115_CFG_MUX_BIT 14
#define ADS1115_CFG_MUX_LENGTH 3
#define ADS1115_CFG_PGA_BIT 11
#define ADS1115_CFG_PGA_LENGTH 3
#define ADS1115_CFG_MODE_BIT 8
#define ADS1115_CFG_DR_BIT 7
#define ADS1115_CFG_DR_LENGTH 3
#define ADS1115_CFG_COMP_MODE_BIT 4
#define ADS1115_CFG_COMP_POL_BIT 3
#define ADS1115_CFG_COMP_LAT_BIT 2
#define ADS1115_CFG_COMP_QUE_BIT 1
#define ADS1115_CFG_COMP_QUE_LENGTH 2
#define ADS1115_MUX_P0_N1 0x00 // default
#define ADS1115_MUX_P0_N3 0x01
#define ADS1115_MUX_P1_N3 0x02
#define ADS1115_MUX_P2_N3 0x03
#define ADS1115_MUX_P0_NG 0x04
#define ADS1115_MUX_P1_NG 0x05
#define ADS1115_MUX_P2_NG 0x06
#define ADS1115_MUX_P3_NG 0x07
#define ADS1115_PGA_6P144 0x00
#define ADS1115_PGA_4P096 0x01
#define ADS1115_PGA_2P048 0x02 // default
#define ADS1115_PGA_1P024 0x03
#define ADS1115_PGA_0P512 0x04
#define ADS1115_PGA_0P256 0x05
#define ADS1115_PGA_0P256B 0x06
#define ADS1115_PGA_0P256C 0x07
#define ADS1115_MV_6P144 0.187500
#define ADS1115_MV_4P096 0.125000
#define ADS1115_MV_2P048 0.062500 // default
#define ADS1115_MV_1P024 0.031250
#define ADS1115_MV_0P512 0.015625
#define ADS1115_MV_0P256 0.007813
#define ADS1115_MV_0P256B 0.007813
#define ADS1115_MV_0P256C 0.007813
#define ADS1115_MODE_CONTINUOUS 0x00
#define ADS1115_MODE_SINGLESHOT 0x01 // default
#define ADS1115_RATE_8 0x00
#define ADS1115_RATE_16 0x01
#define ADS1115_RATE_32 0x02
#define ADS1115_RATE_64 0x03
#define ADS1115_RATE_128 0x04 // default
#define ADS1115_RATE_250 0x05
#define ADS1115_RATE_475 0x06
#define ADS1115_RATE_860 0x07
#define ADS1115_COMP_MODE_HYSTERESIS 0x00 // default
#define ADS1115_COMP_MODE_WINDOW 0x01
#define ADS1115_COMP_POL_ACTIVE_LOW 0x00 // default
#define ADS1115_COMP_POL_ACTIVE_HIGH 0x01
#define ADS1115_COMP_LAT_NON_LATCHING 0x00 // default
#define ADS1115_COMP_LAT_LATCHING 0x01
#define ADS1115_COMP_QUE_ASSERT1 0x00
#define ADS1115_COMP_QUE_ASSERT2 0x01
#define ADS1115_COMP_QUE_ASSERT4 0x02
#define ADS1115_COMP_QUE_DISABLE 0x03 // default
// -----------------------------------------------------------------------------
// Arduino-style "Serial.print" debug constant (uncomment to enable)
// -----------------------------------------------------------------------------
//#define ADS1115_SERIAL_DEBUG
class ADS1115 {
public:
ADS1115();
ADS1115(uint8_t address);
void initialize();
bool testConnection();
// SINGLE SHOT utilities
bool pollConversion(uint16_t max_retries);
void triggerConversion();
// Read the current CONVERSION register
int16_t getConversion(bool triggerAndPoll=true);
// Differential
int16_t getConversionP0N1();
int16_t getConversionP0N3();
int16_t getConversionP1N3();
int16_t getConversionP2N3();
// Single-ended
int16_t getConversionP0GND();
int16_t getConversionP1GND();
int16_t getConversionP2GND();
int16_t getConversionP3GND();
// Utility
float getMilliVolts(bool triggerAndPoll=true);
float getMvPerCount();
// CONFIG register
bool isConversionReady();
uint8_t getMultiplexer();
void setMultiplexer(uint8_t mux);
uint8_t getGain();
void setGain(uint8_t gain);
bool getMode();
void setMode(bool mode);
uint8_t getRate();
void setRate(uint8_t rate);
bool getComparatorMode();
void setComparatorMode(bool mode);
bool getComparatorPolarity();
void setComparatorPolarity(bool polarity);
bool getComparatorLatchEnabled();
void setComparatorLatchEnabled(bool enabled);
uint8_t getComparatorQueueMode();
void setComparatorQueueMode(uint8_t mode);
void setConversionReadyPinMode();
// *_THRESH registers
int16_t getLowThreshold();
void setLowThreshold(int16_t threshold);
int16_t getHighThreshold();
void setHighThreshold(int16_t threshold);
// DEBUG
void showConfigRegister();
private:
uint8_t devAddr;
uint16_t buffer[2];
bool devMode;
uint8_t muxMode;
uint8_t pgaMode;
};
#endif /* _ADS1115_H_ */

View File

@ -0,0 +1,91 @@
// I2C device class (I2Cdev) demonstration Arduino sketch for ADS1115 class
// Example of reading two differential inputs of the ADS1115 and showing the value in mV
// 06 May 2013 by Frederick Farzanegan (frederick1@farzanegan.org)
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-13 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
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.
===============================================
*/
#include "ADS1115.h"
ADS1115 adc0(ADS1115_DEFAULT_ADDRESS);
void setup() {
Wire.begin(); // join I2C bus
Serial.begin(19200); // initialize serial communication
Serial.println("Initializing I2C devices...");
adc0.initialize(); // initialize ADS1115 16 bit A/D chip
Serial.println("Testing device connections...");
Serial.println(adc0.testConnection() ? "ADS1115 connection successful" : "ADS1115 connection failed");
// To get output from this method, you'll need to turn on the
//#define ADS1115_SERIAL_DEBUG // in the ADS1115.h file
adc0.showConfigRegister();
// We're going to do continuous sampling
adc0.setMode(ADS1115_MODE_CONTINUOUS);
}
void loop() {
// Sensor is on P0/N1 (pins 4/5)
Serial.println("Sensor 1 ************************");
// Set the gain (PGA) +/- 1.024v
adc0.setGain(ADS1115_PGA_1P024);
// Get the number of counts of the accumulator
Serial.print("Counts for sensor 1 is:");
// The below method sets the mux and gets a reading.
int sensorOneCounts=adc0.getConversionP0N1(); // counts up to 16-bits
Serial.println(sensorOneCounts);
// To turn the counts into a voltage, we can use
Serial.print("Voltage for sensor 1 is:");
Serial.println(sensorOneCounts*adc0.getMvPerCount());
Serial.println();
// 2nd sensor is on P2/N3 (pins 6/7)
Serial.println("Sensor 2 ************************");
// Set the gain (PGA) +/- 0.256v
adc0.setGain(ADS1115_PGA_0P256);
// Manually set the MUX // could have used the getConversionP* above
adc0.setMultiplexer(ADS1115_MUX_P2_N3);
Serial.print("Counts for sensor 2 is:");
Serial.println(adc0.getConversion());
Serial.print("mVoltage sensor 2 is:");
Serial.println(adc0.getMilliVolts()); // Convenience method to calculate voltage
Serial.println();
delay(500);
}

View File

@ -0,0 +1,110 @@
// I2C device class (I2Cdev) demonstration Arduino sketch for ADS1115 class
// Example of reading two differential inputs of the ADS1115 and showing the value in mV
// 2016-03-22 by Eadf (https://github.com/eadf)
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2016-03-22 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
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.
===============================================
*/
#include "ADS1115.h"
ADS1115 adc0(ADS1115_DEFAULT_ADDRESS);
// Wire ADS1115 ALERT/RDY pin to Arduino pin 2
const int alertReadyPin = 2;
void setup() {
//I2Cdev::begin(); // join I2C bus
Wire.begin();
Serial.begin(115200); // initialize serial communication
Serial.println("Testing device connections...");
Serial.println(adc0.testConnection() ? "ADS1115 connection successful" : "ADS1115 connection failed");
adc0.initialize(); // initialize ADS1115 16 bit A/D chip
// We're going to do single shot sampling
adc0.setMode(ADS1115_MODE_SINGLESHOT);
// Slow things down so that we can see that the "poll for conversion" code works
adc0.setRate(ADS1115_RATE_8);
// Set the gain (PGA) +/- 6.144V
// Note that any analog input must be higher than 0.3V and less than VDD +0.3
adc0.setGain(ADS1115_PGA_6P144);
// ALERT/RDY pin will indicate when conversion is ready
pinMode(alertReadyPin,INPUT_PULLUP);
adc0.setConversionReadyPinMode();
// To get output from this method, you'll need to turn on the
//#define ADS1115_SERIAL_DEBUG // in the ADS1115.h file
#ifdef ADS1115_SERIAL_DEBUG
adc0.showConfigRegister();
Serial.print("HighThreshold="); Serial.println(adc0.getHighThreshold(),BIN);
Serial.print("LowThreshold="); Serial.println(adc0.getLowThreshold(),BIN);
#endif
}
/** Poll the assigned pin for conversion status
*/
void pollAlertReadyPin() {
for (uint32_t i = 0; i<100000; i++)
if (!digitalRead(alertReadyPin)) return;
Serial.println("Failed to wait for AlertReadyPin, it's stuck high!");
}
void loop() {
// The below method sets the mux and gets a reading.
adc0.setMultiplexer(ADS1115_MUX_P0_NG);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A0: "); Serial.print(adc0.getMilliVolts(false)); Serial.print("mV\t");
adc0.setMultiplexer(ADS1115_MUX_P1_NG);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A1: "); Serial.print(adc0.getMilliVolts(false)); Serial.print("mV\t");
adc0.setMultiplexer(ADS1115_MUX_P2_NG);
adc0.triggerConversion();
pollAlertReadyPin();
Serial.print("A2: "); Serial.print(adc0.getMilliVolts(false)); Serial.print("mV\t");
adc0.setMultiplexer(ADS1115_MUX_P3_NG);
// Do conversion polling via I2C on this last reading:
Serial.print("A3: "); Serial.print(adc0.getMilliVolts(true)); Serial.print("mV");
Serial.println(digitalRead(alertReadyPin));
delay(500);
}

View File

@ -0,0 +1,18 @@
{
"name": "I2Cdevlib-ADS1115",
"keywords": "MUX, PGA, comparator, oscillator, reference, i2cdevlib, i2c",
"description": "ADS1115 is 16-Bit ADC with Integrated MUX, PGA, Comparator, Oscillator, and Reference",
"include": "Arduino/ADS1115",
"repository":
{
"type": "git",
"url": "https://github.com/jrowberg/i2cdevlib.git"
},
"dependencies":
{
"name": "I2Cdevlib-Core",
"frameworks": "arduino"
},
"frameworks": "arduino",
"platforms": "atmelavr"
}

View File

@ -0,0 +1,31 @@
{
"name": "I2Cdevlib-Core",
"repository": {
"url": "https://github.com/jrowberg/i2cdevlib.git",
"type": "git"
},
"platforms": [
"atmelavr"
],
"frameworks": [
"arduino"
],
"version": "6744ce0ac4",
"export": {
"include": "Arduino/I2Cdev"
},
"authors": [
{
"maintainer": false,
"name": "Jeff Rowberg",
"url": "https://github.com/jrowberg",
"email": "jeff@rowberg.net"
}
],
"keywords": [
"i2cdevlib",
"i2c"
],
"id": 11,
"description": "The I2C Device Library (I2Cdevlib) is a collection of uniform and well-documented classes to provide simple and intuitive interfaces to I2C devices."
}

File diff suppressed because it is too large Load Diff

278
lib/I2Cdevlib-Core/I2Cdev.h Normal file
View File

@ -0,0 +1,278 @@
// I2Cdev library collection - Main I2C device class header file
// Abstracts bit and byte I2C R/W functions into a convenient class
// 2013-06-05 by Jeff Rowberg <jeff@rowberg.net>
//
// Changelog:
// 2015-10-30 - simondlevy : support i2c_t3 for Teensy3.1
// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications
// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan)
// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire
// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation
// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums)
// 2011-10-03 - added automatic Arduino version detection for ease of use
// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications
// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x)
// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default
// 2011-08-02 - added support for 16-bit registers
// - fixed incorrect Doxygen comments on some methods
// - added timeout value for read operations (thanks mem @ Arduino forums)
// 2011-07-30 - changed read/write function structures to return success or byte counts
// - made all methods static for multi-device memory savings
// 2011-07-28 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2013 Jeff Rowberg
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.
===============================================
*/
#ifndef _I2CDEV_H_
#define _I2CDEV_H_
// -----------------------------------------------------------------------------
// I2C interface implementation setting
// -----------------------------------------------------------------------------
#ifndef I2CDEV_IMPLEMENTATION
#define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE
//#define I2CDEV_IMPLEMENTATION I2CDEV_BUILTIN_FASTWIRE
#endif // I2CDEV_IMPLEMENTATION
// comment this out if you are using a non-optimal IDE/implementation setting
// but want the compiler to shut up about it
#define I2CDEV_IMPLEMENTATION_WARNINGS
// -----------------------------------------------------------------------------
// I2C interface implementation options
// -----------------------------------------------------------------------------
#define I2CDEV_ARDUINO_WIRE 1 // Wire object from Arduino
#define I2CDEV_BUILTIN_NBWIRE 2 // Tweaked Wire object from Gene Knight's NBWire project
// ^^^ NBWire implementation is still buggy w/some interrupts!
#define I2CDEV_BUILTIN_FASTWIRE 3 // FastWire object from Francesco Ferrara's project
#define I2CDEV_I2CMASTER_LIBRARY 4 // I2C object from DSSCircuits I2C-Master Library at https://github.com/DSSCircuits/I2C-Master-Library
// -----------------------------------------------------------------------------
// Arduino-style "Serial.print" debug constant (uncomment to enable)
// -----------------------------------------------------------------------------
//#define I2CDEV_SERIAL_DEBUG
#ifdef ARDUINO
#if ARDUINO < 100
#include "WProgram.h"
#else
#include "Arduino.h"
#endif
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include <Wire.h>
#endif
#if I2CDEV_IMPLEMENTATION == I2CDEV_I2CMASTER_LIBRARY
#include <I2C.h>
#endif
#endif
#ifdef SPARK
#include <spark_wiring_i2c.h>
#define ARDUINO 101
#endif
// 1000ms default read timeout (modify with "I2Cdev::readTimeout = [ms];")
#define I2CDEV_DEFAULT_READ_TIMEOUT 1000
class I2Cdev {
public:
I2Cdev();
static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data);
static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data);
static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data);
static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data);
static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data);
static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data);
static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data);
static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data);
static uint16_t readTimeout;
};
#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
//////////////////////
// FastWire 0.24
// This is a library to help faster programs to read I2C devices.
// Copyright(C) 2012
// Francesco Ferrara
//////////////////////
/* Master */
#define TW_START 0x08
#define TW_REP_START 0x10
/* Master Transmitter */
#define TW_MT_SLA_ACK 0x18
#define TW_MT_SLA_NACK 0x20
#define TW_MT_DATA_ACK 0x28
#define TW_MT_DATA_NACK 0x30
#define TW_MT_ARB_LOST 0x38
/* Master Receiver */
#define TW_MR_ARB_LOST 0x38
#define TW_MR_SLA_ACK 0x40
#define TW_MR_SLA_NACK 0x48
#define TW_MR_DATA_ACK 0x50
#define TW_MR_DATA_NACK 0x58
#define TW_OK 0
#define TW_ERROR 1
class Fastwire {
private:
static boolean waitInt();
public:
static void setup(int khz, boolean pullup);
static byte beginTransmission(byte device);
static byte write(byte value);
static byte writeBuf(byte device, byte address, byte *data, byte num);
static byte readBuf(byte device, byte address, byte *data, byte num);
static void reset();
static byte stop();
};
#endif
#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
// NBWire implementation based heavily on code by Gene Knight <Gene@Telobot.com>
// Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html
// Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html
#define NBWIRE_BUFFER_LENGTH 32
class TwoWire {
private:
static uint8_t rxBuffer[];
static uint8_t rxBufferIndex;
static uint8_t rxBufferLength;
static uint8_t txAddress;
static uint8_t txBuffer[];
static uint8_t txBufferIndex;
static uint8_t txBufferLength;
// static uint8_t transmitting;
static void (*user_onRequest)(void);
static void (*user_onReceive)(int);
static void onRequestService(void);
static void onReceiveService(uint8_t*, int);
public:
TwoWire();
void begin();
void begin(uint8_t);
void begin(int);
void beginTransmission(uint8_t);
//void beginTransmission(int);
uint8_t endTransmission(uint16_t timeout=0);
void nbendTransmission(void (*function)(int)) ;
uint8_t requestFrom(uint8_t, int, uint16_t timeout=0);
//uint8_t requestFrom(int, int);
void nbrequestFrom(uint8_t, int, void (*function)(int));
void send(uint8_t);
void send(uint8_t*, uint8_t);
//void send(int);
void send(char*);
uint8_t available(void);
uint8_t receive(void);
void onReceive(void (*)(int));
void onRequest(void (*)(void));
};
#define TWI_READY 0
#define TWI_MRX 1
#define TWI_MTX 2
#define TWI_SRX 3
#define TWI_STX 4
#define TW_WRITE 0
#define TW_READ 1
#define TW_MT_SLA_NACK 0x20
#define TW_MT_DATA_NACK 0x30
#define CPU_FREQ 16000000L
#define TWI_FREQ 100000L
#define TWI_BUFFER_LENGTH 32
/* TWI Status is in TWSR, in the top 5 bits: TWS7 - TWS3 */
#define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3))
#define TW_STATUS (TWSR & TW_STATUS_MASK)
#define TW_START 0x08
#define TW_REP_START 0x10
#define TW_MT_SLA_ACK 0x18
#define TW_MT_SLA_NACK 0x20
#define TW_MT_DATA_ACK 0x28
#define TW_MT_DATA_NACK 0x30
#define TW_MT_ARB_LOST 0x38
#define TW_MR_ARB_LOST 0x38
#define TW_MR_SLA_ACK 0x40
#define TW_MR_SLA_NACK 0x48
#define TW_MR_DATA_ACK 0x50
#define TW_MR_DATA_NACK 0x58
#define TW_ST_SLA_ACK 0xA8
#define TW_ST_ARB_LOST_SLA_ACK 0xB0
#define TW_ST_DATA_ACK 0xB8
#define TW_ST_DATA_NACK 0xC0
#define TW_ST_LAST_DATA 0xC8
#define TW_SR_SLA_ACK 0x60
#define TW_SR_ARB_LOST_SLA_ACK 0x68
#define TW_SR_GCALL_ACK 0x70
#define TW_SR_ARB_LOST_GCALL_ACK 0x78
#define TW_SR_DATA_ACK 0x80
#define TW_SR_DATA_NACK 0x88
#define TW_SR_GCALL_DATA_ACK 0x90
#define TW_SR_GCALL_DATA_NACK 0x98
#define TW_SR_STOP 0xA0
#define TW_NO_INFO 0xF8
#define TW_BUS_ERROR 0x00
//#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
//#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))
#ifndef sbi // set bit
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif // sbi
#ifndef cbi // clear bit
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif // cbi
extern TwoWire Wire;
#endif // I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
#endif /* _I2CDEV_H_ */

View File

@ -0,0 +1,38 @@
#######################################
# Syntax Coloring Map For I2Cdev
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
I2Cdev KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
readBit KEYWORD2
readBitW KEYWORD2
readBits KEYWORD2
readBitsW KEYWORD2
readByte KEYWORD2
readBytes KEYWORD2
readWord KEYWORD2
readWords KEYWORD2
writeBit KEYWORD2
writeBitW KEYWORD2
writeBits KEYWORD2
writeBitsW KEYWORD2
writeByte KEYWORD2
writeBytes KEYWORD2
writeWord KEYWORD2
writeWords KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,13 @@
{
"name": "I2Cdevlib-Core",
"keywords": "i2cdevlib, i2c",
"description": "The I2C Device Library (I2Cdevlib) is a collection of uniform and well-documented classes to provide simple and intuitive interfaces to I2C devices.",
"include": "Arduino/I2Cdev",
"repository":
{
"type": "git",
"url": "https://github.com/jrowberg/i2cdevlib.git"
},
"frameworks": "arduino",
"platforms": "atmelavr"
}

View File

@ -1,4 +1,11 @@
/* 5.9.0 20171030
/* 5.9.1 20171107
* Add external sensor function pointer interface to enable easy sensor addition
* Add support for ADS1115 to be enabled in user_config.h and needs libraries i2cdevlib-Core and i2cdevlib-ADS1115 (#338, #660)
* Fix Backup Configuration file download failure by defining proper file size (#1115)
* Fix Exception 26 and empty console screen after usage of command WakeupDuration (#1133)
* Fix some changed iTead web links in README.md (#1137)
*
* 5.9.0 20171030
* Rewrite code (partly) using Google C++ Style Guide (https://google.github.io/styleguide/cppguide.html)
* Rewrite code by using command lookup tables and javascript (client side) web page expansions
* Change HTML/CSS to enable nicer form field entry

View File

@ -77,8 +77,9 @@ const char S_JSON_COMMAND_INDEX_NVALUE[] PROGMEM = "{\"%s%d\":%d}";
const char S_JSON_COMMAND_INDEX_SVALUE[] PROGMEM = "{\"%s%d\":\"%s\"}";
const char S_JSON_COMMAND_INDEX_SVALUE_SVALUE[] PROGMEM = "{\"%s%d\":\"%s%s\"}";
const char JSON_SNS_TEMPHUM[] PROGMEM =
"%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s}";
const char JSON_SNS_TEMPHUM[] PROGMEM = "%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s}";
const char S_LOG_I2C_FOUND_AT[] PROGMEM = D_LOG_I2C "%s " D_FOUND_AT " 0x%x";
const char S_LOG_HTTP[] PROGMEM = D_LOG_HTTP;
const char S_LOG_WIFI[] PROGMEM = D_LOG_WIFI;
@ -113,6 +114,13 @@ const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
static const char kMonthNames[] = D_MONTH3LIST;
// webserver.ino
#ifdef USE_WEBSERVER
const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s&deg;%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_PRESSURE[] PROGMEM = "%s{s}%s " D_PRESSURE "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "%s{s}%s " D_PRESSUREATSEALEVEL "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_ANALOG[] PROGMEM = "%s{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
const char S_CONFIGURE_MODULE[] PROGMEM = D_CONFIGURE_MODULE;
@ -128,5 +136,6 @@ const char S_FIRMWARE_UPGRADE[] PROGMEM = D_FIRMWARE_UPGRADE;
const char S_CONSOLE[] PROGMEM = D_CONSOLE;
const char S_INFORMATION[] PROGMEM = D_INFORMATION;
const char S_RESTART[] PROGMEM = D_RESTART;
#endif // USE_WEBSERVER
#endif // _I18N_H_

View File

@ -216,7 +216,7 @@
#define D_SET_BAUDRATE_TO "Baudrate eingestell auf"
#define D_RECEIVED_TOPIC "erhaltenes topic"
#define D_DATA_SIZE "Datengröße"
#define D_ANALOG_INPUT0 "Analog0"
#define D_ANALOG_INPUT "Analog"
#define D_FINGERPRINT "TLS-Fingerabdruck wird verifiziert..."
#define D_TLS_CONNECT_FAILED_TO "TLS-Verbindung fehlgeschlagen an"

View File

@ -216,7 +216,7 @@
#define D_SET_BAUDRATE_TO "Set Baudrate to"
#define D_RECEIVED_TOPIC "Received Topic"
#define D_DATA_SIZE "Data Size"
#define D_ANALOG_INPUT0 "Analog0"
#define D_ANALOG_INPUT "Analog"
#define D_FINGERPRINT "Verify TLS fingerprint..."
#define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to"

View File

@ -216,7 +216,7 @@
#define D_SET_BAUDRATE_TO "Zet baudrate op"
#define D_RECEIVED_TOPIC "Ontvangen topic"
#define D_DATA_SIZE "Data lengte"
#define D_ANALOG_INPUT0 "Analoog0"
#define D_ANALOG_INPUT "Analoog"
#define D_FINGERPRINT "Controleer TLS vingerafdruk..."
#define D_TLS_CONNECT_FAILED_TO "TLS Verbinding mislukt naar"

View File

@ -216,7 +216,7 @@
#define D_SET_BAUDRATE_TO "Ustaw szybkosc transmisji na"
#define D_RECEIVED_TOPIC "Otrzymany temat"
#define D_DATA_SIZE "Wielkosc danych"
#define D_ANALOG_INPUT0 "Wej_analogowe"
#define D_ANALOG_INPUT "Wej_analogowe"
#define D_FINGERPRINT "Weryfikuj odcisk TLS..."
#define D_TLS_CONNECT_FAILED_TO "Nieudane polaczenie TLS do"

View File

@ -90,6 +90,8 @@ typedef unsigned long power_t; // Power (Relay) type
#define APP_BAUDRATE 115200 // Default serial baudrate
#define MAX_STATUS 11 // Max number of status lines
#define XSNS_MAX 20 // Max number of allowed Xsns External Sensors (Update xsns_interface.ino if changed)
/*********************************************************************************************\
* Enumeration
\*********************************************************************************************/
@ -110,6 +112,7 @@ enum Ws2812Color {WS_RED, WS_GREEN, WS_BLUE};
enum LightTypes {LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT_PWM5, LT_PWM6, LT_PWM7, LT_NU8, LT_NU9, LT_NU10, LT_WS2812, LT_RGBW, LT_RGBWC};
enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_RGBWC};
enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX};
enum XsnsFunctions {FUNC_XSNS_INIT, FUNC_XSNS_PREP, FUNC_XSNS_JSON_APPEND, FUNC_XSNS_MQTT_SHOW, FUNC_XSNS_WEB};
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/
#define VERSION 0x05090000 // 5.9.0
#define VERSION 0x05090100 // 5.9.1
// Location specific includes
#include "sonoff.h" // Enumaration used in user_config.h
@ -183,6 +183,8 @@ uint8_t light_type = 0; // Light types
boolean mdns_begun = false;
uint8_t xsns_present = 0; // Number of External Sensors found
boolean (*xsns_func_ptr[XSNS_MAX])(byte); // External Sensor Function Pointers for simple implementation of sensors
char version[16]; // Version string from VERSION define
char my_hostname[33]; // Composed Wifi hostname
char mqtt_client[33]; // Composed MQTT Clientname
@ -1757,9 +1759,8 @@ void PublishStatus(uint8_t payload)
}
if ((0 == payload) || (10 == payload)) {
uint8_t djson = 0;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":"));
MqttShowSensor(&djson);
MqttShowSensor();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "10"));
}
@ -1789,62 +1790,23 @@ void MqttShowState()
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
}
void MqttShowSensor(uint8_t* djson)
boolean MqttShowSensor()
{
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_TIME "\":\"%s\""), mqtt_data, GetDateAndTime().c_str());
int json_data_start = strlen(mqtt_data);
for (byte i = 0; i < MAX_SWITCHES; i++) {
if (pin[GPIO_SWT1 +i] < 99) {
boolean swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i]));
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_SWITCH "%d\":\"%s\""), mqtt_data, i +1, GetStateText(swm ^ lastwallswitch[i]));
*djson = 1;
}
}
MqttShowCounter(djson);
#ifndef USE_ADC_VCC
if (pin[GPIO_ADC0] < 99) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_ANALOG_INPUT0 "\":%d"), mqtt_data, GetAdc0());
*djson = 1;
}
#endif
if (SONOFF_SC == Settings.module) {
MqttShowSonoffSC(djson);
}
if (pin[GPIO_DSB] < 99) {
#ifdef USE_DS18B20
MqttShowDs18b20(djson);
#endif // USE_DS18B20
#ifdef USE_DS18x20
MqttShowDs18x20(djson);
#endif // USE_DS18x20
}
#ifdef USE_DHT
if (dht_flg) {
MqttShowDht(djson);
}
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_SHT
MqttShowSht(djson);
#endif // USE_SHT
#ifdef USE_HTU
MqttShowHtu(djson);
#endif // USE_HTU
#ifdef USE_BMP
MqttShowBmp(djson);
#endif // USE_BMP
#ifdef USE_BH1750
MqttShowBh1750(djson);
#endif // USE_BH1750
#ifdef USE_VEML6070
MqttShowVeml6070(djson);
#endif // USE_VEML6070
}
#endif // USE_I2C
XsnsCall(FUNC_XSNS_JSON_APPEND);
boolean json_data_available = (strlen(mqtt_data) - json_data_start);
if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, TempUnit());
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
return json_data_available;
}
/********************************************************************************************/
@ -1897,39 +1859,7 @@ void PerformEverySecond()
if (Settings.tele_period) {
tele_period++;
if (tele_period == Settings.tele_period -1) {
if (pin[GPIO_DSB] < 99) {
#ifdef USE_DS18B20
Ds18b20ReadTempPrep();
#endif // USE_DS18B20
#ifdef USE_DS18x20
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
#endif // USE_DS18x20
}
#ifdef USE_DHT
if (dht_flg) {
DhtReadPrep();
}
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_SHT
ShtDetect();
#endif // USE_SHT
#ifdef USE_HTU
HtuDetect();
#endif // USE_HTU
#ifdef USE_BMP
BmpDetect();
#endif // USE_BMP
#ifdef USE_BH1750
Bh1750Detect();
#endif // USE_BH1750
#ifdef USE_VEML6070
Veml6070Detect();
#endif // USE_VEML6070
}
#endif // USE_I2C
XsnsCall(FUNC_XSNS_PREP);
}
if (tele_period >= Settings.tele_period) {
tele_period = 0;
@ -1938,16 +1868,12 @@ void PerformEverySecond()
MqttShowState();
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_STATE));
uint8_t djson = 0;
mqtt_data[0] = '\0';
MqttShowSensor(&djson);
if (djson) {
if (MqttShowSensor()) {
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
}
if (hlw_flg) {
MqttShowHlw8012(1);
}
XsnsCall(FUNC_XSNS_MQTT_SHOW);
}
}
@ -2684,24 +2610,9 @@ void GpioInit()
#endif // USE_IR_RECEIVE
#endif // USE_IR_REMOTE
CounterInit();
hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99));
if (hlw_flg) {
HlwInit();
}
#ifdef USE_DHT
if (dht_flg) {
DhtInit();
}
#endif // USE_DHT
#ifdef USE_DS18x20
if (pin[GPIO_DSB] < 99) {
Ds18x20Init();
}
#endif // USE_DS18x20
XSnsInit();
}
extern "C" {

View File

@ -757,6 +757,17 @@ int32_t I2cRead24(uint8_t addr, uint8_t reg)
return I2cRead(addr, reg, 3);
}
void I2cWrite8v(uint8_t addr, uint8_t val)
{
byte x = I2C_RETRY_COUNTER;
do {
Wire.beginTransmission((uint8_t)addr); // start transmission to device
Wire.write(val); // write data
x--;
} while (Wire.endTransmission(true) != 0 && x != 0); // end transmission
}
void I2cWrite8(uint8_t addr, uint8_t reg, uint8_t val)
{
byte x = I2C_RETRY_COUNTER;
@ -1136,16 +1147,6 @@ char TempUnit()
return (Settings.flag.temperature_conversion) ? 'F' : 'C';
}
uint16_t GetAdc0()
{
uint16_t alr = 0;
for (byte i = 0; i < 32; i++) {
alr += analogRead(A0);
delay(1);
}
return alr >> 5;
}
double FastPrecisePow(double a, double b)
{
// https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
@ -1233,8 +1234,66 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl
return result;
}
#ifndef USE_ADC_VCC
/*********************************************************************************************\
* ADC support
\*********************************************************************************************/
void AdcShow(boolean json)
{
uint16_t analog = 0;
for (byte i = 0; i < 32; i++) {
analog += analogRead(A0);
delay(1);
}
analog >>= 5;
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_ANALOG_INPUT "0\":%d"), mqtt_data, analog);
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "", 0, analog);
#endif // USE_WEBSERVER
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_02
boolean Xsns02(byte function)
{
boolean result = false;
if (pin[GPIO_ADC0] < 99) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
// case FUNC_XSNS_PREP:
// break;
case FUNC_XSNS_JSON_APPEND:
AdcShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
AdcShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_ADC_VCC
/*********************************************************************************************\
* Syslog
*
* Example:
* snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG "Any value %d"), value);
* AddLog(LOG_LEVEL_DEBUG);
*
\*********************************************************************************************/
void Syslog()

View File

@ -163,14 +163,15 @@
// -- Sensor code selection -----------------------
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
//#define USE_DS18x20 // Optional using OneWire library for multiple DS18B20 and/or DS18S20 (+2k code)
//#define USE_DS18x20 // Optional for multiple DS18B20 and/or DS18S20 sensors using library OneWire (+2k code)
#define USE_I2C // I2C using library wire (+10k code, 0.2k mem) - Disable by //
#define USE_SHT // Add I2C emulating code for SHT1X sensor
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor
#define USE_BMP // Add I2C code for BMP/BME280 sensor
#define USE_BH1750 // Add I2C code for BH1750 sensor
// #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0.5k code)
#define USE_BMP // Add I2C code for BMP/BME280 sensor
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor
#define USE_SHT // Add I2C emulating code for SHT1X sensor
// #define USE_ADS1115 // Add I2C code for ADS1x15 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code)
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+3k code, 0.3k mem)
// #define USE_IR_HVAC // Support for HVAC system using IR (+2k code)

View File

@ -60,7 +60,8 @@ const char HTTP_HEAD[] PROGMEM =
"x=new XMLHttpRequest();"
"x.onreadystatechange=function(){"
"if(x.readyState==4&&x.status==200){"
"document.getElementById('l1').innerHTML=x.responseText;"
"var s=x.responseText.replace(/{s}/g,\"<tr><th>\").replace(/{m}/g,\"</th><td>\").replace(/{e}/g,\"</td></tr>\").replace(/{t}/g,\"%'><div style='text-align:center;font-weight:\");"
"document.getElementById('l1').innerHTML=s;"
"}"
"};"
"x.open('GET','ay'+a,true);"
@ -274,20 +275,6 @@ const char HTTP_TABLE100[] PROGMEM =
"<table style='width:100%'>";
const char HTTP_COUNTER[] PROGMEM =
"<br/><div id='t' name='t' style='text-align:center;'></div>";
const char HTTP_SNS_TEMP[] PROGMEM =
"<tr><th>%s " D_TEMPERATURE "</th><td>%s&deg;%c</td></tr>";
const char HTTP_SNS_HUM[] PROGMEM =
"<tr><th>%s " D_HUMIDITY "</th><td>%s%</td></tr>";
const char HTTP_SNS_PRESSURE[] PROGMEM =
"<tr><th>%s " D_PRESSURE "</th><td>%s " D_UNIT_PRESSURE "</td></tr>";
const char HTTP_SNS_PRESSUREATSEALEVEL[] PROGMEM =
"<tr><th>%s " D_PRESSUREATSEALEVEL "</th><td>%s " D_UNIT_PRESSURE "</td></tr>";
const char HTTP_SNS_LIGHT[] PROGMEM =
"<tr><th>%s " D_LIGHT "</th><td>%d%</td></tr>";
const char HTTP_SNS_NOISE[] PROGMEM =
"<tr><th>%s " D_NOISE "</th><td>%d%</td></tr>";
const char HTTP_SNS_DUST[] PROGMEM =
"<tr><th>%s " D_AIR_QUALITY "</th><td>%d%</td></tr>";
const char HTTP_END[] PROGMEM =
"</div>"
"</body>"
@ -520,68 +507,23 @@ void HandleAjaxStatusRefresh()
ExecuteCommand(svalue);
}
String tpage = "";
tpage += WebShowCounter();
#ifndef USE_ADC_VCC
if (pin[GPIO_ADC0] < 99) {
snprintf_P(svalue, sizeof(svalue), PSTR("<tr><th>" D_ANALOG_INPUT0 "</th><td>%d</td></tr>"), GetAdc0());
tpage += svalue;
}
#endif
if (hlw_flg) {
tpage += WebShowHlw();
}
if (SONOFF_SC == Settings.module) {
tpage += WebShowSonoffSc();
}
#ifdef USE_DS18B20
if (pin[GPIO_DSB] < 99) {
tpage += WebShowDs18b20();
}
#endif // USE_DS18B20
#ifdef USE_DS18x20
if (pin[GPIO_DSB] < 99) {
tpage += WebShowDs18x20();
}
#endif // USE_DS18x20
#ifdef USE_DHT
if (dht_flg) {
tpage += WebShowDht();
}
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_SHT
tpage += WebShowSht();
#endif
#ifdef USE_HTU
tpage += WebShowHtu();
#endif
#ifdef USE_BMP
tpage += WebShowBmp();
#endif
#ifdef USE_BH1750
tpage += WebShowBh1750();
#endif
#ifdef USE_VEML6070
tpage += WebShowVeml6070();
#endif
}
#endif // USE_I2C
String page = "";
if (tpage.length() > 0) {
mqtt_data[0] = '\0';
XsnsCall(FUNC_XSNS_WEB);
if (strlen(mqtt_data)) {
page += FPSTR(HTTP_TABLE100);
page += tpage;
page += mqtt_data;
page += F("</table>");
}
char line[160];
char line[80];
if (devices_present) {
page += FPSTR(HTTP_TABLE100);
page += F("<tr>");
uint8_t fsize = (devices_present < 5) ? 70 - (devices_present * 8) : 32;
for (byte idx = 1; idx <= devices_present; idx++) {
snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, idx -1));
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:%s;font-size:%dpx'>%s</div></td>"),
// snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:%s;font-size:%dpx'>%s</div></td>"),
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d{t}%s;font-size:%dpx'>%s</div></td>"), // {t} = %'><div style='text-align:center;font-weight:
100 / devices_present, (bitRead(power, idx -1)) ? "bold" : "normal", fsize, (devices_present < 5) ? GetStateText(bitRead(power, idx -1)) : svalue);
page += line;
}
@ -978,14 +920,14 @@ void HandleBackupConfiguration()
uint8_t buffer[sizeof(Settings)];
WiFiClient myClient = WebServer->client();
WebServer->setContentLength(4096);
WebServer->setContentLength(sizeof(buffer));
char attachment[100];
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"),
Settings.friendlyname[0], version);
WebServer->sendHeader(F("Content-Disposition"), attachment);
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
memcpy(buffer, &Settings, sizeof(Settings));
memcpy(buffer, &Settings, sizeof(buffer));
buffer[0] = CONFIG_FILE_SIGN;
buffer[1] = (!CONFIG_FILE_XOR)?0:1;
if (buffer[1]) {

View File

@ -899,7 +899,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
Settings.light_wakeup = payload;
light_wakeup_active = 0;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, Settings.light_wakeup);
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.light_wakeup);
}
else if (CMND_UNDOCA == command_code) { // Theos legacy status
LightGetColor(1, scolor);

View File

@ -1,5 +1,5 @@
/*
xsns_counter.ino - Counter sensors (water meters, electricity meters etc.) sensor support for Sonoff-Tasmota
xsns_01_counter.ino - Counter sensors (water meters, electricity meters etc.) sensor support for Sonoff-Tasmota
Copyright (C) 2017 Maarten Damen and Theo Arends
@ -68,6 +68,8 @@ void CounterSaveState()
}
}
/********************************************************************************************/
void CounterInit()
{
typedef void (*function) () ;
@ -81,57 +83,66 @@ void CounterInit()
}
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
#ifdef USE_WEBSERVER
const char HTTP_SNS_COUNTER[] PROGMEM =
"%s{s}" D_COUNTER "%d{m}%s%s{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
#endif // USE_WEBSERVER
void MqttShowCounter(uint8_t* djson)
void CounterShow(boolean json)
{
char stemp[16];
char counter[16];
byte dsxflg = 0;
for (byte i = 0; i < MAX_COUNTERS; i++) {
if (pin[GPIO_CNTR1 +i] < 99) {
if (bitRead(Settings.pulse_counter_type, i)) {
dtostrfd((double)RtcSettings.pulse_counter[i] / 1000, 3, stemp);
dtostrfd((double)RtcSettings.pulse_counter[i] / 1000, 3, counter);
} else {
dsxflg++;
dtostrfd(RtcSettings.pulse_counter[i], 0, stemp);
dtostrfd(RtcSettings.pulse_counter[i], 0, counter);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_COUNTER "%d\":%s"), mqtt_data, i +1, stemp);
*djson = 1;
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_COUNTER "%d\":%s"), mqtt_data, i +1, counter);
#ifdef USE_DOMOTICZ
if (1 == dsxflg) {
DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]);
dsxflg++;
}
if (1 == dsxflg) {
DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]);
dsxflg++;
}
#endif // USE_DOMOTICZ
}
}
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_COUNTER[] PROGMEM =
"<tr><th>" D_COUNTER "%d</th><td>%s%s</td></tr>";
String WebShowCounter()
{
String page = "";
char stemp[16];
char sensor[80];
for (byte i = 0; i < MAX_COUNTERS; i++) {
if (pin[GPIO_CNTR1 +i] < 99) {
if (bitRead(Settings.pulse_counter_type, i)) {
dtostrfi((double)RtcSettings.pulse_counter[i] / 1000, 3, stemp);
} else {
dtostrfi(RtcSettings.pulse_counter[i], 0, stemp);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_COUNTER, mqtt_data, i +1, counter, (bitRead(Settings.pulse_counter_type, i)) ? " " D_UNIT_SECOND : "");
#endif // USE_WEBSERVER
}
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_COUNTER, i+1, stemp, (bitRead(Settings.pulse_counter_type, i)) ? " " D_UNIT_SECOND : "");
page += sensor;
}
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_01
boolean Xsns01(byte function)
{
boolean result = false;
switch (function) {
case FUNC_XSNS_INIT:
CounterInit();
break;
// case FUNC_XSNS_PREP:
// break;
case FUNC_XSNS_JSON_APPEND:
CounterShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
CounterShow(0);
break;
#endif // USE_WEBSERVER
}
return result;
}

View File

@ -1,5 +1,5 @@
/*
xsns_hlw8012.ino - sonoff pow HLW8012 energy sensor support for Sonoff-Tasmota
xsns_03_hlw8012.ino - sonoff pow HLW8012 energy sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -650,11 +650,20 @@ boolean HlwCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_len,
return serviced;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
/********************************************************************************************/
void HlwMqttStat(byte option)
#ifdef USE_WEBSERVER
const char HTTP_ENERGY_SNS[] PROGMEM =
"{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"
"{s}" D_POWER_FACTOR "{m}%s{e}"
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
#endif // USE_WEBSERVER
void HlwShow(boolean json, boolean option)
{
/* option 0 = do not show period energy usage
* option 1 = show period energy usage
@ -685,17 +694,24 @@ void HlwMqttStat(byte option)
dtostrfd(current, 3, scurrent);
dtostrfd(power_factor, 2, spower_factor);
dtostrfd((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag.energy_resolution, syesterday_energy);
snprintf_P(speriod, sizeof(speriod), PSTR(", \"" D_PERIOD "\":%s"), senergy);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s%s, \"" D_POWERUSAGE "\":%s, \"" D_POWERFACTOR "\":%s, \"" D_VOLTAGE "\":%s, \"" D_CURRENT "\":%s}"),
mqtt_data, stotal_energy, syesterday_energy, sdaily_energy, (option) ? speriod : "", swatts, spower_factor, svoltage, scurrent);
if (json) {
snprintf_P(speriod, sizeof(speriod), PSTR(", \"" D_PERIOD "\":%s"), senergy);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s%s, \"" D_POWERUSAGE "\":%s, \"" D_POWERFACTOR "\":%s, \"" D_VOLTAGE "\":%s, \"" D_CURRENT "\":%s}"),
mqtt_data, stotal_energy, syesterday_energy, sdaily_energy, (option) ? speriod : "", swatts, spower_factor, svoltage, scurrent);
#ifdef USE_DOMOTICZ
if (option) { // Only send if telemetry
dtostrfd(total_energy * 1000, 1, stotal_energy);
DomoticzSensorPowerEnergy((uint16_t)watts, stotal_energy); // PowerUsage, EnergyToday
DomoticzSensor(DZ_VOLTAGE, svoltage); // Voltage
DomoticzSensor(DZ_CURRENT, scurrent); // Current
}
if (option) { // Only send if telemetry
dtostrfd(total_energy * 1000, 1, stotal_energy);
DomoticzSensorPowerEnergy((uint16_t)watts, stotal_energy); // PowerUsage, EnergyToday
DomoticzSensor(DZ_VOLTAGE, svoltage); // Voltage
DomoticzSensor(DZ_CURRENT, scurrent); // Current
}
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS, svoltage, scurrent, swatts, spower_factor, sdaily_energy, syesterday_energy, stotal_energy);
#endif // USE_WEBSERVER
}
}
void MqttShowHlw8012(byte option)
@ -705,54 +721,45 @@ void MqttShowHlw8012(byte option)
*/
// {"Time":"2017-03-04T13:37:24", "Total":0.013, "Yesterday":0.013, "Today":0.000, "Period":0, "Power":0, "Factor":0.00, "Voltage":0, "Current":0.000}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\", "), GetDateAndTime().c_str());
HlwMqttStat(option);
HlwShow(1, option);
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
}
void HlwMqttStatus()
{
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS8_POWER "\":{"));
HlwMqttStat(0);
HlwShow(1, 0);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
}
#ifdef USE_WEBSERVER
const char HTTP_ENERGY_SNS[] PROGMEM =
"<tr><th>" D_VOLTAGE "</th><td>%s " D_UNIT_VOLT "</td></tr>"
"<tr><th>" D_CURRENT "</th><td>%s " D_UNIT_AMPERE "</td></tr>"
"<tr><th>" D_POWERUSAGE "</th><td>%s " D_UNIT_WATT "</td></tr>"
"<tr><th>" D_POWER_FACTOR "</th><td>%s</td></tr>"
"<tr><th>" D_ENERGY_TODAY "</th><td>%s " D_UNIT_KILOWATTHOUR "</td></tr>"
"<tr><th>" D_ENERGY_YESTERDAY "</th><td>%s " D_UNIT_KILOWATTHOUR "</td></tr>"
"<tr><th>" D_ENERGY_TOTAL "</th><td>%s " D_UNIT_KILOWATTHOUR "</td></tr>";
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
String WebShowHlw()
#define XSNS_03
boolean Xsns03(byte function)
{
float total_energy;
float daily_energy;
float energy;
float watts;
float voltage;
float current;
float power_factor;
char stotal_energy[10];
char sdaily_energy[10];
char swatts[10];
char svoltage[10];
char scurrent[10];
char spower_factor[10];
char syesterday_energy[10];
char sensor[400];
boolean result = false;
HlwReadEnergy(0, total_energy, daily_energy, energy, watts, voltage, current, power_factor);
dtostrfi(total_energy, Settings.flag.energy_resolution, stotal_energy);
dtostrfi(daily_energy, Settings.flag.energy_resolution, sdaily_energy);
dtostrfi(watts, Settings.flag.wattage_resolution, swatts);
dtostrfi(voltage, Settings.flag.voltage_resolution, svoltage);
dtostrfi(current, 3, scurrent);
dtostrfi(power_factor, 2, spower_factor);
dtostrfi((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag.energy_resolution, syesterday_energy);
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, svoltage, scurrent, swatts, spower_factor, sdaily_energy, syesterday_energy, stotal_energy);
return String(sensor);
}
if (hlw_flg) {
switch (function) {
case FUNC_XSNS_INIT:
HlwInit();
break;
// case FUNC_XSNS_PREP:
// break;
// case FUNC_XSNS_JSON_APPEND:
// break;
case FUNC_XSNS_MQTT_SHOW:
MqttShowHlw8012(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
HlwShow(0, 0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}

View File

@ -1,5 +1,5 @@
/*
xdrv_snfsc.ino - sonoff SC support for Sonoff-Tasmota
xsns_04_snfsc.ino - sonoff SC support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -101,56 +101,66 @@ void SonoffScSerialInput(char *rcvstat)
}
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowSonoffSC(uint8_t* djson)
{
if (sc_value[0] > 0) {
char stemp1[10];
char stemp2[10];
float t = ConvertTemp(sc_value[1]);
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
float h = sc_value[0];
dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"),
mqtt_data, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(stemp1, stemp2);
DomoticzSensor(DZ_ILLUMINANCE, sc_value[2]);
#endif // USE_DOMOTICZ
}
}
/********************************************************************************************/
#ifdef USE_WEBSERVER
String WebShowSonoffSc()
{
String page = "";
if (sc_value[0] > 0) {
char stemp[10];
char sensor[80];
char scstype[] = "";
float t = ConvertTemp(sc_value[1]);
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, TempUnit());
page += sensor;
float h = sc_value[0];
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, scstype, stemp);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_LIGHT, scstype, sc_value[2]);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_NOISE, scstype, sc_value[3]);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_DUST, scstype, sc_value[4]);
page += sensor;
}
return page;
}
const char HTTP_SNS_SCPLUS[] PROGMEM =
"%s{s}" D_LIGHT "{m}%d%{e}{s}" D_NOISE "{m}%d%{e}{s}" D_AIR_QUALITY "{m}%d%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
#endif // USE_WEBSERVER
void SonoffScShow(boolean json)
{
if (sc_value[0] > 0) {
char temperature[10];
char humidity[10];
float t = ConvertTemp(sc_value[1]);
float h = sc_value[0];
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity);
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"),
mqtt_data, temperature, humidity, sc_value[2], sc_value[3], sc_value[4]);
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(temperature, humidity);
DomoticzSensor(DZ_ILLUMINANCE, sc_value[2]);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "", temperature, TempUnit());
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, "", humidity);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SCPLUS, mqtt_data, sc_value[2], sc_value[3], sc_value[4]);
#endif // USE_WEBSERVER
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_04
boolean Xsns04(byte function)
{
boolean result = false;
if (SONOFF_SC == Settings.module) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
// case FUNC_XSNS_PREP:
// break;
case FUNC_XSNS_JSON_APPEND:
SonoffScShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
SonoffScShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}

View File

@ -1,5 +1,5 @@
/*
xsns_ds18b20.ino - DS18B20 temperature sensor support for Sonoff-Tasmota
xsns_05_ds18b20.ino - DS18B20 temperature sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -181,42 +181,63 @@ boolean Ds18b20ReadTemperature(float &t)
return !isnan(t);
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
/********************************************************************************************/
void MqttShowDs18b20(uint8_t* djson)
void Ds18b20Show(boolean json)
{
char stemp1[10];
float t;
if (Ds18b20ReadTemperature(t)) { // Check if read failed
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), mqtt_data, stemp1);
*djson = 1;
char temperature[10];
dtostrfi(t, Settings.flag.temperature_resolution, temperature);
if(json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), mqtt_data, temperature);
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_TEMP, stemp1);
DomoticzSensor(DZ_TEMP, temperature);
#endif // USE_DOMOTICZ
}
}
#ifdef USE_WEBSERVER
String WebShowDs18b20()
{
// Needs TelePeriod to refresh data (Do not do it here as it takes too much time)
String page = "";
float st;
if (Ds18b20ReadTemperature(st)) { // Check if read failed
char stemp[10];
char sensor[80];
dtostrfi(st, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, TempUnit());
page += sensor;
}
Ds18b20ReadTempPrep();
return page;
}
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "DS18B20", temperature, TempUnit());
#endif // USE_WEBSERVER
}
}
#ifdef USE_WEBSERVER
if (!json) {
Ds18b20ReadTempPrep();
}
#endif // USE_WEBSERVER
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_05
boolean Xsns05(byte function)
{
boolean result = false;
if (pin[GPIO_DSB] < 99) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Ds18b20ReadTempPrep();
break;
case FUNC_XSNS_JSON_APPEND:
Ds18b20Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
Ds18b20Show(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_DS18B20

View File

@ -1,5 +1,5 @@
/*
xsns_ds18x20.ino - DS18x20 temperature sensor support for Sonoff-Tasmota
xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Sonoff-Tasmota
Copyright (C) 2017 Heiko Krupp and Theo Arends
@ -143,79 +143,100 @@ boolean Ds18x20Read(uint8_t sensor, float &t)
return (!isnan(t));
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
/********************************************************************************************/
void Ds18x20Type(uint8_t sensor)
{
strcpy_P(ds18x20_types, PSTR("DS18x20"));
switch(ds18x20_address[ds18x20_index[sensor]][0]) {
case DS18S20_CHIPID:
strcpy_P(ds18x20_types, PSTR("DS18S20"));
break;
case DS18B20_CHIPID:
strcpy_P(ds18x20_types, PSTR("DS18B20"));
break;
case MAX31850_CHIPID:
strcpy_P(ds18x20_types, PSTR("MAX31850"));
break;
case DS18S20_CHIPID:
strcpy_P(ds18x20_types, PSTR("DS18S20"));
break;
case DS18B20_CHIPID:
strcpy_P(ds18x20_types, PSTR("DS18B20"));
break;
case MAX31850_CHIPID:
strcpy_P(ds18x20_types, PSTR("MAX31850"));
break;
}
}
void MqttShowDs18x20(uint8_t* djson)
void Ds18x20Show(boolean json)
{
char stemp1[10];
char stemp2[10];
char temperature[10];
char stemp[10];
float t;
byte dsxflg = 0;
for (byte i = 0; i < Ds18x20Sensors(); i++) {
if (Ds18x20Read(i, t)) { // Check if read failed
Ds18x20Type(i);
dtostrfd(t, Settings.flag.temperature_resolution, stemp2);
if (!dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18x20\":{"), mqtt_data);
*djson = 1;
stemp1[0] = '\0';
}
dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\", \"" D_ADDRESS "\":\"%s\", \"" D_TEMPERATURE "\":%s}"),
mqtt_data, stemp1, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), stemp2);
strcpy(stemp1, ", ");
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
if (json) {
if (!dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18x20\":{"), mqtt_data);
stemp[0] = '\0';
}
dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\", \"" D_ADDRESS "\":\"%s\", \"" D_TEMPERATURE "\":%s}"),
mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature);
strcpy(stemp, ", ");
#ifdef USE_DOMOTICZ
if (1 == dsxflg) {
DomoticzSensor(DZ_TEMP, stemp2);
}
if (1 == dsxflg) {
DomoticzSensor(DZ_TEMP, temperature);
}
#endif // USE_DOMOTICZ
}
}
if (dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
}
}
#ifdef USE_WEBSERVER
String WebShowDs18x20()
{
String page = "";
char stemp[10];
char stemp2[16];
char sensor[80];
float t;
for (byte i = 0; i < Ds18x20Sensors(); i++) {
if (Ds18x20Read(i, t)) { // Check if read failed
Ds18x20Type(i);
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(stemp2, sizeof(stemp2), PSTR("%s-%d"), ds18x20_types, i +1);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, TempUnit());
page += sensor;
} else {
snprintf_P(stemp, sizeof(stemp), PSTR("%s-%d"), ds18x20_types, i +1);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, stemp, temperature, TempUnit());
#endif // USE_WEBSERVER
}
}
}
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
return page;
}
if (json) {
if (dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
}
#ifdef USE_WEBSERVER
} else {
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
#endif // USE_WEBSERVER
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_05
boolean Xsns05(byte function)
{
boolean result = false;
if (pin[GPIO_DSB] < 99) {
switch (function) {
case FUNC_XSNS_INIT:
Ds18x20Init();
break;
case FUNC_XSNS_PREP:
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
break;
case FUNC_XSNS_JSON_APPEND:
Ds18x20Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
Ds18x20Show(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_DS18x20

View File

@ -1,5 +1,5 @@
/*
xsns_dht.ino - DHTxx and AM23xx temperature and humidity sensor support for Sonoff-Tasmota
xsns_06_dht.ino - DHTxx and AM23xx temperature and humidity sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -194,6 +194,8 @@ boolean DhtSetup(byte pin, byte type)
return success;
}
/********************************************************************************************/
void DhtInit()
{
dht_max_cycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for reading pulses from DHT sensor.
@ -218,54 +220,66 @@ void DhtInit()
}
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowDht(uint8_t* djson)
void DhtShow(boolean json)
{
char stemp1[10];
char stemp2[10];
char temperature[10];
char humidity[10];
float t;
float h;
byte dsxflg = 0;
for (byte i = 0; i < dht_sensors; i++) {
if (DhtReadTempHum(i, t, h)) { // Read temperature
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, stemp1, stemp2);
*djson = 1;
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity);
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, temperature, humidity);
#ifdef USE_DOMOTICZ
if (!dsxflg) {
DomoticzTempHumSensor(stemp1, stemp2);
dsxflg++;
}
if (!dsxflg) {
DomoticzTempHumSensor(temperature, humidity);
dsxflg++;
}
#endif // USE_DOMOTICZ
}
}
}
#ifdef USE_WEBSERVER
String WebShowDht()
{
String page = "";
char stemp[10];
char sensor[80];
float t;
float h;
for (byte i = 0; i < dht_sensors; i++) {
if (DhtReadTempHum(i, t, h)) {
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, Dht[i].stype, stemp, TempUnit());
page += sensor;
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, Dht[i].stype, stemp);
page += sensor;
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, Dht[i].stype, temperature, TempUnit());
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, Dht[i].stype, humidity);
#endif // USE_WEBSERVER
}
}
}
return page;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_06
boolean Xsns06(byte function)
{
boolean result = false;
if (dht_flg) {
switch (function) {
case FUNC_XSNS_INIT:
DhtInit();
break;
case FUNC_XSNS_PREP:
DhtReadPrep();
break;
case FUNC_XSNS_JSON_APPEND:
DhtShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
DhtShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_DHT

View File

@ -1,5 +1,5 @@
/*
xsns_sht1x.ino - SHT1x temperature and sensor support for Sonoff-Tasmota
xsns_07_sht1x.ino - SHT1x temperature and sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -159,6 +159,8 @@ boolean ShtReadTempHum(float &t, float &h)
return (!isnan(t) && !isnan(h));
}
/********************************************************************************************/
boolean ShtDetect()
{
if (sht_type) {
@ -180,56 +182,63 @@ boolean ShtDetect()
return sht_type;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowSht(uint8_t* djson)
void ShtShow(boolean json)
{
if (!sht_type) {
return;
}
float t;
float h;
if (ShtReadTempHum(t, h)) {
char stemp[10];
char shum[10];
dtostrfd(t, Settings.flag.temperature_resolution, stemp);
dtostrfd(h, Settings.flag.humidity_resolution, shum);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", stemp, shum);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(stemp, shum);
#endif // USE_DOMOTICZ
}
}
#ifdef USE_WEBSERVER
String WebShowSht()
{
float t;
float h;
String page = "";
if (sht_type) {
if (ShtReadTempHum(t, h)) {
char stemp[10];
char shum[10];
char sensor[80];
float t;
float h;
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
dtostrfi(h, Settings.flag.humidity_resolution, shum);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, TempUnit());
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, "SHT1X", shum);
page += sensor;
if (ShtReadTempHum(t, h)) {
char temperature[10];
char humidity[10];
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity);
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", temperature, humidity);
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(temperature, humidity);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "SHT1X", temperature, TempUnit());
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, "SHT1X", humidity);
#endif // USE_WEBSERVER
}
}
}
return page;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_07
boolean Xsns07(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
ShtDetect();
break;
case FUNC_XSNS_JSON_APPEND:
ShtShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
ShtShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_SHT
#endif // USE_I2C

View File

@ -1,5 +1,5 @@
/*
xsns_htu21.ino - HTU21 temperature and humidity sensor support for Sonoff-Tasmota
xsns_08_htu21.ino - HTU21 temperature and humidity sensor support for Sonoff-Tasmota
Copyright (C) 2017 Heiko Krupp and Theo Arends
@ -205,6 +205,8 @@ float HtuCompensatedHumidity(float humidity, float temperature)
}
}
/********************************************************************************************/
uint8_t HtuDetect()
{
if (htu_type) {
@ -243,7 +245,7 @@ uint8_t HtuDetect()
delay_humidity=23;
}
if (success) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), htu_types, htu_address);
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, htu_types, htu_address);
AddLog(LOG_LEVEL_DEBUG);
} else {
htu_type = 0;
@ -251,52 +253,62 @@ uint8_t HtuDetect()
return success;
}
void HtuShow(boolean json)
{
if (htu_type) {
char temperature[10];
char humidity[10];
float t = HtuReadTemperature();
float h = HtuReadHumidity();
h = HtuCompensatedHumidity(h, t);
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
dtostrfd(h, Settings.flag.humidity_resolution, humidity);
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, temperature, humidity);
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(temperature, humidity);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, htu_types, temperature, TempUnit());
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, htu_types, humidity);
#endif // USE_WEBSERVER
}
}
}
/*********************************************************************************************\
* Presentation
* Interface
\*********************************************************************************************/
void MqttShowHtu(uint8_t* djson)
#define XSNS_08
boolean Xsns08(byte function)
{
if (!htu_type) {
return;
}
char stemp1[10];
char stemp2[10];
float t = HtuReadTemperature();
float h = HtuReadHumidity();
h = HtuCompensatedHumidity(h, t);
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(stemp1, stemp2);
#endif // USE_DOMOTICZ
}
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
HtuDetect();
break;
case FUNC_XSNS_JSON_APPEND:
HtuShow(1);
break;
#ifdef USE_WEBSERVER
String WebShowHtu()
{
String page = "";
if (htu_type) {
char stemp[10];
char sensor[80];
float t_htu21 = HtuReadTemperature();
float h_htu21 = HtuReadHumidity();
h_htu21 = HtuCompensatedHumidity(h_htu21, t_htu21);
dtostrfi(t_htu21, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htu_types, stemp, TempUnit());
page += sensor;
dtostrfi(h_htu21, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, htu_types, stemp);
page += sensor;
}
return page;
}
case FUNC_XSNS_WEB:
HtuShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_HTU
#endif // USE_I2C

View File

@ -1,5 +1,5 @@
/*
xsns_bmp.ino - BMP pressure, temperature and humidity sensor support for Sonoff-Tasmota
xsns_09_bmp.ino - BMP pressure, temperature and humidity sensor support for Sonoff-Tasmota
Copyright (C) 2017 Heiko Krupp and Theo Arends
@ -369,6 +369,8 @@ double BmpReadHumidity(void)
return 0;
}
/********************************************************************************************/
boolean BmpDetect()
{
if (bmp_type) {
@ -398,7 +400,7 @@ boolean BmpDetect()
strcpy_P(bmp_types, PSTR("BME280"));
}
if (success) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bmp_types, bmp_address);
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_types, bmp_address);
AddLog(LOG_LEVEL_DEBUG);
}
else {
@ -407,75 +409,80 @@ boolean BmpDetect()
return success;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowBmp(uint8_t *djson)
void BmpShow(boolean json)
{
if (!bmp_type) {
return;
}
char temperature[10];
char pressure[10];
char humidity[10];
char sea_pressure[10];
char sealevel[40];
double t = BmpReadTemperature();
double p = BmpReadPressure();
double h = BmpReadHumidity();
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
dtostrfd(p, Settings.flag.pressure_resolution, pressure);
dtostrfd(h, Settings.flag.humidity_resolution, humidity);
dtostrfd(bmp_sealevel, Settings.flag.pressure_resolution, sea_pressure);
snprintf_P(sealevel, sizeof(sealevel), PSTR(", \"" D_PRESSUREATSEALEVEL "\":%s"), sea_pressure);
if (BME280_CHIPID == bmp_type) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, humidity, pressure, (Settings.altitude != 0) ? sealevel : "");
}
else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, pressure, (Settings.altitude != 0) ? sealevel : "");
}
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzTempHumPressureSensor(temperature, humidity, pressure);
#endif // USE_DOMOTICZ
}
#ifdef USE_WEBSERVER
String WebShowBmp()
{
String page = "";
if (bmp_type) {
char stemp[10];
char sensor[80];
char temperature[10];
char pressure[10];
char humidity[10];
char sea_pressure[10];
char sealevel[40];
double t = BmpReadTemperature();
double p = BmpReadPressure();
double h = BmpReadHumidity();
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmp_types, stemp, TempUnit());
page += sensor;
if (BME280_CHIPID == bmp_type) {
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, bmp_types, stemp);
page += sensor;
}
dtostrfi(p, Settings.flag.pressure_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSURE, bmp_types, stemp);
page += sensor;
if (Settings.altitude != 0) {
dtostrfi(bmp_sealevel, Settings.flag.pressure_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSUREATSEALEVEL, bmp_types, stemp);
page += sensor;
dtostrfd(t, Settings.flag.temperature_resolution, temperature);
dtostrfd(p, Settings.flag.pressure_resolution, pressure);
dtostrfd(h, Settings.flag.humidity_resolution, humidity);
dtostrfd(bmp_sealevel, Settings.flag.pressure_resolution, sea_pressure);
if (json) {
snprintf_P(sealevel, sizeof(sealevel), PSTR(", \"" D_PRESSUREATSEALEVEL "\":%s"), sea_pressure);
if (BME280_CHIPID == bmp_type) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, humidity, pressure, (Settings.altitude != 0) ? sealevel : "");
}
else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, pressure, (Settings.altitude != 0) ? sealevel : "");
}
#ifdef USE_DOMOTICZ
DomoticzTempHumPressureSensor(temperature, humidity, pressure);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, bmp_types, temperature, TempUnit());
if (BME280_CHIPID == bmp_type) {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, bmp_types, humidity);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, bmp_types, pressure);
if (Settings.altitude != 0) {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, bmp_types, sea_pressure);
}
#endif // USE_WEBSERVER
}
}
return page;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_09
boolean Xsns09(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
BmpDetect();
break;
case FUNC_XSNS_JSON_APPEND:
BmpShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
BmpShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_BMP
#endif // USE_I2C

View File

@ -1,5 +1,5 @@
/*
xsns_bh1750.ino - BH1750 ambient light sensor support for Sonoff-Tasmota
xsns_10_bh1750.ino - BH1750 ambient light sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -30,7 +30,6 @@
uint8_t bh1750_address;
uint8_t bh1750_type = 0;
char bh1750_types[7];
uint16_t Bh1750ReadLux()
{
@ -41,6 +40,8 @@ uint16_t Bh1750ReadLux()
return value;
}
/********************************************************************************************/
boolean Bh1750Detect()
{
if (bh1750_type) {
@ -63,10 +64,9 @@ boolean Bh1750Detect()
if (!status) {
success = true;
bh1750_type = 1;
strcpy_P(bh1750_types, PSTR("BH1750"));
}
if (success) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bh1750_types, bh1750_address);
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "BH1750", bh1750_address);
AddLog(LOG_LEVEL_DEBUG);
} else {
bh1750_type = 0;
@ -74,39 +74,58 @@ boolean Bh1750Detect()
return success;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowBh1750(uint8_t* djson)
{
if (!bh1750_type) {
return;
}
uint16_t l = Bh1750ReadLux();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, bh1750_types, l);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, l);
#endif // USE_DOMOTICZ
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_ILLUMINANCE[] PROGMEM =
"<tr><th>BH1750 " D_ILLUMINANCE "</th><td>%d " D_UNIT_LUX "</td></tr>";
String WebShowBh1750()
{
String page = "";
if (bh1750_type) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_ILLUMINANCE, Bh1750ReadLux());
page += sensor;
}
return page;
}
"%s{s}BH1750 " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
#endif // USE_WEBSERVER
void Bh1750Show(boolean json)
{
if (bh1750_type) {
uint16_t illuminance = Bh1750ReadLux();
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"BH1750\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, illuminance);
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, illuminance);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ILLUMINANCE, mqtt_data, illuminance);
#endif // USE_WEBSERVER
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_10
boolean Xsns10(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Bh1750Detect();
break;
case FUNC_XSNS_JSON_APPEND:
Bh1750Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
Bh1750Show(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_BH1750
#endif // USE_I2C

View File

@ -1,5 +1,5 @@
/*
xsns_veml6070.ino - VEML6070 ultra violet light sensor support for Sonoff-Tasmota
xsns_11_veml6070.ino - VEML6070 ultra violet light sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
@ -44,9 +44,11 @@ uint16_t Veml6070ReadUv()
}
uvi |= Wire.read();
return uvi;
return uvi;
}
/********************************************************************************************/
boolean Veml6070Detect()
{
if (veml6070_type) {
@ -67,7 +69,7 @@ boolean Veml6070Detect()
strcpy_P(veml6070_types, PSTR("VEML6070"));
}
if (success) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), veml6070_types, veml6070_address);
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, veml6070_types, veml6070_address);
AddLog(LOG_LEVEL_DEBUG);
} else {
veml6070_type = 0;
@ -75,39 +77,59 @@ boolean Veml6070Detect()
return success;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowVeml6070(uint8_t* djson)
{
if (!veml6070_type) {
return;
}
uint16_t uv = Veml6070ReadUv();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_UV_LEVEL "\":%d}"), mqtt_data, veml6070_types, uv);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, uv);
#endif // USE_DOMOTICZ
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_ULTRAVIOLET[] PROGMEM =
"<tr><th>VEML6070 " D_UV_LEVEL "</th><td>%d</td></tr>";
String WebShowVeml6070()
{
String page = "";
if (veml6070_type) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_ULTRAVIOLET, Veml6070ReadUv());
page += sensor;
}
return page;
}
"%s{s}VEML6070 " D_UV_LEVEL "{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
#endif // USE_WEBSERVER
void Veml6070Show(boolean json)
{
if (veml6070_type) {
uint16_t uvlevel = Veml6070ReadUv();
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_UV_LEVEL "\":%d}"), mqtt_data, veml6070_types, uvlevel);
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, uvlevel);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ULTRAVIOLET, mqtt_data, uvlevel);
#endif // USE_WEBSERVER
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_11
boolean Xsns11(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Veml6070Detect();
break;
case FUNC_XSNS_JSON_APPEND:
Veml6070Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
Veml6070Show(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_VEML6070
#endif // USE_I2C

166
sonoff/xsns_12_ads1115.ino Normal file
View File

@ -0,0 +1,166 @@
/*
xsns_12_ads1115.ino - ADS1x15 A/D Converter support for Sonoff-Tasmota
Copyright (C) 2017 Stefan Bode and Theo Arends
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_ADS1115
/*********************************************************************************************\
* ADS1115 - 4 channel 16BIT A/D converter
*
* Required library: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/ADS1115
*
* The ADC input range (or gain) can be changed via the following
* functions, but be careful never to exceed VDD +0.3V max, or to
* exceed the upper and lower limits if you adjust the input range!
* Setting these values incorrectly may destroy your ADC!
* ADS1015 ADS1115
* ------- -------
* ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
* ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
* ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV
* ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV
* ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV
* ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV
\*********************************************************************************************/
#include <ADS1115.h>
ADS1115 adc0;
uint8_t ads1115_address;
uint8_t ads1115_type = 0;
uint8_t ads1115_addresses[] = {
ADS1115_ADDRESS_ADDR_GND, // address pin low (GND)
ADS1115_ADDRESS_ADDR_VDD, // address pin high (VCC)
ADS1115_ADDRESS_ADDR_SDA, // address pin tied to SDA pin
ADS1115_ADDRESS_ADDR_SCL // address pin tied to SCL pin
};
int16_t Ads1115GetConversion(byte channel)
{
switch (channel) {
case 0:
adc0.getConversionP0GND();
break;
case 1:
adc0.getConversionP1GND();
break;
case 2:
adc0.getConversionP2GND();
break;
case 3:
adc0.getConversionP3GND();
break;
}
}
/********************************************************************************************/
boolean Ads1115Detect()
{
if (ads1115_type) {
return true;
}
uint8_t status;
boolean success = false;
for (byte i = 0; i < 4; i++) {
ads1115_address = ads1115_addresses[i];
ADS1115 adc0(ads1115_address);
if (adc0.testConnection()) {
adc0.initialize();
adc0.setGain(ADS1115_PGA_2P048); // Set the gain (PGA) +/-4.096V
adc0.setRate(ADS1115_RATE_860);
adc0.setMode(ADS1115_MODE_CONTINUOUS);
success = true;
ads1115_type = 1;
break;
}
}
if (success) {
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address);
AddLog(LOG_LEVEL_DEBUG);
}
return success;
}
void Ads1115Show(boolean json)
{
if (ads1115_type) {
char stemp[10];
byte dsxflg = 0;
for (byte i = 0; i < 4; i++) {
int16_t adc_value = Ads1115GetConversion(i);
if (json) {
if (!dsxflg ) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"ADS1115\":{"), mqtt_data);
stemp[0] = '\0';
}
dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_ANALOG_INPUT "%d\":%d"), mqtt_data, stemp, i, adc_value);
strcpy(stemp, ", ");
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);
#endif // USE_WEBSERVER
}
}
if (json) {
if (dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
}
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_12
boolean Xsns12(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Ads1115Detect();
break;
case FUNC_XSNS_JSON_APPEND:
Ads1115Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
Ads1115Show(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_ADS1115
#endif // USE_I2C

131
sonoff/xsns_interface.ino Normal file
View File

@ -0,0 +1,131 @@
/*
xsns_interface.ino - External sensor interface support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends inspired by ESPEasy
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/>.
*/
void XSnsInit()
{
for (byte i = 0; i < XSNS_MAX; i++) {
xsns_func_ptr[i] = NULL;
}
xsns_present = 0;
#ifdef XSNS_01
xsns_func_ptr[xsns_present++] = &Xsns01;
#endif
#ifdef XSNS_02
xsns_func_ptr[xsns_present++] = &Xsns02;
#endif
#ifdef XSNS_03
xsns_func_ptr[xsns_present++] = &Xsns03;
#endif
#ifdef XSNS_04
xsns_func_ptr[xsns_present++] = &Xsns04;
#endif
#ifdef XSNS_05
xsns_func_ptr[xsns_present++] = &Xsns05;
#endif
#ifdef XSNS_06
xsns_func_ptr[xsns_present++] = &Xsns06;
#endif
#ifdef XSNS_07
xsns_func_ptr[xsns_present++] = &Xsns07;
#endif
#ifdef XSNS_08
xsns_func_ptr[xsns_present++] = &Xsns08;
#endif
#ifdef XSNS_09
xsns_func_ptr[xsns_present++] = &Xsns09;
#endif
#ifdef XSNS_10
xsns_func_ptr[xsns_present++] = &Xsns10;
#endif
#ifdef XSNS_11
xsns_func_ptr[xsns_present++] = &Xsns11;
#endif
#ifdef XSNS_12
xsns_func_ptr[xsns_present++] = &Xsns12;
#endif
#ifdef XSNS_13
xsns_func_ptr[xsns_present++] = &Xsns13;
#endif
#ifdef XSNS_14
xsns_func_ptr[xsns_present++] = &Xsns14;
#endif
#ifdef XSNS_15
xsns_func_ptr[xsns_present++] = &Xsns15;
#endif
#ifdef XSNS_16
xsns_func_ptr[xsns_present++] = &Xsns16;
#endif
#ifdef XSNS_17
xsns_func_ptr[xsns_present++] = &Xsns17;
#endif
#ifdef XSNS_18
xsns_func_ptr[xsns_present++] = &Xsns18;
#endif
#ifdef XSNS_19
xsns_func_ptr[xsns_present++] = &Xsns19;
#endif
#ifdef XSNS_20
xsns_func_ptr[xsns_present++] = &Xsns20;
#endif
XsnsCall(FUNC_XSNS_INIT);
}
/*********************************************************************************************\
* Function call to all xsns
\*********************************************************************************************/
boolean XsnsCall(byte Function)
{
boolean result = false;
switch (Function) {
case FUNC_XSNS_INIT:
case FUNC_XSNS_PREP:
case FUNC_XSNS_JSON_APPEND:
case FUNC_XSNS_MQTT_SHOW:
case FUNC_XSNS_WEB:
for (byte x = 0; x < xsns_present; x++) {
xsns_func_ptr[x](Function);
}
break;
}
return result;
}