Код датчика температуры LMT01 не работает - нужна помощь

6 апреля 2018 г., 21:52

Надеюсь, это уместно. Я разместил этот вопрос на сайте Arduino/Sensor, получил 42 просмотра, но не получил ответа.

Мне не удалось получить помощь ни в одной из предыдущих публикаций на эту тему, поэтому я начинаю с нового кода Кевана Дарра. Он хороший программист, поэтому код должен работать, но не работает. Я много читал и понимаю, как это должно работать, поэтому позвольте мне потратить несколько слов на объяснение того, что я узнал, и, возможно, кто-то сможет взять это оттуда. Выход LMT01 составляет импульсы от 0,6 В до 1,6 В шириной 10 мкс, я проверил это с помощью осциллографа, общее количество этих импульсов пропорционально температуре. Это повторяется каждые 100 мс. Этот сигнал подается на контакт D2, но это цифровой контакт: High = 5V, Low = 0V, но Arduino IDE делает что-то скрытое, когда вы используете специальную функцию «attachInterrupt (pin, ISR, Falling)» — она перенаправляет сигнал внутри к контакту A0N положительной стороны аналогового компаратора и подключает к AN1 внутри стабильное опорное напряжение 1,1 В. Теперь импульсы от 0,6 В до 1,6 В точно центрируются на компараторе, поэтому он выдает идеальные единицы и нули для легкого подсчета.

Итак, повторюсь, только Pin2 подключен с помощью LMT01 к Arduino. Почему не работает эта &!#^-штука, правильно скомпилировалась и загрузилась. Если бы у меня был отладчик этого софта, перемещая по одной строке за раз, я мог бы исправить это сам. Далее следует код:

 //Пример кода для датчика температуры LMT01
//LMT01ELPGQ1
//Кевин Дарра

//Временные контакты
#define pulsePin 2 //D2 на arduino D5 на esp8266 **Это вывод LMT01

//глобальные значения для датчика температуры LMT01
volatile unsigned int pulseCount = 0;//импульсы из датчика
float temperatureC = 0, temperatureF = 0;//преобразованные температуры
float tempHIGH, tempLOW = 1000;

//функции
void pulseDetect();//функция прерывания
float getTemperature();//вызываем это, чтобы получить температуру от LMT01 - возвращает значение с плавающей запятой для температуры в (C)

void setup() {
  Serial.begin(115200);
  pinMode(pulsePin, INPUT);//выход из цепи датчика LMT01

}

