Курс Arduino с нуля · Датчики

Урок 17. Датчик Холла: магнитный детектор

Плата получает чувство, которого нет у человека, — она видит магнитное поле. Определяем полюса магнита, измеряем силу поля и собираем датчик двери.

Урок 17 из 31⏱ примерно 45 минутОбновлено: 26 июля 2026

Что понадобится

  • Плата Uno из набора
  • Кабель USB
  • Макетная плата
  • Датчик Холла SS49E
  • Светодиод (любого цвета)
  • Резистор 470 Ом
  • 5 проводов «папа-папа»
  • Любой магнит (в набор не входит)

Все детали есть в обучающем наборе, по которому идёт курс.

Остался последний датчик набора — и, пожалуй, самый удивительный. Свет мы видим, наклон чувствуем, вибрацию слышим. А магнитное поле человек не ощущает никак: оно проходит сквозь стол, сквозь пластик, сквозь руку — и мы об этом даже не подозреваем.

Датчик Холла даёт нам это чувство. С ним плата научится замечать магнит через стенку коробки, отличать один полюс от другого и понимать, открыта дверь или закрыта.

Понадобится магнит — его в наборе нет. Подойдёт любой: магнитик с холодильника, магнит из старых наушников или из динамика, крепёж для штор. Чем сильнее, тем лучше видно эффект.

Что такое эффект Холла

Явление открыл Эдвин Холл в 1879 году, и объясняется оно неожиданно просто. Представьте тонкую пластинку, по которой течёт ток — заряды бегут вдоль неё. Если поднести магнит, поле начнёт сталкивать бегущие заряды к одному краю пластинки. На одном краю их станет больше, на другом меньше — а значит, между краями появится напряжение.

Внешний вид и выводыSS49E5 ВGNDсигналдержите плоской гранью к себеЧто происходит внутритонкая пластинка с токомтокмагнитное полепоявляется напряжение поперёкПоле сдвигает бегущие заряды в сторону —и на краях пластинки возникает разность напряжений.
Слева — деталь из набора: три ножки и плоская грань. Справа — что происходит внутри.

Это напряжение крошечное, поэтому внутри детали рядом с пластинкой сидит усилитель. Наружу выходит уже готовый сигнал — обычное аналоговое напряжение, которое мы умеем читать analogRead. Датчик так и называется — SS49E, и он линейный: показывает не только «есть магнит или нет», но и насколько он силён.

Три ножки — и одну нельзя перепутать

У датчика три вывода: два для питания и один сигнальный. Держите деталь плоской гранью к себе, ножками вниз — тогда слева направо идут: 5 вольт, земля, сигнал.

Питание перепутывать нельзя. Светодиод от переворота просто не загорится, а микросхема внутри датчика от обратного питания может выйти из строя. Прежде чем включать USB, проверьте: крайняя левая ножка — в шину «+», средняя — в шину «−».

Собираем схему

++abcdefghij11020456121517SS49E123451Датчик Холла: три ножки в столбики 4, 5 и 6 (ряд b), плоской гранью к себе.2Питание: столбик 4 — в шину «+», столбик 5 — в шину «−». Перепутать нельзя!3Жёлтый провод: сигнальная ножка (столбик 6) → вход A0 платы.4Светодиод: вывод 10 → резистор 470 Ом → длинная ножка; короткая — в шину «−».5Питание макетки: 5V платы → шина «+», GND → шина «−».
Датчик тремя ножками в соседние столбики, сигнал — на A0, светодиод остаётся на выводе 10.
UnoA0D10GNDDD1SS49E5 ВVD1R1 470 ОмУ датчика три вывода: два на питание, третий выдаёт напряжение — его и читает вход A0.
На чертеже датчик рисуют прямоугольником: он ведь целая микросхема, а не одна деталь.

Проверьте перед включением: плоская грань датчика смотрит на вас; левая ножка — питание, средняя — земля, правая — сигнал; сигнальный провод идёт на A0, а не на цифровой вывод.

