From 6e49e161b2630ac6c5d939a10719ff1590e1f7d1 Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Sun, 12 Nov 2023 21:02:29 +0000 Subject: [PATCH 1/7] Changes from 11/12/2023. Switches made, need debug --- .../Adafruit_TSL2591.cpp | 2 +- .../tasmota_xsns_sensor/xsns_57_tsl2591.ino | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp index 57a0a67a92d1..2795dee6aae8 100644 --- a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp +++ b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp @@ -117,7 +117,7 @@ enum Adafruit_TSL2591::Adafruit_TSL2591() { _initialized = false; - _integration = TSL2591_INTEGRATIONTIME_100MS; + _integration = TSL2591_INTEGRATIONTIME_300MS; _gain = TSL2591_GAIN_MED; // we cant do wire initialization till later, because we havent loaded Wire yet diff --git a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino index 57d70f992293..ac5d8f2e7a51 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino @@ -90,6 +90,62 @@ void Tsl2591Show(bool json) } } +bool tsl2591CommandSensor() { + bool serviced = true; + + //tsl.setGain(TSL2591_GAIN_LOW); + //Response_P("test"); + + char argument[XdrvMailbox.data_len]; + + long value = 0; + for (uint32_t ca = 0; ca < XdrvMailbox.data_len; ca++) { + if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; } + } + + bool any_value = (strchr(XdrvMailbox.data, ',') != nullptr); + + if (any_value) { value = strtol(ArgV(argument, 2), nullptr, 10); } + + switch (XdrvMailbox.payload) { + case 1: + tsl.setGain(TSL2591_GAIN_LOW); + break; + case 2: + tsl.setGain(TSL2591_GAIN_MED); + break; + case 3: + tsl.setGain(TSL2591_GAIN_HIGH); + break; + case 4: + tsl.setGain(TSL2591_GAIN_MAX); + break; + } + if (any_value) { + switch (value) { + case 1: + tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); + break; + case 2: + tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS); + break; + case 3: + tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS); + break; + case 4: + tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS); + break; + case 5: + tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS); + break; + case 6: + tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); + break; + } + } + return serviced; +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -116,6 +172,11 @@ bool Xsns57(uint32_t function) Tsl2591Show(0); break; #endif // USE_WEBSERVER + case FUNC_COMMAND_SENSOR: + if (XSNS_57 == XdrvMailbox.index) { + result = tsl2591CommandSensor(); + } + break; } } return result; From 738bd235ea6df3b086c2348c202f34bdcf29beb1 Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Thu, 16 Nov 2023 19:46:05 +0000 Subject: [PATCH 2/7] Finalized gain/integration adjustment trees --- tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino index ac5d8f2e7a51..1dc718748797 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino @@ -92,21 +92,15 @@ void Tsl2591Show(bool json) bool tsl2591CommandSensor() { bool serviced = true; - - //tsl.setGain(TSL2591_GAIN_LOW); - //Response_P("test"); - char argument[XdrvMailbox.data_len]; - long value = 0; + for (uint32_t ca = 0; ca < XdrvMailbox.data_len; ca++) { if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; } } - + bool any_value = (strchr(XdrvMailbox.data, ',') != nullptr); - if (any_value) { value = strtol(ArgV(argument, 2), nullptr, 10); } - switch (XdrvMailbox.payload) { case 1: tsl.setGain(TSL2591_GAIN_LOW); @@ -143,6 +137,8 @@ bool tsl2591CommandSensor() { break; } } + Response_P(PSTR(" {Gain input = %d} {Gain hex = %d}"),XdrvMailbox.payload,tsl.getGain()); + ResponseAppend_P(PSTR(" {Timing input = %d} {Timing hex = %d}"),value,tsl.getTiming()); return serviced; } From 1d3d55c989f17952b34bc7fd917ace3fa35bab8c Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Thu, 30 Nov 2023 21:30:15 +0000 Subject: [PATCH 3/7] Fixed the bugs --- .../Adafruit_TSL2591.cpp | 2 +- .../tasmota_xsns_sensor/xsns_57_tsl2591.ino | 47 ++++--------------- 2 files changed, 10 insertions(+), 39 deletions(-) diff --git a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp index 2795dee6aae8..57a0a67a92d1 100644 --- a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp +++ b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp @@ -117,7 +117,7 @@ enum Adafruit_TSL2591::Adafruit_TSL2591() { _initialized = false; - _integration = TSL2591_INTEGRATIONTIME_300MS; + _integration = TSL2591_INTEGRATIONTIME_100MS; _gain = TSL2591_GAIN_MED; // we cant do wire initialization till later, because we havent loaded Wire yet diff --git a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino index 1dc718748797..1a76fc0bf163 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino @@ -39,6 +39,9 @@ uint8_t tsl2591_type = 0; uint8_t tsl2591_valid = 0; float tsl2591_lux = 0; +tsl2591Gain_t gain_enum_array[4] = {TSL2591_GAIN_LOW,TSL2591_GAIN_MED,TSL2591_GAIN_HIGH,TSL2591_GAIN_MAX}; +tsl2591IntegrationTime_t int_enum_array[6] = {TSL2591_INTEGRATIONTIME_100MS,TSL2591_INTEGRATIONTIME_200MS,TSL2591_INTEGRATIONTIME_300MS,TSL2591_INTEGRATIONTIME_400MS,TSL2591_INTEGRATIONTIME_500MS,TSL2591_INTEGRATIONTIME_600MS}; + void Tsl2591Init(void) { // if (I2cSetDevice(0x29) || I2cSetDevice(0x39) || I2cSetDevice(0x49)) { @@ -94,49 +97,17 @@ bool tsl2591CommandSensor() { bool serviced = true; char argument[XdrvMailbox.data_len]; long value = 0; - + for (uint32_t ca = 0; ca < XdrvMailbox.data_len; ca++) { if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; } } - + bool any_value = (strchr(XdrvMailbox.data, ',') != nullptr); if (any_value) { value = strtol(ArgV(argument, 2), nullptr, 10); } - switch (XdrvMailbox.payload) { - case 1: - tsl.setGain(TSL2591_GAIN_LOW); - break; - case 2: - tsl.setGain(TSL2591_GAIN_MED); - break; - case 3: - tsl.setGain(TSL2591_GAIN_HIGH); - break; - case 4: - tsl.setGain(TSL2591_GAIN_MAX); - break; - } - if (any_value) { - switch (value) { - case 1: - tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); - break; - case 2: - tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS); - break; - case 3: - tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS); - break; - case 4: - tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS); - break; - case 5: - tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS); - break; - case 6: - tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); - break; - } - } + + tsl.setGain(gain_enum_array[XdrvMailbox.payload-1]); + tsl.setTiming(int_enum_array[value-1]); + Response_P(PSTR(" {Gain input = %d} {Gain hex = %d}"),XdrvMailbox.payload,tsl.getGain()); ResponseAppend_P(PSTR(" {Timing input = %d} {Timing hex = %d}"),value,tsl.getTiming()); return serviced; From 9def89b86ae0f6c3bbbe0450f3aeb6fa4e402c40 Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Fri, 1 Dec 2023 18:00:40 +0000 Subject: [PATCH 4/7] Outputs in JSON, hex displays as hex was decimal --- tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino index 1a76fc0bf163..37f456beaf57 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino @@ -108,8 +108,8 @@ bool tsl2591CommandSensor() { tsl.setGain(gain_enum_array[XdrvMailbox.payload-1]); tsl.setTiming(int_enum_array[value-1]); - Response_P(PSTR(" {Gain input = %d} {Gain hex = %d}"),XdrvMailbox.payload,tsl.getGain()); - ResponseAppend_P(PSTR(" {Timing input = %d} {Timing hex = %d}"),value,tsl.getTiming()); + Response_P(PSTR("{\"Gain input\":%d,\"Gain hex\":0x%x,"),XdrvMailbox.payload,tsl.getGain()); + ResponseAppend_P(PSTR("\"Timing input\":%d,\"Timing hex\":0x0%x}"),value,tsl.getTiming()); return serviced; } From 04335ba6c59257fe9c30dc22d4cac00a3beea0c7 Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Tue, 12 Mar 2024 19:18:19 +0000 Subject: [PATCH 5/7] works but polishing code --- .../BlueRobotics_MS5837_Library/MS5837.cpp | 258 ++++++++++++++++++ .../BlueRobotics_MS5837_Library/MS5837.h | 113 ++++++++ .../tasmota_xsns_sensor/xsns_128_ms5837.ino | 113 ++++++++ 3 files changed, 484 insertions(+) create mode 100644 lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp create mode 100644 lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h create mode 100644 tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino diff --git a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp new file mode 100644 index 000000000000..3431e81272ab --- /dev/null +++ b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.cpp @@ -0,0 +1,258 @@ +#include "MS5837.h" +#include + +const uint8_t MS5837_ADDR = 0x76; +const uint8_t MS5837_RESET = 0x1E; +const uint8_t MS5837_ADC_READ = 0x00; +const uint8_t MS5837_PROM_READ = 0xA0; +const uint8_t MS5837_CONVERT_D1_8192 = 0x4A; +const uint8_t MS5837_CONVERT_D2_8192 = 0x5A; + +const float MS5837::Pa = 100.0f; +const float MS5837::bar = 0.001f; +const float MS5837::mbar = 1.0f; + +const uint8_t MS5837::MS5837_30BA = 0; +const uint8_t MS5837::MS5837_02BA = 1; +const uint8_t MS5837::MS5837_UNRECOGNISED = 255; + +const uint8_t MS5837_02BA01 = 0x00; // Sensor version: From MS5837_02BA datasheet Version PROM Word 0 +const uint8_t MS5837_02BA21 = 0x15; // Sensor version: From MS5837_02BA datasheet Version PROM Word 0 +const uint8_t MS5837_30BA26 = 0x1A; // Sensor version: From MS5837_30BA datasheet Version PROM Word 0 + +MS5837::MS5837() { + fluidDensity = 1029; +} + +bool MS5837::begin(TwoWire &wirePort) { + return (init(wirePort)); +} + +bool MS5837::init(TwoWire &wirePort) { + _i2cPort = &wirePort; //Grab which port the user wants us to use + + // Reset the MS5837, per datasheet + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_RESET); + _i2cPort->endTransmission(); + + // Wait for reset to complete + delay(10); + + // Read calibration values and CRC + for ( uint8_t i = 0 ; i < 7 ; i++ ) { + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_PROM_READ+i*2); + _i2cPort->endTransmission(); + + _i2cPort->requestFrom(MS5837_ADDR,2); + C[i] = (_i2cPort->read() << 8) | _i2cPort->read(); + } + + // Verify that data is correct with CRC + uint8_t crcRead = C[0] >> 12; + uint8_t crcCalculated = crc4(C); + + if ( crcCalculated != crcRead ) { + return false; // CRC fail + } + + uint8_t version = (C[0] >> 5) & 0x7F; // Extract the sensor version from PROM Word 0 + + // Set _model according to the sensor version + if (version == MS5837_02BA01) + { + _model = MS5837_02BA; + } + else if (version == MS5837_02BA21) + { + _model = MS5837_02BA; + } + else if (version == MS5837_30BA26) + { + _model = MS5837_30BA; + } + else + { + _model = MS5837_UNRECOGNISED; + } + // The sensor has passed the CRC check, so we should return true even if + // the sensor version is unrecognised. + // (The MS5637 has the same address as the MS5837 and will also pass the CRC check) + // (but will hopefully be unrecognised.) + return true; +} + +void MS5837::setModel(uint8_t model) { + _model = model; +} + +uint8_t MS5837::getModel() { + return (_model); +} + +void MS5837::setFluidDensity(float density) { + fluidDensity = density; +} + +void MS5837::read() { + //Check that _i2cPort is not NULL (i.e. has the user forgoten to call .init or .begin?) + if (_i2cPort == NULL) + { + return; + } + + // Request D1 conversion + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_CONVERT_D1_8192); + _i2cPort->endTransmission(); + + delay(20); // Max conversion time per datasheet + + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_ADC_READ); + _i2cPort->endTransmission(); + + _i2cPort->requestFrom(MS5837_ADDR,3); + D1_pres = 0; + D1_pres = _i2cPort->read(); + D1_pres = (D1_pres << 8) | _i2cPort->read(); + D1_pres = (D1_pres << 8) | _i2cPort->read(); + + // Request D2 conversion + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_CONVERT_D2_8192); + _i2cPort->endTransmission(); + + delay(20); // Max conversion time per datasheet + + _i2cPort->beginTransmission(MS5837_ADDR); + _i2cPort->write(MS5837_ADC_READ); + _i2cPort->endTransmission(); + + _i2cPort->requestFrom(MS5837_ADDR,3); + D2_temp = 0; + D2_temp = _i2cPort->read(); + D2_temp = (D2_temp << 8) | _i2cPort->read(); + D2_temp = (D2_temp << 8) | _i2cPort->read(); + + calculate(); +} + +void MS5837::calculate() { + // Given C1-C6 and D1, D2, calculated TEMP and P + // Do conversion first and then second order temp compensation + + int32_t dT = 0; + int64_t SENS = 0; + int64_t OFF = 0; + int32_t SENSi = 0; + int32_t OFFi = 0; + int32_t Ti = 0; + int64_t OFF2 = 0; + int64_t SENS2 = 0; + + // Terms called + dT = D2_temp-uint32_t(C[5])*256l; + if ( _model == MS5837_02BA ) { + SENS = int64_t(C[1])*65536l+(int64_t(C[3])*dT)/128l; + OFF = int64_t(C[2])*131072l+(int64_t(C[4])*dT)/64l; + P = (D1_pres*SENS/(2097152l)-OFF)/(32768l); + } else { + SENS = int64_t(C[1])*32768l+(int64_t(C[3])*dT)/256l; + OFF = int64_t(C[2])*65536l+(int64_t(C[4])*dT)/128l; + P = (D1_pres*SENS/(2097152l)-OFF)/(8192l); + } + + // Temp conversion + TEMP = 2000l+int64_t(dT)*C[6]/8388608LL; + + //Second order compensation + if ( _model == MS5837_02BA ) { + if((TEMP/100)<20){ //Low temp + Ti = (11*int64_t(dT)*int64_t(dT))/(34359738368LL); + OFFi = (31*(TEMP-2000)*(TEMP-2000))/8; + SENSi = (63*(TEMP-2000)*(TEMP-2000))/32; + } + } else { + if((TEMP/100)<20){ //Low temp + Ti = (3*int64_t(dT)*int64_t(dT))/(8589934592LL); + OFFi = (3*(TEMP-2000)*(TEMP-2000))/2; + SENSi = (5*(TEMP-2000)*(TEMP-2000))/8; + if((TEMP/100)<-15){ //Very low temp + OFFi = OFFi+7*(TEMP+1500l)*(TEMP+1500l); + SENSi = SENSi+4*(TEMP+1500l)*(TEMP+1500l); + } + } + else if((TEMP/100)>=20){ //High temp + Ti = 2*(dT*dT)/(137438953472LL); + OFFi = (1*(TEMP-2000)*(TEMP-2000))/16; + SENSi = 0; + } + } + + OFF2 = OFF-OFFi; //Calculate pressure and temp second order + SENS2 = SENS-SENSi; + + TEMP = (TEMP-Ti); + + if ( _model == MS5837_02BA ) { + P = (((D1_pres*SENS2)/2097152l-OFF2)/32768l); + } else { + P = (((D1_pres*SENS2)/2097152l-OFF2)/8192l); + } +} + +float MS5837::pressure(float conversion) { + if ( _model == MS5837_02BA ) { + return P*conversion/100.0f; + } + else { + return P*conversion/10.0f; + } +} + +float MS5837::temperature() { + return TEMP/100.0f; +} + +// The pressure sensor measures absolute pressure, so it will measure the atmospheric pressure + water pressure +// We subtract the atmospheric pressure to calculate the depth with only the water pressure +// The average atmospheric pressure of 101300 pascal is used for the calcuation, but atmospheric pressure varies +// If the atmospheric pressure is not 101300 at the time of reading, the depth reported will be offset +// In order to calculate the correct depth, the actual atmospheric pressure should be measured once in air, and +// that value should subtracted for subsequent depth calculations. +float MS5837::depth() { + return (pressure(MS5837::Pa)-101300)/(fluidDensity*9.80665); +} + +float MS5837::altitude() { + return (1-pow((pressure()/1013.25),.190284))*145366.45*.3048; +} + + +uint8_t MS5837::crc4(uint16_t n_prom[]) { + uint16_t n_rem = 0; + + n_prom[0] = ((n_prom[0]) & 0x0FFF); + n_prom[7] = 0; + + for ( uint8_t i = 0 ; i < 16; i++ ) { + if ( i%2 == 1 ) { + n_rem ^= (uint16_t)((n_prom[i>>1]) & 0x00FF); + } else { + n_rem ^= (uint16_t)(n_prom[i>>1] >> 8); + } + for ( uint8_t n_bit = 8 ; n_bit > 0 ; n_bit-- ) { + if ( n_rem & 0x8000 ) { + n_rem = (n_rem << 1) ^ 0x3000; + } else { + n_rem = (n_rem << 1); + } + } + } + + n_rem = ((n_rem >> 12) & 0x000F); + + return n_rem ^ 0x00; +} diff --git a/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h new file mode 100644 index 000000000000..8787de1b6a05 --- /dev/null +++ b/lib/lib_i2c/BlueRobotics_MS5837_Library/MS5837.h @@ -0,0 +1,113 @@ +/* Blue Robotics Arduino MS5837-30BA Pressure/Temperature Sensor Library +------------------------------------------------------------ + +Title: Blue Robotics Arduino MS5837-30BA Pressure/Temperature Sensor Library + +Description: This library provides utilities to communicate with and to +read data from the Measurement Specialties MS5837-30BA pressure/temperature +sensor. + +Authors: Rustom Jehangir, Blue Robotics Inc. + Adam Å imko, Blue Robotics Inc. + +------------------------------- +The MIT License (MIT) + +Copyright (c) 2015 Blue Robotics Inc. + +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 MS5837_H_BLUEROBOTICS +#define MS5837_H_BLUEROBOTICS + +#include "Arduino.h" +#include + +class MS5837 { +public: + static const float Pa; + static const float bar; + static const float mbar; + + static const uint8_t MS5837_30BA; + static const uint8_t MS5837_02BA; + static const uint8_t MS5837_UNRECOGNISED; + + MS5837(); + + bool init(TwoWire &wirePort = Wire); + bool begin(TwoWire &wirePort = Wire); // Calls init() + + /** Set model of MS5837 sensor. Valid options are MS5837::MS5837_30BA (default) + * and MS5837::MS5837_02BA. + */ + void setModel(uint8_t model); + uint8_t getModel(); + + /** Provide the density of the working fluid in kg/m^3. Default is for + * seawater. Should be 997 for freshwater. + */ + void setFluidDensity(float density); + + /** The read from I2C takes up to 40 ms, so use sparingly is possible. + */ + void read(); + + /** Pressure returned in mbar or mbar*conversion rate. + */ + float pressure(float conversion = 1.0f); + + /** Temperature returned in deg C. + */ + float temperature(); + + /** Depth returned in meters (valid for operation in incompressible + * liquids only. Uses density that is set for fresh or seawater. + */ + float depth(); + + /** Altitude returned in meters (valid for operation in air only). + */ + float altitude(); + + uint8_t crc4(uint16_t n_prom[]); + +private: + + //This stores the requested i2c port + TwoWire * _i2cPort; + + uint16_t C[8]; + uint32_t D1_pres, D2_temp; + int32_t TEMP; + int32_t P; + uint8_t _model; + + float fluidDensity; + + /** Performs calculations per the sensor data sheet for conversion and + * second order compensation. + */ + void calculate(); + + //uint8_t crc4(uint16_t n_prom[]); +}; + +#endif diff --git a/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino new file mode 100644 index 000000000000..e13e4493d18d --- /dev/null +++ b/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino @@ -0,0 +1,113 @@ +/* + xsns_14_sht3x.ino - SHT3X, SHT4X and SHTCX temperature and humidity sensor support for Tasmota + + Copyright (C) 2022 Theo Arends, Stefan Tibus + + 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 . +*/ + +#ifdef USE_I2C +#ifdef USE_MS5837 + +#define MS5837_ADDR 0x76 + +#define XSNS_128 128 +#define XI2C_98 98 // See I2CDEVICES.md +/*********************************************************************************************\ + * BlueRobotics Pressure Sensor + * + * This driver supports the following sensors: + * - BlueRobotics MS5837 +\*********************************************************************************************/ + +#include +#include + +MS5837 sensor_ms5837; + +uint8_t ms5837_start = 0; + +/********************************************************************************************/ + +void MS5837init(void) { + + if (I2cSetDevice(0x76)) { + TwoWire& myWire = I2cGetWire(); + + if(sensor_ms5837.init(myWire)) { + sensor_ms5837.setModel(sensor_ms5837.MS5837_02BA); + sensor_ms5837.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater) + ms5837_start = 1; + I2cSetActiveFound(MS5837_ADDR, "MS5837"); + } + } + AddLog(LOG_LEVEL_DEBUG, PSTR("BME: Gas variant %d"), bme_dev[bmp_idx].variant_id); +} + +#ifdef USE_WEBSERVER +const char HTTP_SNS_MS5837[] PROGMEM = + "{s}MS5837 Pressure {m}%s hPa{e}{s}MS5837 Temperature {m}%s C{e}"; // {s} = , {m} = , {e} = +#endif // USE_WEBSERVER + +void MS5837Show(bool json) { + sensor_ms5837.read(); + + char temperature_str[8]; + dtostrf(sensor_ms5837.temperature(), sizeof(temperature_str)-1, 3, temperature_str); + char pressure_str[8]; + dtostrf(sensor_ms5837.pressure(), sizeof(pressure_str)-1, 3, pressure_str); + if (json) { + ResponseAppend_P(PSTR(",\"MS5837\":{\"Temperature\":%s,"), temperature_str); + ResponseAppend_P(PSTR("\"Pressure\":%s}"), pressure_str); +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_MS5837, pressure_str, temperature_str); +#endif // USE_WEBSERVER + } + if (I2cEnabled(XI2C_10)) { + pressure_delta = sensor_ms5837.pressure() - bmp_sensors[0].bmp_pressure; + inches_water = pressure_delta*0.401463078662; + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns128(uint32_t function) { + //if (!I2cEnabled(XI2C_98)) { return false; } + + bool result = false; + //I2cScan(); + + if (FUNC_INIT == function) { + MS5837init(); + } + else if (ms5837_start) { + switch (function) { + case FUNC_JSON_APPEND: + MS5837Show(1); + break; + #ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + MS5837Show(0); + break; + #endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_SHT3X +#endif // USE_I2C From ee0fb81477cc1ca19248aac5437063133500d73f Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Tue, 12 Mar 2024 20:01:50 +0000 Subject: [PATCH 6/7] need to debug pressure in bmp --- tasmota/include/tasmota_configurations.h | 1 + tasmota/include/tasmota_configurations_ESP32.h | 2 ++ tasmota/my_user_config.h | 1 + tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino | 7 ++++--- tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino | 2 +- tasmota/tasmota_xx2c_global/xsns_interface.ino | 14 ++++++++++++-- tasmota/tasmota_xx2c_global/xx2c_interface.ino | 10 +++++++++- tools/decode-status.py | 2 +- 10 files changed, 33 insertions(+), 10 deletions(-) diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h index b556267943f8..8e33d6085450 100644 --- a/tasmota/include/tasmota_configurations.h +++ b/tasmota/include/tasmota_configurations.h @@ -168,6 +168,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) +#define USE_MS5837 //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index ac46ac568e93..ed56858b27c3 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -476,6 +476,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) +#define USE_MS5837 //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) @@ -712,6 +713,7 @@ //#define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code) //#define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code) //#define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code) +#define USE_MS5837 //#define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 7e918a675fd1..107f710df410 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -718,6 +718,7 @@ // #define USE_PCA9557 // [I2cDriver81] Enable PCA9557 8-bit I/O Expander (I2C addresses 0x18 - 0x1F) (+2k5 code) // #define USE_MAX17043 // [I2cDriver83] Enable MAX17043 fuel-gauge systems Lipo batteries sensor (I2C address 0x36) (+0k9 code) // #define MAX17043_ALERT_THRESHOLD 32 // [I2cDriver83] Define the alert threshold for low battery level percentage 1-32 + #define USE_MS5837 // #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one // #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) diff --git a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino index b9ed27082ba5..445eb4d88e6b 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - + #ifdef USE_I2C #ifdef USE_BMP /*********************************************************************************************\ diff --git a/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino index e13e4493d18d..ce998f6ad5b0 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino @@ -52,7 +52,6 @@ void MS5837init(void) { I2cSetActiveFound(MS5837_ADDR, "MS5837"); } } - AddLog(LOG_LEVEL_DEBUG, PSTR("BME: Gas variant %d"), bme_dev[bmp_idx].variant_id); } #ifdef USE_WEBSERVER @@ -75,9 +74,11 @@ void MS5837Show(bool json) { WSContentSend_PD(HTTP_SNS_MS5837, pressure_str, temperature_str); #endif // USE_WEBSERVER } + AddLog(LOG_LEVEL_DEBUG, PSTR("BMP Pressure: %d"), ConvertPressure(bmp_sensors[1].bmp_pressure)); if (I2cEnabled(XI2C_10)) { - pressure_delta = sensor_ms5837.pressure() - bmp_sensors[0].bmp_pressure; - inches_water = pressure_delta*0.401463078662; + float pressure_delta = sensor_ms5837.pressure() - ConvertPressure(bmp_sensors[1].bmp_pressure); + float inches_water = pressure_delta*0.401463078662; + AddLog(LOG_LEVEL_DEBUG, PSTR("Pressure Delta: %d | Inches Water: %d"), pressure_delta, inches_water); } } diff --git a/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino b/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino index daf1b5a1fd5e..4fb41a0224db 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino @@ -18,7 +18,7 @@ */ #ifdef USE_I2C -#ifdef USE_SHT3X +#ifdef USE_SHT3X /*********************************************************************************************\ * Sensirion I2C temperature and humidity sensors * diff --git a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino index 37f456beaf57..4dc4d1abb4c3 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino @@ -81,7 +81,7 @@ void Tsl2591Show(bool json) char lux_str[10]; dtostrf(tsl2591_lux, sizeof(lux_str)-1, 3, lux_str); if (json) { - ResponseAppend_P(PSTR(",\"TSL2591\":{\"" D_JSON_ILLUMINANCE "\":%s}"), lux_str); + ResponseAppend_P(PSTR(",\"TSL2591\":{\"" D_JSON_ILLUMINANCE "\":%s}"), lux_str); #ifdef USE_DOMOTICZ if (0 == TasmotaGlobal.tele_period) { DomoticzSensor(DZ_ILLUMINANCE, tsl2591_lux); } #endif // USE_DOMOTICZ diff --git a/tasmota/tasmota_xx2c_global/xsns_interface.ino b/tasmota/tasmota_xx2c_global/xsns_interface.ino index f78d5e9e2246..1f0f9d60fbaf 100644 --- a/tasmota/tasmota_xx2c_global/xsns_interface.ino +++ b/tasmota/tasmota_xx2c_global/xsns_interface.ino @@ -528,8 +528,13 @@ bool (* const xsns_func_ptr[])(uint32_t) = { // Sensor Function Pointers for si #endif #ifdef XSNS_127 - &Xsns127 + &Xsns127, #endif + +#ifdef XSNS_128 + &Xsns128 +#endif + }; const uint8_t xsns_present = sizeof(xsns_func_ptr) / sizeof(xsns_func_ptr[0]); // Number of External Sensors found @@ -1049,8 +1054,13 @@ const uint8_t kXsnsList[] = { #endif #ifdef XSNS_127 - XSNS_127 + XSNS_127, #endif + +#ifdef XSNS_128 + XSNS_128 +#endif + }; /*********************************************************************************************/ diff --git a/tasmota/tasmota_xx2c_global/xx2c_interface.ino b/tasmota/tasmota_xx2c_global/xx2c_interface.ino index 55e8a1a0a559..7dcfa97dfb71 100644 --- a/tasmota/tasmota_xx2c_global/xx2c_interface.ino +++ b/tasmota/tasmota_xx2c_global/xx2c_interface.ino @@ -406,7 +406,15 @@ const uint8_t kI2cList[] = { #endif #ifdef XI2C_96 - XI2C_96 + XI2C_96, +#endif + +#ifdef XI2C_97 + XI2C_97, +#endif + +#ifdef XI2C_98 + XI2C_98 #endif }; diff --git a/tools/decode-status.py b/tools/decode-status.py index 3b8af81b40d6..e6d90d7e721c 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -246,7 +246,7 @@ "USE_INA219","USE_SHT3X","USE_MHZ19","USE_TSL2561", "USE_SENSEAIR","USE_PMS5003","USE_MGS","USE_NOVA_SDS", "USE_SGP30","USE_SR04","USE_SDM120","USE_SI1145", - "USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638" + "USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638","USE_MS5837" ],[ "USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050", "USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766", From 8ec2629cdd36e6008355a49fb505eb0efb698b96 Mon Sep 17 00:00:00 2001 From: vtHydroponics plant Date: Mon, 6 May 2024 20:52:10 +0000 Subject: [PATCH 7/7] updated temp to change via setoption8 command from tasmota --- tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino | 2 ++ .../tasmota_xsns_sensor/xsns_128_ms5837.ino | 33 +++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino index 445eb4d88e6b..89efe6ababb1 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino @@ -337,6 +337,8 @@ void Bme280Read(uint8_t bmp_idx) { p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData[bmp_idx].dig_P7) << 4); bmp_sensors[bmp_idx].bmp_pressure = (float)p / 25600.0f; + AddLog(LOG_LEVEL_DEBUG, PSTR("BMP_data{pressure:%f,temperature:%f,bmp_idx:%d}"), bmp_sensors[bmp_idx].bmp_pressure, bmp_sensors[bmp_idx].bmp_temperature, bmp_idx); + if (BMP280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { return; } int32_t adc_H = I2cRead16(address, BME280_REGISTER_HUMIDDATA, bus); diff --git a/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino b/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino index ce998f6ad5b0..2754af056d09 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_128_ms5837.ino @@ -36,7 +36,8 @@ MS5837 sensor_ms5837; -uint8_t ms5837_start = 0; +uint8_t ms5837Start = 0; +float pressureOffset = 2.85; /********************************************************************************************/ @@ -48,7 +49,7 @@ void MS5837init(void) { if(sensor_ms5837.init(myWire)) { sensor_ms5837.setModel(sensor_ms5837.MS5837_02BA); sensor_ms5837.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater) - ms5837_start = 1; + ms5837Start = 1; I2cSetActiveFound(MS5837_ADDR, "MS5837"); } } @@ -56,30 +57,36 @@ void MS5837init(void) { #ifdef USE_WEBSERVER const char HTTP_SNS_MS5837[] PROGMEM = - "{s}MS5837 Pressure {m}%s hPa{e}{s}MS5837 Temperature {m}%s C{e}"; // {s} = , {m} = , {e} = + "{s}MS5837 Pressure {m}%s hPa{e}{s}MS5837 Temperature {m}%s %c{e}{s}Inches Water {m}%s in{e}"; // {s} = , {m} = , {e} = #endif // USE_WEBSERVER void MS5837Show(bool json) { - sensor_ms5837.read(); + float pressure_delta; + float inches_water; + sensor_ms5837.read(); + if (I2cEnabled(XI2C_10)) { + pressure_delta = sensor_ms5837.pressure() - bmp_sensors[0].bmp_pressure + pressureOffset; + inches_water = pressure_delta*0.401463078662; + // AddLog(LOG_LEVEL_DEBUG, PSTR("Pressure Delta: %f | Inches Water: %f"), pressure_delta, inches_water); + } char temperature_str[8]; dtostrf(sensor_ms5837.temperature(), sizeof(temperature_str)-1, 3, temperature_str); char pressure_str[8]; dtostrf(sensor_ms5837.pressure(), sizeof(pressure_str)-1, 3, pressure_str); + char inchesWater_str[8]; + dtostrf(inches_water, sizeof(inchesWater_str)-1, 3, inchesWater_str); if (json) { + // consolidate to one line ResponseAppend_P(PSTR(",\"MS5837\":{\"Temperature\":%s,"), temperature_str); - ResponseAppend_P(PSTR("\"Pressure\":%s}"), pressure_str); + ResponseAppend_P(PSTR("\"Pressure\":%s,"), pressure_str); + ResponseAppend_P(PSTR("\"Inches Water\":%s}"), inchesWater_str); #ifdef USE_WEBSERVER } else { - WSContentSend_PD(HTTP_SNS_MS5837, pressure_str, temperature_str); + WSContentSend_PD(HTTP_SNS_MS5837, pressure_str, TempUnit(), temperature_str, inchesWater_str); #endif // USE_WEBSERVER } - AddLog(LOG_LEVEL_DEBUG, PSTR("BMP Pressure: %d"), ConvertPressure(bmp_sensors[1].bmp_pressure)); - if (I2cEnabled(XI2C_10)) { - float pressure_delta = sensor_ms5837.pressure() - ConvertPressure(bmp_sensors[1].bmp_pressure); - float inches_water = pressure_delta*0.401463078662; - AddLog(LOG_LEVEL_DEBUG, PSTR("Pressure Delta: %d | Inches Water: %d"), pressure_delta, inches_water); - } + AddLog(LOG_LEVEL_DEBUG, PSTR("BMP Pressure: %f"), bmp_sensors[0].bmp_pressure); } /*********************************************************************************************\ @@ -95,7 +102,7 @@ bool Xsns128(uint32_t function) { if (FUNC_INIT == function) { MS5837init(); } - else if (ms5837_start) { + else if (ms5837Start) { switch (function) { case FUNC_JSON_APPEND: MS5837Show(1);