void loop() {
  temperatureC = getTemperature();// вызовите getTemperature(), чтобы вернуть температуру в C
  if (temperatureC != 1000) {// возвращает 1000, если что-то пошло не так
    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 *** возвращает температуру C
  attachInterrupt(digitalPinToInterrupt(pulsePin), pulseDetect, FALLING);//используем триггер tp вывода прерывания по заднему фронту

  unsigned long conversionStartTime = millis();//отслеживает время

  while (millis() - conversionStartTime < 10) { // ищем тишину, на случай, если мы перейдем к считыванию температуры в середине измерения, дождемся следующего
   // yield();//для ESP8266, чтобы другие задачи были довольны
    if (pulseCount > 0) {
      pulseCount = 0;
      conversionStartTime = millis();
    }
  }

  pulseCount = 0;//сброс счетчика импульсов
  while (millis() - conversionStartTime < 150) {//ожидание первого импульса
   // yield(); // чтобы ESP8266 выполнял другие задачи
    if (pulseCount > 0)
      break;
  }
  if (pulseCount == 0)
    return 1000;//FAIL - никогда не было импульса

  conversionStartTime = millis();//конвертация выполнена, поэтому сбрасываем время
  unsigned int oldPulseCount = pulseCount;//просто для того, чтобы отслеживать тайминги, когда пин пульса бездействует
  unsigned long pulseTime = millis();
  while (millis() - conversionStartTime < 60) { // измеряем импульсы
   // yield(); // чтобы ESP8266 выполнял другие задачи

    if (pulseCount != oldPulseCount) {//новый пульс, поэтому обновите таймер
      oldPulseCount = pulseCount;
      pulseTime = millis();
    }
    else if (millis() - pulseTime > 5) {// какое-то время импульсов не будет, необходимо выполнить.
      break;
    }
  }
  //^^^ Застревает здесь, считая импульсы в течение 60 мс

  if (pulseCount < 5) { //это просто шум, ложный срабатывание... Я имею в виду только 5 импульсов, это не может быть правдой
    return 1000;//НЕУДАЧА
  }

  detachInterrupt(digitalPinToInterrupt(pulsePin));//готово с прерыванием
  temperatureC = 256.000 * pulseCount / 4096.000 - 50;//преобразование
  //см. 7.3.2 Выходная передаточная функция в таблице данных

  return temperatureC;//сбрасываем температуру обратно
}

// изменить эту функцию, чтобы она выглядела так, если используется ESP8266
//аннулировать ICACHE_RAM_ATTR pulseDetect()

void pulseDetect() {// ********** ФУНКЦИЯ ПРЕРЫВАНИЯ СЧЕТЧИКА ИМПУЛЬСОВ
  pulseCount++;
}

, 👍0

Обсуждение

начните с сокращения вашего кода, чтобы просто подсчитывать импульсы и распечатывать значение pulseCount каждую секунду или около того .... вы также делаете предположение, что все процессоры Arduino ведут себя одинаково внутри ........... ... ваш вопрос слишком многословен ... вы написали кучу текста, который не имеет никакого отношения к проблеме ... заставляет людей терять интерес, прежде чем они доберутся до описания проблемы .... все, что до `Вывод LMT01, Импульсы от 0,6 В до 1,6 В шириной 10 мкс — это просто ерунда., @jsotola

«не работает» — это описание, которое не содержит информации о сбое, @jsotola


1 ответ


2

Это добавлено через 15 месяцев после OP, но информации об этом датчике очень мало.

Вы не включили свои схемы, которые были бы полезны. Для этой настройки TI предлагает вам четыре варианта: смещение уровня транзистора, изоляция, подключение нескольких устройств к одному выводу MCU и общее заземление с сигналом верхней стороны. Кевин Дарра использует в своих видео метод смещения уровня транзистора. См. техническое описание TI для подключения, страницы 3 и 21 относятся к настройке. Существует также этот пример кода с видео, демонстрирующим настройку с использованием компаратора.

ПРИМЕЧАНИЕ. Убедитесь, что датчик не имеет обратного смещения, иначе он не будет работать и может выйти из строя. Диоды — хорошая идея.

Попробуйте закомментировать это:

if (pulseCount < 5) { //это просто шум, ложный срабатывание... Я имею в виду только 5 импульсов, это не может быть правильным
return 1000;//НЕУДАЧА

Я обнаружил, что этот датчик дает очень низкие показания пульса, если вы что-то настроили неправильно, что будет около -50C, и эта линия может привести к тому, что он считывает сбой. Если это так, вам нужно будет переписать функцию getTemperature(), возможно, используя метод сравнения, предоставленный TI, который потребует от вас переподключения, см. их обучающий код, который включает видео. TI отмечает, что первые несколько показаний могут быть неверными. В моем коде функция выполняет несколько одноразовых тестов, прежде чем выдать показания.

TL;DR Если вы используете метод компаратора TI, вы можете использовать цифровые контакты для питания вместо +5 В постоянного тока, как они делают, но использовать диод (необходимый также для нескольких датчиков), чтобы изолировать датчик, чтобы предотвратить обратное смещение. Если вы сделаете это, вы можете отключить датчик, переключив его на INPUT, но имейте в виду, что режим OUTPUT по умолчанию переходит на землю, что может вызвать обратное смещение и поджарить ваш датчик. Используйте digitalWrite(pin,HIGH) перед переключением на OUTPUT, чтобы изменить поведение по умолчанию на +5V, а не на GND (правда, диод должен защитить вас здесь, но добавление этой линии в любом случае необходимо, поэтому делайте это в этом порядке, прежде всего безопасность). Мне нужно было несколько датчиков в моей сборке, поэтому я нашел это, я довольно успешно использовал метод компаратора на основе Arduino.

У меня нет необходимых компонентов для соединения со сдвигом уровня транзистора и фактического тестирования этого в данный момент, но вы можете попробовать этот код, если хотите. Я урезал его, убрал большую часть вещей ESP8266, которые вы все равно не использовали, и изменил функцию getTemperature, чтобы она напоминала то, что у меня сейчас работает.

//Пример кода для датчика температуры LMT01
//LMT01ELPGQ1
//Кевин Дарра
// Бен Несбитт, 2019 г.

// Для LMT01 при использовании транзисторного метода подключения

//Временные контакты
#define pulsePin 2 //D2 на Arduino **Это выход LMT01

//глобальные значения для датчика температуры LMT01
volatile unsigned int pulseCount = 0;//импульсы из датчика
float tempC = 0;//пересчитанные температуры
float tempHigh = 151;
float tempLow = 151;
unsigned long timeMillis = millis();

//функции
void pulseDetect();//функция прерывания

void setup() {
  Serial.begin(115200);

  pinMode(pulsePin, INPUT);//выход из цепи датчика LMT01

}

void loop() {
  timeMillis = millis();
  tempC = getTemp(pulsePin);// вернуть температуру в C

  Serial.print(tempC); Serial.print("C  ");
  Serial.print(pulseCount); Serial.println("pulses  ");

  while (millis() - timeMillis < 5000) {} // Измените это значение на то, как часто вы хотите измерять температуру.


}


float getTemp(int pin) 
{
  attachInterrupt(digitalPinToInterrupt(pin), pulseDetect, FALLING);//используем триггер tp вывода прерывания по заднему фронту
  float temperature = 0;
  unsigned long timeMillis = millis();//отслеживает время
  int counterRef = 0; // Ссылка на счетчик импульсов

  while (millis() - timeMillis < 10) { // ищем тишину, на случай, если мы перейдем к считыванию температуры в середине измерения, дождемся следующего
    if (pulseCount > 0) {
      pulseCount = 0;
      timeMillis = millis();
    }
  }

  pulseCount = 0;//сброс счетчика импульсов
  for (int i = 0; i < 3; i++)
  {
    while(pulseCount < 1) {}  //* TI рекомендует прервать первые один или два теста как неточные

    if(pulseCount != 0){
      //ждем завершения подсчета
      counterRef = 0;
      while(pulseCount != counterRef)
      {
        counterRef = pulseCount;
        timeMillis = millis();
        while (timeMillis == millis()){}
      }
      if (i < 2)
      {
        pulseCount = 0;
      }
      else
      {
         temperature = 0.0625 * pulseCount -50; // Преобразование импульсов в температуру
      }
    }
  }

  detachInterrupt(digitalPinToInterrupt(pin));//с прерыванием покончено

  //см. 7.3.2 Выходная передаточная функция в таблице данных

  return temperature;
}

void pulseDetect() {// ********** ФУНКЦИЯ ПРЕРЫВАНИЯ СЧЕТЧИКА ИМПУЛЬСОВ
  pulseCount++;
}
,