Шаг 1. Смотрим на тишину

const int HALL = A0;

void setup() {
  Serial.begin(9600);
  Serial.println("Показания датчика Холла:");
}

void loop() {
  Serial.println(analogRead(HALL));
  delay(100);
}

Откройте монитор порта, не поднося магнит. Число будет колебаться где-то около 500 — примерно половина шкалы. Это и есть «тишина»: магнитного поля нет, и датчик выдаёт половину питания, то есть около 2,5 вольта.

0≈ 5121023магнита нетодин полюс — число падаетдругой полюс — число растётЧем ближе магнит, тем сильнее отклонение от середины.
Особенность линейного датчика Холла: покой — это середина шкалы, а не ноль.

Теперь поднесите магнит одной стороной — число поедет вверх. Переверните магнит и поднесите другой стороной — поедет вниз. Вы только что своими глазами увидели, чем северный полюс отличается от южного.

Датчик видит сквозь предметы. Положите лист бумаги, книгу или пластиковую крышку между магнитом и датчиком — показания не изменятся. Магнитное поле спокойно проходит через всё, кроме железа. Именно поэтому такие датчики ставят в герметичные корпуса и в подводную технику.

Шаг 2. Считаем отклонение, а не показание

У каждого экземпляра датчика своя «тишина»: у одного 498, у другого 517. Работать с сырым числом неудобно — гораздо разумнее измерить свой ноль при включении и дальше считать отклонение от него.

const int HALL = A0;

int zero = 512;   // показание без магнита, измеряется при включении

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

  // Полсекунды усредняем показания — это и есть наш ноль.
  long sum = 0;
  for (int i = 0; i < 50; i++) {
    sum = sum + analogRead(HALL);
    delay(10);
  }
  zero = sum / 50;

  Serial.print("ноль датчика: ");
  Serial.println(zero);
}

void loop() {
  int value = analogRead(HALL);

  // Отклонение может быть и в плюс, и в минус.
  int offset = value - zero;

  Serial.print(value);
  Serial.print("   отклонение: ");
  Serial.println(offset);

  delay(100);
}

Знакомый приём: то же самое мы делали с датчиком света и с сигнализацией. Прибор подстраивается под себя сам, и программа перестаёт зависеть от конкретного экземпляра детали.

Обратите внимание: отклонение бывает и отрицательным. Число −80 означает, что поле сдвинуло сигнал ниже середины. Раньше нам такое не встречалось — все наши датчики выдавали только положительные значения.

Шаг 3. Определяем полюс

Раз знак отклонения зависит от полюса магнита, программа легко их различит:

const int HALL = A0;
const int LED = 10;
const int THRESHOLD = 30;   // меньше этого считаем, что магнита нет

int zero = 512;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);

  long sum = 0;
  for (int i = 0; i < 50; i++) {
    sum = sum + analogRead(HALL);
    delay(10);
  }
  zero = sum / 50;

  Serial.println("Подносите магнит разными сторонами.");
}

void loop() {
  int offset = analogRead(HALL) - zero;

  if (offset > THRESHOLD) {
    Serial.println("один полюс");
    digitalWrite(LED, HIGH);
  } else if (offset < -THRESHOLD) {
    Serial.println("другой полюс");
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }

  delay(150);
}

Обратите внимание на конструкцию else if — «иначе, если». Она позволяет проверить несколько условий по очереди: сначала одно, если не подошло — другое, и только потом else для всех остальных случаев.

Поднесите магнит одной стороной, потом другой — и подпишите на нём маркером, где север. Настоящая физическая лаборатория на макетной плате: у вас появился прибор, который знает то, чего не знаете вы.

Шаг 4. Индикатор силы поля

Теперь пусть яркость светодиода показывает, насколько близко магнит — независимо от того, каким полюсом он повёрнут:

const int HALL = A0;
const int LED = 10;

