← До всіх проєктів
Сенсори Початковий

LM35 і TMP36: аналоговий термометр на ESP32 та Arduino без бібліотек

Три ніжки, 10 мВ на градус і жодної бібліотеки. Розбираємося, чим LM35 відрізняється від TMP36, чому на ESP32 варто читати мілівольти, а не «сирі» значення АЦП, і як усередненням прибрати стрибки показів.

Складність
Початковий
Час
30 min
Категорія
Сенсори
Оновлено

Про проєкт

LM35 і TMP36 — найпростіші датчики температури: мікросхема в корпусі TO-92, як у транзистора, видає напругу, пропорційну температурі. Жодної шини, адрес і бібліотек — лише analogRead(). Саме тому на них зручно розібратися з АЦП мікроконтролера і його похибками.

Що потрібно

  • ESP32 DevKit (або Arduino Uno / Nano)
  • Датчик LM35DZ або TMP36
  • Кілька проводів; для довгого кабелю — конденсатор 0.1 мкФ між OUT і GND

LM35 чи TMP36

LM35 TMP36
Крутизна 10 мВ/°C 10 мВ/°C
0 °C 0 мВ 500 мВ
Живлення 4–30 В 2.7–5.5 В
Діапазон з одним живленням +2…+150 °C −40…+125 °C
Формула T = U / 10 T = (U − 500) / 10

Головна пастка LM35 — живлення від 4 В. Від 3.3 В він формально не працює, тому на ESP32 його підключають до виводу 5V: вихідна напруга однаково не перевищить 1.5 В, і для входу ESP32 це безпечно. Друга особливість — з одним живленням LM35 не видає від'ємної напруги, тож мінус на ньому не побачити. Для вулиці беріть TMP36 або DS18B20.

Схема

Якщо тримати датчик плоским боком до себе, ніжки зліва направо: +Vs, Vout, GND.

Датчик ESP32 Arduino Uno
+Vs 5V (LM35) або 3V3 (TMP36) 5V
Vout GPIO34 (ADC1) A0
GND GND GND

На ESP32 використовуйте виводи ADC1 (GPIO32–39): ADC2 не працює, коли ввімкнено Wi-Fi.

Чому мілівольти, а не analogRead()

АЦП ESP32 нелінійний: біля нуля і біля верхньої межі він «з'їдає» десятки мілівольт, а коефіцієнт відрізняється від чипа до чипа. analogRead() * 3.3 / 4095 легко дає похибку 2–3 °C. Функція analogReadMilliVolts() застосовує заводську калібровку, записану в eFuse, і повертає напругу в мілівольтах — для LM35 це одразу десяті частки градуса.

На Arduino Uno АЦП лінійний, але грубий: 10 біт від 5 В — це 4.9 мВ на крок, тобто приблизно 0.5 °C. Точніше можна, якщо перемкнути опорну напругу на внутрішні 1.1 В (analogReference(INTERNAL)): тоді крок — 0.1 °C, а максимум — 110 °C.

Код

// LM35 / TMP36 на ESP32: усереднюємо виміри і переводимо мілівольти в °C
const int SENSOR_PIN = 34;     // ADC1
const bool IS_TMP36 = false;   // true для TMP36 (0 °C = 500 мВ)

float readCelsius() {
  uint32_t sum = 0;
  for (int i = 0; i < 16; i++) {
    sum += analogReadMilliVolts(SENSOR_PIN);   // мілівольти з заводською калібровкою
    delay(2);
  }
  float mv = sum / 16.0;
  return IS_TMP36 ? (mv - 500) / 10.0 : mv / 10.0;
}

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

void loop() {
  float t = readCelsius();
  Serial.printf("Температура: %.1f °C\n", t);
  delay(1000);
}

Шістнадцять вимірів із паузою 2 мс усереднюють шум АЦП і наведення від Wi-Fi. У симуляторі змінюйте температуру у властивостях датчика і перемикайте модель на TMP36 — не забудьте тоді виправити IS_TMP36.

Типові проблеми

  • Показує на 5–10 °C більше, ніж є. Датчик гріється сам від себе або від плати. Винесіть його на проводі подалі від стабілізатора.
  • Покази стрибають на довгому кабелі. LM35 не любить ємності кабелю: поставте резистор 2 кОм послідовно з виходом або конденсатор 0.1 мкФ на GND біля входу АЦП.
  • Живлення 3.3 В. LM35 від 3.3 В бреше або «застигає» — симулятор про це попередить.
  • Крок 0.5 °C на Arduino. Це обмеження 10-бітного АЦП; допоможе analogReference(INTERNAL) або цифровий датчик.