CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Датчики Холла

Датчик Холла — это датчик магнитного поля. Он был так назван из-за принципа своей работы — эффекта Холла: если в магнитное поле поместить пластину с протекающим через неё током, то электроны в пластине будут отклоняться в направлении, перпендикулярном направлению тока. В какую именно сторону будут отклоняться электроны, зависит от полярности магнитного поля:


  1. Электроны
  2. Пластина
  3. Магниты
  4. Магнитное поле
  5. Источник тока
Различная плотность электронов на сторонах пластины создаёт разность потенциалов, которую можно усилить и измерить, что датчики Холла и делают.

Датчики Холла (далее просто ДХ) бывают аналоговыми и цифровыми. Аналоговый преобразует индукцию магнитного поля в напряжение, знак и величина которого будут зависеть от полярности и силы поля. Цифровой же выдаёт лишь факт наличия/отсутствия поля, и обычно имеет два порога: включения — когда значение индукции выше порога, датчик выдает логическую единицу; и выключения — когда значение ниже порога, датчик выдаёт логический ноль. Наличие зоны нечувствительности между порогами называется гистерезисом и служит для исключения ложного срабатывания датчика на всяческие помехи — аналогично работает цифровая электроника с логическими уровнями напряжения. Цифровые ДХ делятся ещё на униполярные и биполярные: первые включаются магнитным полем определённой полярности и выключаются при снижении индукции поля; биполярные же включаются полем одной полярности, а выключаются полем противоположной полярности.

Аналоговый ДХ SS49E

Его размер — всего 4x3 мм, и он имеет три вывода:



Как видно, питание датчику нужно биполярное — тогда на южный полюс магнита датчик будет реагировать положительным уровнем на выходе, на северный — отрицательным, а на отсутствие поля — нулевым. Однако можно обойтись однополярным питанием — в этом случае уровень на выходе (Vo) в половину напряжения питания (Vdc/2) будет означать отсутствие магнитного поля, Vo > Vdc/2 — южный полюс, Vo < Vdc/2 — северный.

Характеристики при однополярном питании 5 В и температуре от -40 до 85 °C:
  • Потребляемый ток: от 6 до 10 мА
  • Выходной ток: от 1.0 до 1.5 мА
  • Выходное напряжение: от 1.0 до 1.75 мВ/Гс, в среднем 1.4 мВ/Гс (милливольт на гаусс)
  • Нулевая точка: от 2.25 до 2.75 В, в среднем 2.5 В
  • Магнитный диапазон: от ±650 Гс до ±1000Гс
  • Время отклика: 3 мс
Из этих данных следует, что при стандартном питании от Arduino (+5V, GND) при 25 °C датчик в отсутствие магнитного поля будет выдавать 2.5 В, а на поле силой 1000 Гс — 2.5 ± 1.4 В. Соответственно, если воспользоваться АЦП, разброс значений будет примерно в диапазоне от 280 до 800 со нулевой точкой в 512.

Приступим к экспериментам. Подключаем вывод “+” к 5V Arduino, вывод “-” к GND, оставшийся — к Analog 0:



Заливаем в Arduino следующий скетч:

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

void loop()
{
  Serial.println(analogRead(0));
  delay(500);
}

Не спеша подносим магнит вплотную сначала одним полюсом, потом другим, глядя в Serial monitor:



Цифровой биполярный ДХ TLE4945L

Выглядит он точно так же, как и аналоговый, даже выводы расположены так же:



Тут можно не бояться, биполярный он только в магнитном смысле, а питание ему можно подавать вполне себе обычное, однополярное. К слову, питание этот датчик принимает в довольно широком диапазоне — от 3.8 до 24 В, а ток может отдавать до 100 мА, что позволяет непосредственно от него запитывать управляемые им устройства (например, реле). Чувствительность у него почти точь-в-точь как у аналогового SS49E: от -600 Гс до -1000 Гс (северный полюс магнита) и от 600 Гс до 1000 Гс.

Подключается он чуть посложнее, чем аналоговый: выход датчика Q нужно подтянуть к питанию резистором в 10 кОм, так как выход у него с открытым коллектором:



А вот и суперсложное подключение, где выход Q подключен к цифровому пину 2:



Зальём в Arduino ещё один крутой скетч:

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

void loop()
{
 static uint8_t prev_state = LOW;

 uint8_t state = digitalRead(2);

 if (state != prev_state)
 {
    prev_state = state;
    Serial.println(state == LOW ? "OFF" : "ON");
 }
}

Теперь подносим магнит то одним полюсом, то другим и смотрим в Serial monitor:



Обратите внимание — датчик не переключается, пока не поднесёшь магнит другим полюсом, а ещё он очень чувствительный и переключается магнитом, вытащенным из дохлого CD-ROM’а, на расстоянии около 2 см!

Применение

Датчики Холла используются в качестве бесконтактных выключателей, как замена герконам, для бесконтактных замеров тока в проводниках, управления моторами, чтения магнитных кодов, измерения уровня жидкости (магнитный поплавок) и т.д.

Ну а я, имея два цифровых биполярных ДХ, сделаю бесконтактный магнитный энкодер. Принцип прост: на вращающийся диск лепим рядышком два магнита разными полюсами вверх (для униполярных ДХ хватит одного), а над ними размещаем цифровые ДХ и снимаем показания. Можно использовать скетч из статьи про энкодеры, но смотреть на стрелочки скучно, ведь хочется ещё посчитать обороты, так что напишем новый:

#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

/* Пины, к которым подключен энкодер */
enum { ENC_PIN1 = 2, ENC_PIN2 = 3 };

enum { FORWARD = 1, BACKWARD = -1 };

