Калибровка датчиков

Калибровка нужна, когда сырое число датчика ещё не отвечает на вопрос робота. Код 700 с датчика линии, почвы или света сам по себе ничего не значит, пока мы не сравнили его с известными условиями.
Калибровка связывает сырые значения с понятной шкалой проекта: темно/светло, сухо/влажно, близко/далеко, линия/пол. Она не убирает шум, но помогает выбрать рабочие пороги и понять, где результат уже недостоверен.
Зачем это нужно
Одинаковые LDR-модули могут давать разные коды под одной лампой. Датчик влажности почвы зависит от земли и соли. Массив QTR на белом пластике и на серой фанере видит разные диапазоны. Поэтому значения из чужого проекта нельзя просто перенести в свой робот.
Примеры датчиков

| Датчик | Что калибруем | Типичные эталоны | Главный риск |
|---|---|---|---|
| LDR-модуль | код света | тень, рабочая лампа, окно | другой источник света меняет результат |
| QTR-8A | отражение линии | белое поле, чёрная линия, край | высота и поверхность меняют шкалу |
| Ёмкостный датчик почвы | влажность грунта | сухой грунт, влажный грунт | нет универсальных процентов |
| HC-SR04 | расстояние | линейка на нескольких точках | угол и материал объекта дают выбросы |
Главный вопрос: какие реальные условия считаются минимумом и максимумом именно для этого робота? Без ответа map() только красиво растягивает случайные числа.
Главная идея
Калибровка отделяет три задачи:
| Задача | Вопрос | Пример |
|---|---|---|
| Проверка диапазона | какие сырые значения возможны? | raw меняется от 180 до 840 |
| Привязка шкалы | что считать 0% и 100%? | сухая и влажная почва |
| Проверка решения | работает ли правило на новых данных? | робот едет по другому участку трассы |
Фильтр уменьшает разброс, но не исправляет неверный масштаб. Если сухая почва и влажная почва дают почти одинаковый код, сначала ищут физическую причину: питание, контакт, глубину, тип грунта или неисправный датчик.

Пошаговая процедура
- Определить, какое решение принимает робот: включить насос, повернуть по линии, остановиться перед стеной.
- Выбрать эталоны: сухо/влажно, белое/чёрное,
10 см/50 см. - Записать сырые значения без фильтра.
- Повторить измерения несколько раз и посмотреть разброс.
- Выбрать рабочий диапазон и пороги с запасом.
- Проверить результат на данных, которые не использовались при подборе.
- Сохранить параметры вместе с условиями опыта.
Калибровка значений на Arduino
Сначала полезно вывести сырые значения в Serial Monitor. Так видно, меняется ли датчик в ожидаемую сторону и какой реальный диапазон получается на вашей схеме.
const int SENSOR_PIN = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int raw = analogRead(SENSOR_PIN);
Serial.print("raw=");
Serial.println(raw);
delay(200);
}
После опыта выбирают границы. Допустим, на вашей трассе датчик линии даёт около 180 над чёрной линией и около 840 над белым полем. Эти числа лучше оформить константами, чтобы было понятно, откуда взялась шкала.
const int SENSOR_PIN = A0;
const int RAW_MIN = 180;
const int RAW_MAX = 840;
const int OUTPUT_MIN = 0;
const int OUTPUT_MAX = 100;
void setup() {
Serial.begin(9600);
}
void loop() {
int raw = analogRead(SENSOR_PIN);
int clipped = constrain(raw, RAW_MIN, RAW_MAX);
int percent = map(clipped, RAW_MIN, RAW_MAX, OUTPUT_MIN, OUTPUT_MAX);
Serial.print("raw=");
Serial.print(raw);
Serial.print(" clipped=");
Serial.print(clipped);
Serial.print(" percent=");
Serial.println(percent);
delay(200);
}
constrain() обрезает выбросы за пределами выбранного диапазона. map() переводит ограниченное значение в рабочую шкалу 0...100. Для датчика, у которого большее сырое значение означает меньше физической величины, границы выхода можно поменять местами: OUTPUT_MAX, OUTPUT_MIN.
Важно: RAW_MIN и RAW_MAX нельзя оставлять «примерными навсегда». Их подбирают на своём датчике, своём питании и своей механике.
Калибровка, настройка и фильтрация
| Действие | Меняет | Пример |
|---|---|---|
| Настройка | поведение модуля | потенциометр порога на TCRT5000 |
| Калибровка | связь сырых чисел с задачей | сухая и влажная почва |
| Фильтрация | разброс последовательных отсчётов | среднее из нескольких измерений |
Сначала проверяют физику и диапазон, потом калибруют шкалу, и только после этого выбирают фильтр. Иначе можно сгладить ошибку так, что она станет красивой, но всё равно неправильной.
Что запомнить про калибровку
- Сырое значение датчика не равно физической величине.
- Границы нужно измерять на своём экземпляре и в своих условиях.
constrain()защищает рабочую шкалу от выбросов за выбранный диапазон.map()удобен для простой линейной шкалы, но не делает датчик точным.- Фильтрация не заменяет калибровку.
Практика
- Выведите сырые значения любого аналогового датчика в Serial Monitor.
- Найдите минимальное и максимальное рабочее значение для своей задачи.
- Добавьте
constrain()иmap(), затем проверьте результат на промежуточных условиях. - Запишите в тетрадь модель датчика, питание, дату и условия калибровки.
Проверьте себя
- Почему нельзя взять порог датчика линии из чужого проекта?
- Чем настройка потенциометра отличается от калибровки в программе?
- Зачем печатать одновременно
raw,clippedиpercent? - Что произойдёт, если
RAW_MINиRAW_MAXпоменять местами?
Сначала ответьте без подсказки. Ответ можно считать полным, если вы:
- формулируете основную мысль своими словами;
- называете важные условия, ограничения или меры безопасности;
- для схемы, кода или расчёта показываете ход решения и ожидаемый результат.
Если один из пунктов объяснить не получается, найдите соответствующую главу статьи, перечитайте её и повторите ответ.
Словарь статьи
- Сырое значение — число, полученное напрямую от датчика или АЦП.
- Эталон — известное состояние, с которым сравнивают датчик.
- Калибровка — подбор связи между сырым значением и рабочей шкалой.
- Выброс — отдельное значение, резко отличающееся от ожидаемого.
- Порог — граница принятия решения.
Связанные темы
- АЦП — откуда берётся сырое значение аналогового входа.
- Датчики линии — как калибровка влияет на движение по трассе.
- Фильтрация данных с датчиков — что делать с шумом после калибровки.
Источники
- Arduino Documentation. analogRead().
- Arduino Documentation. constrain().
- Arduino Documentation. map().