int zero = 512;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);

  long sum = 0;
  for (int i = 0; i < 50; i++) {
    sum = sum + analogRead(HALL);
    delay(10);
  }
  zero = sum / 50;
}

void loop() {
  int offset = analogRead(HALL) - zero;

  // abs берёт число без знака: и +80, и -80 дают 80.
  int power = abs(offset);

  int bright = map(power, 0, 200, 0, 255);
  analogWrite(LED, constrain(bright, 0, 255));

  delay(20);
}

Новая команда — abs. Она убирает знак: и +80, и −80 превращаются в 80. То есть нас интересует уже не направление поля, а только его сила.

Поводите магнитом над датчиком — светодиод разгорается и гаснет, как будто вы играете на невидимой струне. Кстати, число 200 в map подберите под свой магнит: слабому хватит и 60, сильный неодимовый даст все 400.

Шаг 5. Датчик двери

Соберём то, что стоит в каждой охранной системе. Магнит крепится на дверь, датчик — на косяк. Дверь закрыта — магнит рядом, отклонение большое. Открыли — магнит уехал, отклонение упало почти до нуля.

const int HALL = A0;
const int LED = 10;

// Два порога: магнит рядом — дверь закрыта, уехал — открыта.
const int CLOSE_LEVEL = 60;
const int OPEN_LEVEL = 35;

int zero = 512;
bool doorOpen = false;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);

  long sum = 0;
  for (int i = 0; i < 50; i++) {
    sum = sum + analogRead(HALL);
    delay(10);
  }
  zero = sum / 50;

  Serial.println("Датчик двери готов.");
}

void loop() {
  int power = abs(analogRead(HALL) - zero);

  if (!doorOpen && power < OPEN_LEVEL) {
    doorOpen = true;
    Serial.println("дверь открыли");
  }

  if (doorOpen && power > CLOSE_LEVEL) {
    doorOpen = false;
    Serial.println("дверь закрыли");
  }

  digitalWrite(LED, doorOpen);
  delay(30);
}

И снова два порога — гистерезис из пятнадцатого урока. Без него в момент, когда дверь приоткрыта на пару сантиметров, устройство сходило бы с ума. Приём один и тот же, а применений у него не счесть.

Почему тут именно датчик Холла, а не кнопка? Потому что в нём нечему изнашиваться: он не касается двери и не имеет подвижных частей. Такой датчик работает годами, ему не мешают пыль и влага, и его невозможно заклинить. По той же причине его ставят в стиральных машинах — чтобы понимать, закрыт ли люк.

Не работает? Разбираемся

  • Показания около 0 или около 1023 и не меняются. Перепутаны ножки: скорее всего, сигнальная стоит там, где ожидалось питание. Выньте датчик, разверните плоской гранью к себе и вставьте заново.
  • Датчик заметно нагрелся. Немедленно отключите USB: питание подано наоборот. Проверьте, что левая ножка идёт в шину «+», а средняя — в «−».
  • Магнит рядом, а число не двигается. Подносите магнит к плоской грани — датчик чувствует поле, направленное сквозь неё. Сбоку чувствительность гораздо ниже.
  • Число дёргается на единицы. Это обычный шум аналогового входа. Усредните десяток измерений, как в четырнадцатом уроке, — дрожание пропадёт.
  • Отклонение всегда отрицательное. Просто ваш магнит повёрнут другой стороной. Переверните его — или используйте abs, если полюс не важен.
  • Ноль измерился неправильно. Магнит лежал рядом в момент включения. Уберите его подальше и нажмите RES на плате.

Задания для тренировки

  • РазминкаСравните силу разных магнитов: поднесите каждый вплотную к датчику и запишите отклонение. Кто в доме самый сильный — магнитик с холодильника или динамик наушника?
  • ПосложнееСделайте «магнитную линейку»: пусть плата печатает, на каком примерно расстоянии находится магнит. Подсказка: снимите несколько замеров с линейкой и подберите границы для map.
  • Со звёздочкой ⭐Посчитайте обороты: приклейте магнит к колесу или к крышке и считайте, сколько раз он проехал мимо датчика. Так устроен велосипедный спидометр. Разбор ниже.
