Курс Arduino с нуля · Датчики
Урок 17. Датчик Холла: магнитный детектор
Плата получает чувство, которого нет у человека, — она видит магнитное поле. Определяем полюса магнита, измеряем силу поля и собираем датчик двери.
Что понадобится
- Плата Uno из набора
- Кабель USB
- Макетная плата
- Датчик Холла SS49E
- Светодиод (любого цвета)
- Резистор 470 Ом
- 5 проводов «папа-папа»
- Любой магнит (в набор не входит)
Все детали есть в обучающем наборе, по которому идёт курс.
Остался последний датчик набора — и, пожалуй, самый удивительный. Свет мы видим, наклон чувствуем, вибрацию слышим. А магнитное поле человек не ощущает никак: оно проходит сквозь стол, сквозь пластик, сквозь руку — и мы об этом даже не подозреваем.
Датчик Холла даёт нам это чувство. С ним плата научится замечать магнит через стенку коробки, отличать один полюс от другого и понимать, открыта дверь или закрыта.
Понадобится магнит — его в наборе нет. Подойдёт любой: магнитик с холодильника, магнит из старых наушников или из динамика, крепёж для штор. Чем сильнее, тем лучше видно эффект.
Что такое эффект Холла
Явление открыл Эдвин Холл в 1879 году, и объясняется оно неожиданно просто. Представьте тонкую пластинку, по которой течёт ток — заряды бегут вдоль неё. Если поднести магнит, поле начнёт сталкивать бегущие заряды к одному краю пластинки. На одном краю их станет больше, на другом меньше — а значит, между краями появится напряжение.
Это напряжение крошечное, поэтому внутри детали рядом с пластинкой сидит усилитель. Наружу выходит уже готовый сигнал — обычное аналоговое напряжение, которое мы умеем читать analogRead. Датчик так и называется — SS49E, и он линейный: показывает не только «есть магнит или нет», но и насколько он силён.
Три ножки — и одну нельзя перепутать
У датчика три вывода: два для питания и один сигнальный. Держите деталь плоской гранью к себе, ножками вниз — тогда слева направо идут: 5 вольт, земля, сигнал.
Питание перепутывать нельзя. Светодиод от переворота просто не загорится, а микросхема внутри датчика от обратного питания может выйти из строя. Прежде чем включать USB, проверьте: крайняя левая ножка — в шину «+», средняя — в шину «−».
Собираем схему
Проверьте перед включением: плоская грань датчика смотрит на вас; левая ножка — питание, средняя — земля, правая — сигнал; сигнальный провод идёт на A0, а не на цифровой вывод.
Шаг 1. Смотрим на тишину
const int HALL = A0;
void setup() {
Serial.begin(9600);
Serial.println("Показания датчика Холла:");
}
void loop() {
Serial.println(analogRead(HALL));
delay(100);
}
Откройте монитор порта, не поднося магнит. Число будет колебаться где-то около 500 — примерно половина шкалы. Это и есть «тишина»: магнитного поля нет, и датчик выдаёт половину питания, то есть около 2,5 вольта.
Теперь поднесите магнит одной стороной — число поедет вверх. Переверните магнит и поднесите другой стороной — поедет вниз. Вы только что своими глазами увидели, чем северный полюс отличается от южного.
Датчик видит сквозь предметы. Положите лист бумаги, книгу или пластиковую крышку между магнитом и датчиком — показания не изменятся. Магнитное поле спокойно проходит через всё, кроме железа. Именно поэтому такие датчики ставят в герметичные корпуса и в подводную технику.
Шаг 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 вольт, земля и сигнал. Питание перепутывать нельзя — от обратного включения датчик может выйти из строя.
Входит ли магнит в набор?
Нет, магнит нужно взять свой. Подойдёт любой: магнитик с холодильника, магнит из старых наушников или динамика. Чем он сильнее, тем заметнее отклонение показаний.
