Правильный датчик — половина успеха автоматизации
Самый умный ПЛК и лучший алгоритм управления ничего не стоят, если датчик даёт неверные данные. Выбор, монтаж и калибровка датчиков — часто недооцениваемая область, которая определяет качество всей системы.
Промышленный датчик — не просто "измерительное устройство". Это прибор, который должен работать 24/7 годами в условиях вибраций, агрессивных сред, перепадов температур и электромагнитных помех. И при этом давать достоверные показания.
Классификация выходных сигналов
Прежде чем выбирать датчик — определитесь с типом сигнала:
Аналоговые сигналы
4–20 мА (токовая петля):
Самый распространённый промышленный стандарт
4 мА = 0% диапазона, 20 мА = 100%
Устойчив к помехам (ток, не напряжение)
Обнаружение обрыва кабеля: < 3.8 мА = авария
Длина линии до нескольких км (ограничено напряжением питания)
Двухпроводная схема: датчик питается от той же петли!
0–10 В:
Проще в подключении, но чувствителен к помехам
Нет встроенного обнаружения обрыва
Ограничение длины кабеля (~50 м)
Используется в HVAC, Building Automation
0–5 В / ±10 В:
Распространён для ускорений, давлений в автомотиве
Дискретные сигналы
NPN / PNP:
NPN: выход тянет к GND при активации (сигнал = LOW)
PNP: выход тянет к питанию (сигнал = HIGH)
Подключение к ПЛК: важно соответствие типа входного модуля!
NO / NC (нормально открытый / нормально закрытый):
NO: контакт разомкнут в норме, замыкается при срабатывании
NC: контакт замкнут в норме, размыкается при срабатывании
Для безопасности: NC предпочтительнее (обрыв провода = срабатывание защиты)
Цифровые/протокольные
IO-Link, HART, Profibus PA, Foundation Fieldbus, EtherCAT — для умных датчиков с диагностикой и конфигурированием по линии.
Температура: термопары и PT100
Термопары (Thermocouple)
Принцип: эффект Зеебека — два разных металла, соединённых в двух точках, генерируют ЭДС при разнице температур.
Тип | Диапазон | Материал | Применение |
|---|---|---|---|
K | -200..+1372°C | NiCr-NiAl | Универсальный, самый популярный |
J | -210..+1200°C | Fe-CuNi | Печи, старые установки |
T | -270..+400°C | Cu-CuNi | Криогеника, пищевая промышленность |
N | -270..+1300°C | NiCrSi-NiSi | Стабильнее K при высоких T |
S | 0..+1768°C | Pt10Rh-Pt | Металлургия (эталон) |
B | +250..+1820°C | Pt30Rh-Pt6Rh | Высокотемпературные печи |
Ключевые особенности термопар:
Генерируют малую ЭДС (0–80 мВ) — нужен прецизионный усилитель
Требуют компенсации холодного спая (CJC — Cold Junction Compensation)
Длинные термопарные кабели из компенсационных проводов (дороже!)
Нелинейная характеристика (полиномиальная аппроксимация по ГОСТ)
Подключение к микроконтроллеру через MAX31855/MAX6675:
#include <Adafruit_MAX31855.h>
#include <SPI.h>
// MAX31855: усилитель термопары типа K с SPI интерфейсом
Adafruit_MAX31855 thermocouple(D5, D6, D7); // CLK, CS, DO
void setup() {
Serial.begin(115200);
if (!thermocouple.begin()) {
Serial.println("MAX31855 не найден!");
while (1);
}
}
void loop() {
double hot_temp = thermocouple.readCelsius(); // Температура термопары
double cold_temp = thermocouple.readInternal(); // Температура холодного спая (чип)
if (isnan(hot_temp)) {
uint8_t fault = thermocouple.readError();
Serial.print("Ошибка: ");
if (fault & MAX31855_FAULT_OPEN) Serial.println("обрыв термопары");
if (fault & MAX31855_FAULT_SHORT_GND) Serial.println("КЗ на GND");
if (fault & MAX31855_FAULT_SHORT_VCC) Serial.println("КЗ на VCC");
} else {
Serial.printf("T = %.2f°C (холодный спай: %.2f°C)\n", hot_temp, cold_temp);
}
delay(1000);
}
Термосопротивления PT100/PT1000
Принцип: сопротивление платинового проводника линейно растёт с температурой.
PT100: 100 Ом при 0°C, α = 0.00385 Ом/(Ом·°C)
PT1000: 1000 Ом при 0°C (лучше для длинных кабелей)
R(T) = R0 × [1 + A×T + B×T² + C×T³ × (T-100)]
R0 = 100 Ом
A = 3.9083×10⁻³
B = -5.775×10⁻⁷
C = -4.183×10⁻¹² (только при T < 0°C)
Упрощённо для -50..+200°C:
R(T) ≈ 100 × (1 + 0.00385 × T)
T ≈ (R - 100) / 0.385
Схемы подключения:
2-проводная (дёшево, но ошибка от сопротивления кабеля):
[ПЛК]──R_кабель──[PT100]──R_кабель──[ПЛК]
Ошибка: ΔR_кабель = 2 × ρ × L / S
При 10 м, 0.5 мм²: ΔR ≈ 0.7 Ом ≈ 1.8°C погрешность!
3-проводная (стандарт):
[ПЛК]──R1──[PT100]──R2──[ПЛК]
│
R3──────────[ПЛК]
Измерительная схема компенсирует сопротивление одного провода
4-проводная (эталонная точность):
[ПЛК]──I+──[PT100]──I-──[ПЛК] (ток через PT100)
[ПЛК]──U+──[PT100]──U-──[ПЛК] (измерение напряжения)
Сопротивление провода не влияет на точность
Датчики давления: 4–20 мА в промышленности
Основные типы:
Пьезорезистивные: мембрана с тензодатчиками, сигнал 4–20 мА. Самые распространённые.
Пьезоэлектрические: для динамических давлений (удары, взрывы). Заряд пропорционален давлению.
Ёмкостные: высокая точность (0.01%), дорогие. Для точных технологических процессов.
Подключение датчика 4–20 мА:
Двухпроводная схема (+питание, -сигнал):
24В ──────────┬──────── Датчик (+)
│
R_shunt (250 Ом)
│
GND ──────────┴──────── Датчик (-)
│
Измеряем U на R_shunt
4мА → 1.000В
20мА → 5.000В
В ПЛК: аналоговый вход 1–5В или через преобразователь ток→напряжение
def current_to_pressure(current_ma: float,
pressure_min: float,
pressure_max: float) -> float:
"""
Преобразование тока 4-20мА в давление.
Args:
current_ma: ток в мА (4.0..20.0)
pressure_min: давление при 4мА (нижний предел датчика)
pressure_max: давление при 20мА (верхний предел)
Returns:
давление в единицах pressure_min/max
"""
# Проверка обрыва линии
if current_ma < 3.8:
raise ValueError(f"Обрыв линии или ошибка датчика: {current_ma} мА")
# Проверка превышения
if current_ma > 20.5:
raise ValueError(f"Превышение тока: {current_ma} мА")
# Линейное масштабирование
# 4мА = 0%, 20мА = 100%
pct = (current_ma - 4.0) / 16.0
return pressure_min + pct * (pressure_max - pressure_min)
# ADC напряжение → ток → давление
def adc_voltage_to_pressure(voltage_v: float, shunt_ohm: float = 250.0,
p_min: float = 0.0, p_max: float = 16.0) -> float:
current_ma = voltage_v / shunt_ohm * 1000.0
return current_to_pressure(current_ma, p_min, p_max)
# Пример:
voltage = 2.5 # Вольт на шунте 250 Ом
current = 2.5 / 250 * 1000 # = 10 мА
pressure = current_to_pressure(current, 0, 16) # = 7.5 бар (середина диапазона)
Индуктивные датчики: металл без контакта
Индуктивный датчик (Inductive Proximity Sensor) обнаруживает металлические объекты без физического контакта.
Принцип: высокочастотное электромагнитное поле. При попадании металла в зону — меняется амплитуда генератора → срабатывание.
Дальность обнаружения зависит от металла:
Сталь (St37): номинальная дальность × 1.0
Нержавейка (304): × 0.7–0.85
Алюминий: × 0.4–0.5
Медь, латунь: × 0.35–0.45
Типичные параметры:
Диаметр: M8, M12, M18, M30 (стандартные серии)
Дальность: 2–50 мм
Выход: NPN или PNP, NO или NC
Питание: 10–30В DC
Частота переключения: до 3000–5000 Гц
Пример выбора:
Считать металлические детали на конвейере: M12, PNP NO, Sn=4 мм
Контроль положения поршня цилиндра: M8 встраиваемый, PNP NO
Подключение PNP к ПЛК с входом 24В:
+24В ──────── Коричневый провод датчика (питание)
Синий провод ────────────────────────── GND (0В)
Чёрный провод ── DI вход ПЛК ─── ↗ 24В при срабатывании
NPN подключение к ПЛК: +24В ────────────────────────────── DI
вход ПЛК Чёрный провод ─── DI вход ПЛК ──
↘ 0В при срабатывании
Ёмкостные датчики: любые материалы
Ёмкостной датчик (Capacitive) обнаруживает металлы, пластики, жидкости, порошки, дерево.
Принцип: электрод датчика образует конденсатор с объектом. Приближение объекта → рост ёмкости → срабатывание.
Применения:
Контроль уровня сыпучих материалов (зерно, цемент, порошки) сквозь стенку ёмкости
Обнаружение прозрачных объектов (стекло, пластик) — там, где оптика не работает
Контроль присутствия жидкости в трубе (сквозь пластик)
Счётчик таблеток/ампул на фармацевтическом конвейере
Особенность: требует настройки чувствительности под конкретный материал и расстояние (потенциометр или IO-Link).
Ультразвуковые датчики уровня
Принцип: излучают ультразвуковой импульс → принимают эхо → время до эха = расстояние.
Расстояние = v_звука × t_эхо / 2
v_звука ≈ 343 м/с при 20°C
Поправка на температуру:
v(T) = 331.5 + 0.606 × T(°C)
При T=40°C: v = 331.5 + 0.606×40 = 355.7 м/с
Ошибка без коррекции при 5м дальности: Δd = 5 × (355.7-343)/343 = 0.185 м = 18.5 см!
Пример: SR-04 (HC-SR04) на Arduino:
// HC-SR04: бюджетный датчик для прототипов (не промышленный!)
// Промышленные: Pepperl+Fuchs, Microsonic, ifm, Banner
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
float measure_distance_cm(float temp_celsius = 20.0) {
// Отправляем импульс 10 мкс
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Измеряем длительность эхо
unsigned long duration_us = pulseIn(ECHO_PIN, HIGH, 30000); // таймаут 30 мс
if (duration_us == 0) {
return -1; // Объект не найден или слишком далеко
}
// Расчёт расстояния с коррекцией температуры
float speed_cms = (331.5 + 0.606 * temp_celsius) * 100.0 / 1000000.0; // см/мкс
float distance = duration_us * speed_cms / 2.0;
return distance;
}
// Уровень в резервуаре:
float measure_tank_level(float tank_height_cm) {
float distance = measure_distance_cm(25.0);
if (distance < 0 || distance > tank_height_cm) return -1;
float level_pct = (1.0 - distance / tank_height_cm) * 100.0;
return max(0.0f, min(100.0f, level_pct));
}
Мёртвая зона: HC-SR04 не измеряет до 2 см. Промышленные: от 1–3 мм. Проблемы: пена на поверхности жидкости, пыль, ветер, наклонные поверхности, температурные градиенты.
Расходомеры: измерение потока
Электромагнитный (Flowmeter/Магнитный):
Только электропроводящие жидкости (вода, кислоты, суспензии)
Нет движущихся частей → долговечность
Нет потерь давления
Погрешность: 0.5–1%
Сигнал: 4–20 мА + импульсный выход (число импульсов = объём)
Вихревой (Vortex):
Жидкости и газы
Измеряет частоту вихрей (пропорциональна скорости)
Минимальный расход: ограничен (при малом расходе не работает)
Ультразвуковой (накладной / inline):
Накладной: крепится снаружи трубы без врезки!
Подходит для ретрофита существующих трубопроводов
Для чистых жидкостей (пузыри искажают сигнал)
Coriolis:
Измеряет массовый расход напрямую (не объём!)
Самый точный (0.1%), самый дорогой
Работает с любыми жидкостями, суспензиями, вязкими средами
Датчики вибрации: предиктивное обслуживание
import numpy as np
from scipy.fft import rfft, rfftfreq
from scipy.signal import find_peaks
class VibrationAnalyzer:
"""
Анализ вибрации для диагностики подшипников и валов.
Акселерометр: ADXL345 (I2C) или промышленный 4-20мА.
"""
def __init__(self, sample_rate: int = 1000):
self.sample_rate = sample_rate
def analyze(self, samples: np.ndarray, machine_rpm: float) -> dict:
"""
Полный анализ вибрационного сигнала.
machine_rpm: скорость вращения (об/мин) для идентификации гармоник
"""
n = len(samples)
# === ВРЕМЕННЫЕ ПОКАЗАТЕЛИ ===
rms = np.sqrt(np.mean(samples**2))
peak = np.max(np.abs(samples))
crest = peak / rms if rms > 0 else 0
# Эксцесс (Kurtosis): для обнаружения ударных дефектов
mean = np.mean(samples)
std = np.std(samples)
kurtosis = np.mean(((samples - mean) / std)**4) if std > 0 else 0
# === СПЕКТРАЛЬНЫЙ АНАЛИЗ ===
# Оконная функция для уменьшения утечек
window = np.hanning(n)
spectrum = np.abs(rfft(samples * window)) * 2 / n
freqs = rfftfreq(n, 1.0 / self.sample_rate)
# Основная частота вращения
f_rotation = machine_rpm / 60.0
# Поиск пиков в спектре
peaks_idx, peak_props = find_peaks(
spectrum, height=0.01 * np.max(spectrum), distance=5
)
peaks = [(float(freqs[i]), float(spectrum[i])) for i in peaks_idx]
peaks.sort(key=lambda x: -x[1]) # По убыванию амплитуды
# Идентификация характерных частот
identified = {}
for freq, amp in peaks[:10]:
# Гармоники вращения
for harmonic in range(1, 8):
if abs(freq - harmonic * f_rotation) < 2.0:
identified[f"{harmonic}x_rotation"] = (freq, amp)
# === ДИАГНОСТИКА ===
# ISO 10816-3: нормы вибрации для промышленных машин
# Класс 1 (малые): OK<2.3, WARN<4.5, CRIT<7.1 мм/с RMS
# Класс 2 (средние): OK<4.5, WARN<7.1, CRIT<11.0
rms_velocity_mms = rms / (2 * np.pi * f_rotation) * 1000 if f_rotation > 0 else 0
if rms_velocity_mms < 2.3:
iso_status = "Зона A (Хорошо)"
elif rms_velocity_mms < 4.5:
iso_status = "Зона B (Допустимо)"
elif rms_velocity_mms < 7.1:
iso_status = "Зона C (Внимание!)"
else:
iso_status = "Зона D (Опасно!)"
# Диагностика по Kurtosis
if kurtosis > 6:
bearing_diagnosis = "Дефект подшипника (ударные нагрузки)"
elif kurtosis > 4:
bearing_diagnosis = "Начальный износ подшипника"
else:
bearing_diagnosis = "Норма"
return {
'rms_g': round(rms, 4),
'peak_g': round(peak, 4),
'crest_factor': round(crest, 2),
'kurtosis': round(kurtosis, 2),
'rms_velocity_mms': round(rms_velocity_mms, 2),
'iso_status': iso_status,
'bearing_status': bearing_diagnosis,
'top_frequencies': peaks[:5],
'identified_harmonics': identified,
}
Калибровка: без неё данные не достоверны
Каждый датчик имеет погрешности: смещение (offset), нелинейность, дрейф со временем и температурой. Калибровка — сравнение с эталоном и коррекция.
def two_point_calibration(raw_low: float, ref_low: float,
raw_high: float, ref_high: float,
raw_measured: float) -> float:
"""
Двухточечная линейная калибровка.
raw_low, raw_high: показания датчика в нижней и верхней точках
ref_low, ref_high: эталонные значения в этих точках
raw_measured: текущее показание датчика
Пример: PT100 показывает 99.2 Ом при 0°C (вместо 100) и 138.9 при 100°C (вместо 138.5)
calibrated = two_point_calibration(99.2, 100.0, 138.9, 138.5, current_reading)
"""
if raw_high == raw_low:
return ref_low
# Линейная интерполяция
slope = (ref_high - ref_low) / (raw_high - raw_low)
offset = ref_low - slope * raw_low
return slope * raw_measured + offset
Периодичность калибровки:
Термопары: ежегодно или при замене
PT100: 1–2 раза в год (дрейф незначителен)
Датчики давления: раз в год или при смене диапазона
Расходомеры: согласно паспорту (обычно 1 раз в год)
Монтаж: правила, которые нельзя игнорировать
Температурные датчики:✅ Погружение на 1/2–2/3 диаметра трубы
✅ Против потока (для лучшего теплообмена)
✅ Защитный карман (гильза) из нержавейки
❌ На наружной поверхности трубы (ошибка до 50°C!)
❌ В зоне завихрений (после колен, до 10D от колена)
Датчики давления:
✅ Импульсные линии: уклон для самодренажа (для газа — вверх, для жидкости — вниз)
✅ Манометрический вентиль для обслуживания без остановки
❌ Прямое подключение к горячим/агрессивным средам без разделительного сосуда
Индуктивные датчики:
✅ Расстояние > 2× диаметра от соседних металлических поверхностей
✅ Осевая нагрузка — только через крепёжную гайку, не на корпус
❌ Монтаж в металлический кронштейн вплотную (ложные срабатывания)
Заключение
Правильный выбор датчика — это компромисс между точностью, диапазоном, стойкостью к среде, стоимостью и сложностью подключения. Никогда не выбирайте датчик по принципу "самый дешёвый" — плохой датчик в критическом месте обойдётся дороже в простоях и ремонтах.
Всегда изучайте datasheet: реальный диапазон рабочих температур, степень защиты IP, материал контактной части. И никогда не экономьте на монтаже — половина проблем с датчиками — это неправильный монтаж, а не неисправность прибора.
Create an account or sign in to leave a review
There are no reviews to display.