/* Если что, revolutions здесь и далее - обороты, а не революции (: */
long revolutions = 0, revolutions_at_last_display = 0;
int direction = FORWARD;
uint8_t previous_code = 0;

/* Реакция на событие поворота */
void turned(int new_direction)
{
  if (new_direction != direction)
  {
    revolutions = 0;
    revolutions_at_last_display = 0;
  }
  else
    ++revolutions;

  direction = new_direction;
}

/* Объеденил чтение кода Грея с энкодера с его декодированием */
uint8_t readEncoder(uint8_t pin1, uint8_t pin2)
{
  uint8_t gray_code = digitalRead(pin1) | (digitalRead(pin2) << 1), result = 0;

  for (result = 0; gray_code; gray_code >>= 1)
    result ^= gray_code;

  return result;
}

void setup()
{
  pinMode(ENC_PIN1, INPUT);
  pinMode(ENC_PIN2, INPUT);

  lcd.begin(8, 2);
}

void loop()
{
  /* Читаем значение с энкодера */
  uint8_t code = readEncoder(ENC_PIN1, ENC_PIN2);

  /* Обрабатываем его */
  if (code == 0)
  {
    if (previous_code == 3)
      turned(FORWARD);
    else if (previous_code == 1)
      turned(BACKWARD);
  }

  previous_code = code;

  /* Раз в секунду выводим накопленную информацию */

  static unsigned long millis_at_last_display = 0;

  if (millis() - millis_at_last_display >= 1000)
  {
    /* Выводим на экран направление вращения */
    lcd.clear();
    lcd.print(direction == FORWARD ? ">> " : "<< ");
    /* ... скорость вращения в оборотах в секунду */
    lcd.print(revolutions - revolutions_at_last_display);
    lcd.print("/s");
    /* ... и общее число обротов в текущем направлении */
    lcd.setCursor(0, 1);
    lcd.print(revolutions);
    
    millis_at_last_display = millis();
    revolutions_at_last_display = revolutions;
  }
}

Выглядеть конечная установка может так:





Я разобрал старый нерабочий жёсткий диск и установил на его пластину два магнита от системы позиционирования головки CD-ROMа на расстоянии ~5 мм друг от друга, а датчики разместил на креплении над пластиной, на расстоянии ~15 мм друг от друга. Вот как оно работает:



Если не нужно знать направление вращения, а хочется просто считать обороты, то можно обойтись вообще одним униполярным датчиком и одним магнитом (:
  • +3
  • 9 сентября 2011, 16:59
  • burjui

Комментарии (11)

RSS свернуть / развернуть
+
+1
Спасибо за статью. Как раз то что нужно именно сейчас.
avatar

Toxa

  • 10 сентября 2011, 23:27
+
0
Спасибо за статью.
А как подсчитать кол-во оборотов в единицу времени, т.е. скорость вращения?
avatar

lcc7

  • 21 сентября 2011, 18:58
+
+1
Так у меня же в скетче написано:

lcd.print(revolutions — revolutions_at_last_display);

Я сделал просто — каждую секунду отнимаю от текущего числа оборотов запомненное секундой ранее. Можете считать общее количество оборотов делить на время, прошедшее с последнего момента смены направления — тогда получите среднюю скорость вращения. Например, можете засекать время в фукции turned() в условии if (new_direction != direction).
avatar

burjui

  • 21 сентября 2011, 20:30
+
0
Спасибо за статью. Подскажите, а эти датчики могут не только переключаться при изменении магнитного поля, но и регистрировать промежуточные значения? Т.е. например, определять расстояние до магнита.
avatar

Homer

  • 23 сентября 2011, 19:37
+
+1
Аналоговые так могут, и те, что доступны мне (SS49E), реагируют на достаточно сильный магнит начиная с расстояния в 2 см. Так что сильно точно и далеко с ними не померишь. Перечитайте статью, там на скриншоте в описании аналогового датчика прекрасно видно, что значения меняются плавно в зависимости от расстояния до магнита.
Ну, а в цифровых датчиках промежуточные значения игнорируются умышленно, ибо сие есть суть цифровых устройств (:
avatar

burjui

  • 24 сентября 2011, 17:28
+
0
Спасибо за быстрый ответ. В статье увидел, что меняются, но было небольшое сомнение.
avatar

Homer

  • 24 сентября 2011, 17:48
+
0
А что делать с датчиками Холла у которых 4 вывода?
Такие датчики стоят под обмотками у двигателей CD-ROM.
Там 3 датчика и как узнать, какие именно датчики там стоят, сильно ли они отличаются?
avatar

Baxster

  • 12 декабря 2011, 14:10
+
0
Как всегда — пользуясь Google и интуицией. Если датчики не имеют никакой маркировки, тогда больше интуиция поможет. Могу только посоветовать сначала снимать с них сигнал, как с аналоговых, а там уж по значениям analogRead() будет ясно, какой датчик на самом деле. Выложите фотку этих датчиков, если не трудно — хоть полюбуемся все на такое чудо (:
avatar

burjui

  • 12 декабря 2011, 14:32
+
0
К сожалению уже 3 прошло, но если кто нибудь тут есть, скажите как можно реализовать счетчик оборотов на SS49E
avatar

EvgenT

  • 22 апреля 2014, 18:35
+
0
А как будет выглядеть скетч, если после остановки, при вращении в обратную сторону обороты уменьшаются до «0» затем меняют направление и начинают отчёт оборотов в другую сторону?
avatar

alexander

  • 25 мая 2015, 22:18
+
0
Cпасибо! Просто и со вкусом. А можно ли так же считывать показания двух датчиков для контроля вращения двух объектов?
avatar

Leon

  • 24 мая 2016, 20:45

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.