Apr 06, 2018, 09:52 pm
I hope this is appropriate. I posted this question on the Arduino/Sensor site, got 42 views, but no reply.
I had no success getting help with any earlier post on this subject, so I am starting over with new code by Kevan Darrah. He is a good programmer, so the code should work, but it doesn't. I did a lot of reading and I understand how it should work, so let me spend few words explaining what I learned and maybe someone can take it from there. The LMT01 output is 0.6V to 1.6V pulses 10 usec wide, I verified this using a scope, the total number of theses pulses is proportional to the temperature. This repeats every 100 msec. This signal is input to pin D2, but that is a digital pin: High=5V, Low= 0V, but Arduino IDE does something sneaky when you use the special function "attachInterrupt(pin,ISR,Falling)" - It redirects the signal internally to pin A0N of the positive side of an Analog Comparator, and attaches to AN1 internally a stable reference voltage of 1.1V. Now the 0.6V to 1.6V pulses are exactly centered on the comparator so it puts out a perfect 1's and 0's for easy counting.
So to repeat myself only Pin2 is attached with the LMT01 to the Arduino. Why doesn't this &!#^-thing work, it compiled and uploaded correctly. If I had a debugger on this software, moving one line at a time I could fix it myself. Code follows:
//Sample Code for LMT01 Temperature Sensor
//LMT01ELPGQ1
//Kevin Darrah
//TempPins
#define pulsePin 2 //D2 on arduino D5 on esp8266 **This is the output from the LMT01
//globals for the LMT01 temp sensor
volatile unsigned int pulseCount = 0;//pulses out of the sensor
float temperatureC = 0, temperatureF = 0;//converted temperatures
float tempHIGH, tempLOW = 1000;
//functions
void pulseDetect();//interrupt function
float getTemperature();//call this to get temperature from the LMT01 - returns a float for the temperature in (C)
void setup() {
Serial.begin(115200);
pinMode(pulsePin, INPUT);//output from LMT01 sensor circuit
}
void loop() {
temperatureC = getTemperature();// call getTemperature() to return temp in C
if (temperatureC != 1000) {//returns 1000 if anything went wrong
temperatureF = temperatureC * 9.000 / 5.000 + 32;
if (temperatureF > tempHIGH)
tempHIGH = temperatureF;
if (temperatureF < tempLOW)
tempLOW = temperatureF;
Serial.print(temperatureC);
Serial.print("C ");
Serial.print(temperatureF);
Serial.print("F HIGH=");
Serial.print(tempHIGH);
Serial.print("F LOW=");
Serial.print(tempLOW);
Serial.print("F DIFF=");
Serial.print(tempHIGH - tempLOW);
Serial.print("F ");
Serial.print(pulseCount);
Serial.println("pulses ");
for (int i = 0; i < random(50, 200); i++)
delay(1);
}
}
float getTemperature() {// ********* GET TEMPERATURE FUNCTION *** returns the temperature C
attachInterrupt(digitalPinToInterrupt(pulsePin), pulseDetect, FALLING);//using interrupt pin tp trigger on falling edge
unsigned long conversionStartTime = millis();//keeps track of timing
while (millis() - conversionStartTime < 10) { //looking for silence, in case we go to read temperature mid-measurement, ride it out till next one
// yield();//for the ESP8266 to keep other tasks happy
if (pulseCount > 0) {
pulseCount = 0;
conversionStartTime = millis();
}
}
pulseCount = 0;//reset pulse count
while (millis() - conversionStartTime < 150) {//wait for first pulse
// yield();//for the ESP8266 to keep other tasks happy
if (pulseCount > 0)
break;
}
if (pulseCount == 0)
return 1000;//FAIL - never got a pulse
conversionStartTime = millis();//conversion done, so reset time
unsigned int oldPulseCount = pulseCount;//just to help keep track of timings when pulse pin goes idle
unsigned long pulseTime = millis();
while (millis() - conversionStartTime < 60) { //measure pulses
// yield();//for the ESP8266 to keep other tasks happy
if (pulseCount != oldPulseCount) {//new pulse, so update timer
oldPulseCount = pulseCount;
pulseTime = millis();
}
else if (millis() - pulseTime > 5) {//no pulses for a while, must be done.
break;
}
}
//^^^ Stays stuck here counting pulese for 60ms
if (pulseCount < 5) { //this is just noise, false trigger... I mean only 5 pulses, that can't be right
return 1000;//FAIL
}
detachInterrupt(digitalPinToInterrupt(pulsePin));//done with the interrupt
temperatureC = 256.000 * pulseCount / 4096.000 - 50;//conversion
//see 7.3.2 Output Transfer Function in Datasheet
return temperatureC;//throw the temp back
}
//change this function to look like this if using the ESP8266
//void ICACHE_RAM_ATTR pulseDetect()
void pulseDetect() {// ********* PULSE COUNTER INTERRUPT FUNCTION
pulseCount++;
}
1 Answer 1
This is added 15 months after the OP but there is very little information on this sensor.
You have not included your schematics which would be useful. For this setup TI gives you four options: transistor level shifting, isolation, multiple devices to one MCU pin, and common ground with high-side signal. Kevin Darrah uses the transistor level shifting method in his videos. Please refer to the TI datasheet for connections, pages 3 and 21 are relevant in setting that up. There is also this sample code supplied with a video that shows setup using the comparator.
NOTE: Ensure you do not have your sensor reverse biased or it will not work and may wreck it. Diodes are a good idea here.
Try commenting this out:
if (pulseCount < 5) { //this is just noise, false trigger... I mean only 5 pulses, that can't be right
return 1000;//FAIL
}
I found this sensor gives very low pulse readings if you have something setup incorrectly which will come out around -50C and this line may be causing it to read a fail. If that is the case you will need to rewrite the getTemperature() function, possibly using the comparator method supplied by TI which will require you to rewire, see their training code which includes a video. TI notes the first couple of readings may be incorrect. In my code I have my function perform several throwaway tests before spitting out a reading.
TL;DR If you use the TI comparator method, you can use the digital pins for power instead of the +5VDC like they do but use a diode (needed also for multiple sensors) to isolate the sensor to prevent reverse bias. If you do this you can shut the sensor off by switching it to INPUT but be aware, OUTPUT mode goes to ground by default which can cause reverse bias and fry your sensor. Use digitalWrite(pin,HIGH) prior to switching to OUTPUT to change default behaviour to +5V rather than GND (true, the diode should protect you here but adding this line is necessary anyway so do it in this order, safety first). I needed multiple sensors in my build so this is what I found, I used the Arduino-based comparator method quite successfully.
I don't have the necessary components to connect with transistor level shifting and actually test this at the moment but you could try this code if you want. I trimmed it down, eliminated most of the ESP8266 stuff you weren't using anyway and modified the getTemperature function to resemble what I have working right now.
//Sample Code for LMT01 Temperature Sensor
//LMT01ELPGQ1
//Kevin Darrah
// Ben Nesbitt, 2019
// For LMT01 if using transistor method of connection
//TempPins
#define pulsePin 2 //D2 on arduino **This is the output from the LMT01
//globals for the LMT01 temp sensor
volatile unsigned int pulseCount = 0;//pulses out of the sensor
float tempC = 0;//converted temperatures
float tempHigh = 151;
float tempLow = 151;
unsigned long timeMillis = millis();
//functions
void pulseDetect();//interrupt function
void setup() {
Serial.begin(115200);
pinMode(pulsePin, INPUT);//output from LMT01 sensor circuit
}
void loop() {
timeMillis = millis();
tempC = getTemp(pulsePin);// return temp in C
Serial.print(tempC); Serial.print("C ");
Serial.print(pulseCount); Serial.println("pulses ");
while (millis() - timeMillis < 5000) {} // Change this for how often you want to sample the temperature.
}
float getTemp(int pin)
{
attachInterrupt(digitalPinToInterrupt(pin), pulseDetect, FALLING);//using interrupt pin tp trigger on falling edge
float temperature = 0;
unsigned long timeMillis = millis();//keeps track of timing
int counterRef = 0; // Pulse count reference
while (millis() - timeMillis < 10) { //looking for silence, in case we go to read temperature mid-measurement, ride it out till next one
if (pulseCount > 0) {
pulseCount = 0;
timeMillis = millis();
}
}
pulseCount = 0;//reset pulse count
for (int i = 0; i < 3; i++)
{
while(pulseCount < 1) {} //* TI recommends aborting the first one or two tests as inaccurate
if(pulseCount != 0){
//Wait for counting to be complete
counterRef = 0;
while(pulseCount != counterRef)
{
counterRef = pulseCount;
timeMillis = millis();
while (timeMillis == millis()){}
}
if (i < 2)
{
pulseCount = 0;
}
else
{
temperature = 0.0625 * pulseCount -50; // Pulses to temperature conversion
}
}
}
detachInterrupt(digitalPinToInterrupt(pin));//done with the interrupt
//see 7.3.2 Output Transfer Function in Datasheet
return temperature;
}
void pulseDetect() {// ********* PULSE COUNTER INTERRUPT FUNCTION
pulseCount++;
}
The LMT01 output is 0.6V to 1.6V pulses 10 usec wide
is just fluffdoes not work
is a description that provides no information about the failure