Показать разбор «счётчик проездов»

Ловушка тут ровно та же, что была с кнопкой в одиннадцатом уроке. Пока магнит проезжает мимо, условие «магнит рядом» верно на сотнях проходов loop(). Считать нужно не состояние, а событие — момент появления магнита.

const int HALL = A0;
const int LED = 10;
const int THRESHOLD = 60;

int zero = 512;
bool magnetNear = false;
int passes = 0;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(9600);

  long sum = 0;
  for (int i = 0; i < 50; i++) {
    sum = sum + analogRead(HALL);
    delay(10);
  }
  zero = sum / 50;

  Serial.println("Считаю проезды магнита:");
}

void loop() {
  int power = abs(analogRead(HALL) - zero);

  // Событие — не «магнит рядом», а «магнит ТОЛЬКО ЧТО появился».
  if (!magnetNear && power > THRESHOLD) {
    magnetNear = true;
    passes = passes + 1;

    Serial.print("проезд № ");
    Serial.println(passes);
  }

  // Отпускаем счётчик, когда магнит явно уехал — тот же гистерезис.
  if (magnetNear && power < THRESHOLD / 2) {
    magnetNear = false;
  }

  digitalWrite(LED, magnetNear);
}

Переменная magnetNear помнит, был ли магнит рядом на прошлом проходе. Счётчик растёт только в тот момент, когда «не было» сменилось на «есть». А отпускается флаг при вдвое меньшем пороге — это снова гистерезис, иначе на границе счётчик намотал бы лишнего.

Добавьте millis() — и по времени между проездами можно вычислить скорость. Именно так велокомпьютер узнаёт, с какой скоростью вы едете: он просто засекает, как часто магнит на спице пролетает мимо датчика.

Что мы узнали

  • Датчик Холла превращает магнитное поле в напряжение. SS49E — линейный: показывает и наличие поля, и его силу, и полюс.
  • У него три вывода, и питание перепутывать нельзя — деталь можно сжечь.
  • Покой у такого датчика — середина шкалы, около 512. Полезная величина — отклонение от неё, и оно бывает отрицательным.
  • abs убирает знак, когда важна только сила, а не направление.
  • Магнитное поле проходит сквозь неметаллические преграды — поэтому такие датчики работают в закрытых и грязных местах, где кнопка не выживет.

Все датчики набора освоены: свет, наклон, вибрация, магнит и крутилка. Пора собрать из них настоящее устройство. В следующем уроке — проект «Умный ночник»: он сам включается в темноте, слушается кнопки, настраивается крутилкой и переключает режимы. Это первый прибор курса, который не стыдно поставить на полку.

Частые вопросы

Что такое эффект Холла простыми словами?

По тонкой пластинке течёт ток. Магнитное поле сталкивает бегущие заряды к одному её краю, и между краями появляется напряжение. Чем сильнее поле, тем больше это напряжение — его и измеряет плата.

Почему датчик Холла без магнита показывает около 512, а не 0?

SS49E — линейный датчик: он должен различать оба полюса. Поэтому в покое он выдаёт половину питания, около 2,5 вольта. Один полюс поднимает напряжение выше середины, другой опускает ниже.

Как определить выводы датчика SS49E?

Держите деталь плоской гранью к себе, ножками вниз: слева направо идут питание 5 вольт, земля и сигнал. Питание перепутывать нельзя — от обратного включения датчик может выйти из строя.

Входит ли магнит в набор?

Нет, магнит нужно взять свой. Подойдёт любой: магнитик с холодильника, магнит из старых наушников или динамика. Чем он сильнее, тем заметнее отклонение показаний.

← Все уроки курса