Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for LMT01 temperature sensor #8713

Merged
merged 2 commits into from
Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tasmota/language/en_GB.h
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@
#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd"
#define D_SENSOR_TELEINFO_RX "TInfo Rx"
#define D_SENSOR_TELEINFO_ENABLE "TInfo EN"
#define D_SENSOR_LMT01_PULSE "LMT01 Pulse"
#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
#define D_GPIO_WEBCAM_RESET "CAM_RESET"
#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
Expand Down
1 change: 1 addition & 0 deletions tasmota/my_user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@
#define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!)
#define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000)
#define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD
//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)

// -- IR Remote features - all protocols from IRremoteESP8266 --------------------------
// IR Full Protocols mode is activated through platform.io only.
Expand Down
1 change: 1 addition & 0 deletions tasmota/tasmota_configurations.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)

#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
Expand Down
7 changes: 6 additions & 1 deletion tasmota/tasmota_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ enum UserSelectablePins {
GPIO_TCP_RX, // TCP Serial bridge
GPIO_TELEINFO_RX, // TELEINFO serial interface
GPIO_TELEINFO_ENABLE,// TELEINFO Enable PIN
GPIO_LMT01, // LMT01 input counting pin
GPIO_SENSOR_END };

// Programmer selectable GPIO functionality
Expand Down Expand Up @@ -330,7 +331,8 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_WINDMETER_SPEED "|"
D_SENSOR_BL0940_RX "|"
D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|"
D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE
D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|"
D_SENSOR_LMT01_PULSE
;

const char kSensorNamesFixed[] PROGMEM =
Expand Down Expand Up @@ -696,6 +698,9 @@ const uint8_t kGpioNiceList[] PROGMEM = {
GPIO_TELEINFO_RX,
GPIO_TELEINFO_ENABLE,
#endif
#ifdef USE_LMT01 // LMT01, count pulses on GPIO
GPIO_LMT01,
#endif
};

/********************************************************************************************/
Expand Down
1 change: 1 addition & 0 deletions tasmota/tasmota_template_ESP32.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ enum UserSelectablePins {
GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet
GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin
GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin
GPIO_LMT01, // LMT01 input counting pin
GPIO_SENSOR_END };

enum ProgramSelectablePins {
Expand Down
146 changes: 146 additions & 0 deletions tasmota/xsns_74_lmt01.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
xns_74_lmt01.ino

Copyright (C) 2020 Theo Arends, Justifiably

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_LMT01
/*********************************************************************************************\
* LMT01 - 0.5°C Accurate 2-Pin Digital Output Temperature Sensor With Pulse Count Interface
*
* Uses fragments of public domain code LMT01_Example.ino released by Texas Instruments, July 10th 2017.
* See https://training.ti.com/how-interface-lmt01-temperature-sensor-arduino
*
\*********************************************************************************************/

#define XSNS_74 74

#define LMT01_TIMEOUT 200 // ms timeout for a reading cycle

bool lmt01_initialized = false;
float lmt01_temperature = NAN;

void LMT01_Init(void) {
if (PinUsed(GPIO_LMT01)) {
pinMode(Pin(GPIO_LMT01), INPUT);
attachInterrupt(Pin(GPIO_LMT01), LMT01_countPulse, FALLING);
lmt01_initialized = true;
}
}

#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception
void LMT01_countPulse(void) ICACHE_RAM_ATTR;
#endif // ARDUINO_ESP8266_RELEASE_2_3_0

volatile int lmt01_pulseCount = 0;

void LMT01_countPulse(void) {
lmt01_pulseCount++;
}

void LMT01_GetTemperature(void) {
int pulses = 0;
pulses = LMT01_getPulses();
if (pulses >= 0) {
// simple linear conversion, datasheet has a look-up table alternative
// which is accurate over a wider temperature range
lmt01_temperature = ConvertTemp(0.0625 * pulses - 50);
} else {
lmt01_temperature = NAN; // Timeout
}
}

int LMT01_getPulses(void) {
int timeout = LMT01_TIMEOUT;
int hold = -1;
// complete current pulse cycle (50ms max)
while(lmt01_pulseCount != hold && --timeout > 0) {
hold = lmt01_pulseCount;
delay(1);
}
lmt01_pulseCount = 0;
// wait for start of next (54ms max)
while(lmt01_pulseCount == 0 && --timeout > 0) {
delay(1);
}
hold = -1;
// take this count (up to 50ms)
while(lmt01_pulseCount != hold && --timeout > 0) {
hold = lmt01_pulseCount;
delay(1);
}
if (timeout > 0) {
return hold;
}
return -1;
}


void LMT01_Show(bool Json) {
char temp[33];
dtostrfd(lmt01_temperature, Settings.flag2.temperature_resolution, temp);

if (Json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), \
"LMT01", temp);
#ifdef USE_DOMOTICZ
if (0 == tele_period) {
DomoticzSensor(DZ_TEMP, temp);
}
#endif // USE_DOMOTICZ
#ifdef USE_KNX
if (0 == tele_period) {
KnxSensor(KNX_TEMPERATURE, lmt01_temperature);
}
#endif // USE_KNX
#ifdef USE_WEBSERVER
} else {
WSContentSend_PD(HTTP_SNS_TEMP, "LMT01", temp, TempUnit());
#endif // USE_WEBSERVER
}
}


/*********************************************************************************************\
* Interface
\*********************************************************************************************/

bool Xsns74(uint8_t function)
{
bool result = false;

if (FUNC_INIT == function) {
LMT01_Init();
}
else if (lmt01_initialized) {
switch (function) {
case FUNC_EVERY_SECOND:
LMT01_GetTemperature();
break;
case FUNC_JSON_APPEND:
LMT01_Show(true);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
LMT01_Show(false);
break;
#endif // USE_WEBSERVER
}
}
return result;
}

#endif // USE_LMT01