Измеритель магнитной индукции на датчике холла и stm32

STM Урок 49. HAL. Магнитометр LSM303DLHC. Часть 2

В прошлой части урока мы кратко изучили документацию на магнитометр, создали для него проект, добавили некоторые макросы и написали функцию инициализации датчика.

Добавим функцию считывания данных с осей магнитометра, скопировав и исправив подобную для осей акселерометра

void Mag _GetXYZ(int16_t* pData)

buffer[0] = Accel_IO_Read( MAG_I2C_ADDRESS,LSM303DLHC_OUT_X_H_M );

buffer[1] = Accel_IO_Read( MAG_I2C_ADDRESS,LSM303DLHC_OUT_X_L_M );

buffer[2] = Accel_IO_Read( MAG_I2C_ADDRESS,LSM303DLHC_OUT_Y_H_M );

buffer[3] = Accel_IO_Read( MAG_I2C_ADDRESS,LSM303DLHC_OUT_Y_L_M );

buffer[4] = Accel_IO_Read( MAG_I2C_ADDRESS,LSM303DLHC_OUT_Z_H_M );

buffer[5] = Accel_IO_Read( MAG_I2C_ADDRESS,LSM303DLHC_OUT_Z_L_M );

if(pData[i]!=-4096) pData [i]=((int16_t)((uint16_t)buffer[ 2*i ] 2*i+1 ]);

У функции Accel_ReadAcc поменяем имя на Accel Mag _Read, также изменив её и раскомментировав в файле main.c в бесконечном цикле

void Accel Mag _Read(void)

/* USER CODE BEGIN 3 */

Accel Mag _Read();

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

static int16_t val[3], tmp16;

Пишем данную функцию дальше

//уберем переполнение из показаний осей

tmp16=buffer[0]; if(tmp16!=-4096) val[0]=tmp16;

tmp16=buffer[1]; if(tmp16!=-4096) val[1]=tmp16;

tmp16=buffer[2]; if(tmp16!=-4096) val[2]=tmp16;

Из комментария здесь в принципе всё ясно.

Дальше немного подправим код

tmp16=buffer[2]; if(tmp16!=-4096) val[2]=tmp16;

sprintf(str1,»X:%06d Y:%06d Z:%06drn», val [0] , val [1] , val [2] );

// buf2[2]=(uint8_t)(val [0] >>8);

// buf2[4]=(uint8_t)(val [1] >>8);

// buf2[6]=(uint8_t)(val [2] >>8);

Исправляем код дальше, поменяв в нём также местами светодиоды в связи с определённым положением осей магнитометра

Соберем код, прошьем контроллер и посмотрим в терминале показания осей

Покрутим плату относительно всех трёх и сверим показания. На основании данной сверки внесем корректировку нулей в код. То есть мы сверяем максимальное положительное показание по каждой оси с максимальным отрицательным показанием по той же оси, складываем их и результат делим пополам. Лучше всего ориентировать каждую ось вертикально в разных направлениях. Вообщем, если показания будут отличаться только знаком, то корректировать не нужно, а если будет отличие по модулю то корректируем по знаку в сторону меньшего.

Например, показания по X у нас в среднем -165 и 165, значит корректировка по данной оси нам не требуется.

Проделаем то же самое для остальных трёх осей. У меня получилось вот так

tmp16=buffer[0]; if(tmp16!=-4096) val[0]=tmp16;

tmp16=buffer[1]; if(tmp16!=-4096) val[1]=tmp16 +40 ;

tmp16=buffer[2]; if(tmp16!=-4096) val[2]=tmp16 -50 ;

Вообще, если мы реализовываем компас, то по-хорошему мы должны подключать акселерометр с гироскопом и в значениях по осям мы должны кроме магнитной индукции также учитывать значение крена и тангажа. Но так как мы используем только магнитометр, то нам придется обойтись только показанием магнитной индукции.

Теперь мы раскомментируем код для визуализации данных, а для текстового вывода наоборот закомментируем

tmp16=buffer[2]; if(tmp16!=-4096) val[2]=tmp16-50;

// sprintf(str1,»X:%06d Y:%06d Z:%06drn», val[0], val[1], val[2]);

Я немного подправил свои программки визуализации данных под собственно магнитометр. Запустим первую из них. Покрутим немного плату

Из данной картины мы видим, что наш магнитометр работает нормально, только единственное, присутствует некоторый шум. Давайте всё-таки сочиним некоторый низкочастотный фильтр. Самым простейшим фильтром, но и в то же время вполне работающим мне показалось скользящее среднее. Я исследовал некоторое количество передового опыта по данной теме, и всё-таки решил сочинить свою реализацию. Вообще скользящее среднее основано на том, что мы собираем определённое количество показаний подряд каждого измеренного значения, вычисляем их среднее арифметическое и используем его уже на выходе. Затем после следующего измеренного значения мы берем столько же последних показаний и также вычисляем их среднее арифметическое. Но на деле данная операция проводится немного не так. Мы сначала набираем буфер из определенного количества измеренных подряд показаний, находим среднее арифметическое, но также запоминаем их сумму, не разделенную ещё на количество показаний. Затем мы к данной сумме прибавляем следующее измеренное показание и вычитаем самое старое показание, а затем делим на количество показаний. И так далее. То есть при больших количествах значений нам не приходится каждый раз складывать их, что вносит оптимизацию в код и экономит процессорное время.

Я данный алгоритм реализовал следующим образом. Набрал буфер, нашел среднее арифметическое. Затем беру участок буфера с количеством элементов меньшим на один, чем общее количество элементов буфера и сдвигаю их как обычный участок памяти. Тем самым освобождается один элемент, в который мы и запишем новое значение. Работает данный трюк только в одну сторону, в другую не работает. В другую приходится сначала копировать в другой буфер потом уже копировать в нужный участок этого. Нам это не подходит, так как время операции удваивается, и мы поэтому выбираем первый вариант.

Вот, собственно и код функции вычисления скользящего среднего. Сначала добавим глобальные переменные

//буферы для скользящего среднего

volatile int16_t xbuf_avg[8]=<0>,ybuf_avg[8]=<0>,zbuf_avg[8]=<0>;

//счётчик наполнения буферов скользящего среднего

  • Все
  • Тематические

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

    1. Электроны
    2. Пластина
    3. Магниты
    4. Магнитное поле
    5. Источник тока

    Различная плотность электронов на сторонах пластины создаёт разность потенциалов, которую можно усилить и измерить, что датчики Холла и делают.

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

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

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

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

  • Нулевая точка: от 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 следующий скетч:

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

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

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

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

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

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

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

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

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

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

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

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

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

5 мм друг от друга, а датчики разместил на креплении над пластиной, на расстоянии

15 мм друг от друга. Вот как оно работает:

Если не нужно знать направление вращения, а хочется просто считать обороты, то можно обойтись вообще одним униполярным датчиком и одним магнитом (:

Измерение напряженности магнитного поля с помощью Arduino

В этом проекте мы будем использовать датчик Холла и плату Arduino Uno для измерения напряженности магнитного поля. Мы будем использовать датчик Холла с наименованием UGN3503U, который измеряет величину напряженности магнитного поля и обеспечивает на своем выходе аналоговое напряжение пропорциональное напряженности магнитного поля, которое мы затем будем переводить с помощью аналогового-цифрового преобразования в Arduino в цифровой вид. Датчик измеряет напряженность магнитного поля (электромагнитную индукцию) в гауссах (GAUSS). Один гаусс равен одной десятитысячной Тесла (Тл).

Величину напряженности магнитного поля, преобразованную в цифровую форму с помощью Arduino, мы затем будем показывать на ЖК дисплее 16х2.

Плата Arduino имеет 6 каналов АЦП (аналогового-цифрового преобразования). Любой из них можно использовать в качестве аналогового входа. АЦП Arduino Uno имеет разрешающую способность 10 бит, что соответствует значениям целых чисел в диапазоне 0-(2^10) 1023. Это означает что входное напряжение в диапазоне от до 5 Вольт преобразуется в целое число от 0 до 1023. То есть одному цифровому значению (шагу) соответствует шаг аналогового напряжения 5/1024= 4.9mV.

В нашем проекте мы будем подключать аналоговый выход датчика Холла к контакту ‘A0’ платы Arduino Uno.

Более подробно о датчике Холла можно прочитать в этой статье: подключение датчика Холла к микроконтроллеру AVR.

Необходимые компоненты

  1. Плата Arduino Uno (купить на AliExpress).
  2. Датчик Холла UGn3503U (купить на AliExpress).
  3. ЖК дисплей JHD_162ALCD (16×2) (купить на AliExpress).
  4. Конденсатор 100 мкФ (2 шт.) (купить на AliExpress).
  5. Источник питания с напряжением 5 В.

Работа схемы и программы

Схема устройства представлена на следующем рисунке.

Жидкокристаллический (ЖК) дисплей 16×2 использует 16 контактов для своей работы в случае если нужен черный цвет. Если черный цвет не нужен, то достаточно 14 контактов. В этом случае контакты черного цвета можно либо запитать, либо оставить их как есть. То есть из 14 контактов ЖК дисплея мы имеем 8 контактов для данных (7-14 или D0-D7), 2 контакта для подачи питания (1&2 или VSS&VDD или GND&+5v), 3-й контакт для управления контрастностью (VEE) – определяет насколько «толстыми» будут выглядеть символы на экране, и 3 управляющих контакта (RS&RW&E).

На представленной схеме мы использовали только 2 управляющих контактах ЖК дисплея – это позволяет лучше понять логику работы схемы начинающим. Контакт для управления контрастностью и READ/WRITE сравнительно редко используются и в нашем случае их можно замкнуть на землю. Это переводит ЖК дисплей в режим чтения и обеспечивает ему максимальную контрастность. Поэтому нам нужно только управлять состоянием контактов ENABLE и RS чтобы передавать символы и данные на ЖК дисплей.

В схеме необходимо сделать следующие соединения с ЖК дисплеем:
PIN1 или VSS – на землю
PIN2 или VDD или VCC – к источнику питания +5 В
PIN3 или VEE – на землю (обеспечивает наилучшую контрастность – лучше для начинающих)
PIN4 или RS (выбор регистра) – к контакту PIN8 ARDUINO UNO
PIN5 или RW (Read/Write) – на землю (переводит ЖК дисплей в режим чтения, что упрощает взаимодействие с ним для начинающих)
PIN6 или E (Enable — доступность) к контакту PIN9 ARDUINO UNO
PIN11 или D4 – к контакту PIN10 ARDUINO UNO
PIN12 или D5 – к контакту PIN11 ARDUINO UNO
PIN13 или D6 – к контакту PIN12 ARDUINO UNO
PIN14 или D7 – к контакту PIN13 ARDUINO UNO

ARDUINO IDE позволяет пользователю использовать ЖК дисплей в 4 битном режиме. Этот режим позволяет уменьшить число используемых контактов ARDUINO. 4-битный режим взаимодействия с ЖК дисплеем предусмотрен для ARDUINO по умолчанию, поэтому нет необходимости предпринимать какие либо действия чтобы его включить. В представленной схеме можно увидеть, что мы использовали 4-битный режим (D4-D7). То есть у нас с ARDUINO соединено 6 контактов ЖК дисплея: 4 контакта для передачи данных и 2 контакта для управления.

Чтобы задействовать АЦП в Arduino Uno необходимо сделать следующие вещи:

1. analogRead(pin);
2. analogReference();
3. analogReadResolution(bits);

Плата Arduino Uno по умолчанию имеет опорное напряжение АЦП равное 5 В. То есть максимальное входное напряжение для АЦП будет равно 5 В. Но поскольку некоторые датчики обеспечивают на своем выходе напряжение в диапазоне 0-2.5 В, то в этом случае если мы будем использовать опорное напряжение АЦП 5 В, то мы потеряем в точности преобразования. Поэтому в Arduino предусмотрена специальная команда для изменения опорного напряжения АЦП (“ analogReference(); ”.

Максимальная разрешающая способность (разрешение) АЦП платы Arduino составляет 10 бит, изменить его можно с помощью команды “ analogReadResolution(bits) ;”. Эта функция может быть полезна в некоторых случаях, например, когда нужно увеличить скорость аналого-цифрового преобразования.

Теперь, если все установки работы с АЦП выполнены, мы можем непосредственно считать значение с выхода АЦП с помощью функции “ analogRead(pin); ”, где “pin” обозначает номер контакта, с которого мы будем считывать аналоговый сигнал. В нашем случае это будет контакт “A0”. Значение с выхода АЦП можно сразу присвоить переменной целого типа (integer) с помощью команды “ int ADCVALUE = analogRead(A0); ”.

Для взаимодействия с ЖК дисплеем прежде всего необходимо подключить библиотеку для работы с ним с помощью инструкции ‘ #include
’. Эта библиотека сразу по умолчанию включает 4-битный режим взаимодействия с ЖК дисплеем.

После этого необходимо сообщить Arduino тип подключаемого ЖК дисплея. ЖК дисплеи бывают различных типов, например 20×4, 16×2, 16×1 и т.д. В нашем случае мы будем подключать к Arduino ЖК дисплей 16×2, поэтому нам необходимо использовать инструкцию ‘ lcd.begin(16, 2); ’.

Далее плате Arduino необходимо сообщить, к каким ее контактам мы подключили ЖК дисплей. В соответствии с представленной схемой нам необходимо использовать команду LiquidCrystal lcd(8, 9, 10, 11, 12, 13) , которая сообщит Arduino что ЖК дисплей подключен к ее контактам 8, 9, 10, 11, 12 и 13.

После выполнения всех этих действий можно приступать к передаче данных на ЖК дисплей.

Исходный код программы

Представленная программа должна делать следующие действия: как только вблизи датчика Холла появляется какой-нибудь магнит (магнитное поле) напряжение на его выходе изменяется, значение этого напряжения подается на АЦП платы Arduino, которая переводит его в цифровую форму (число от 0 до 1023). После этого значение напряженности магнитного поля высвечивается на ЖК дисплее.

Подключение магнитного энкодера AS5048 к микроконтроллеру.

Приветствую всех на нашем сайте! У меня лежит комплект датчиков с AliExpress, так вот я решил сделать своего рода обзор и пример программы для работы с ними. Речь идет о магнитных энкодерах AS5048. Задача определения угла в различных проектах встречается довольно часто, а эти датчики себя проявили с наилучшей стороны, поэтому нельзя обойти их вниманием 🙂 И для примера подключения энкодера мы будем использовать контроллер STM32.

Классификация энкодеров как таковых достаточно обширна. Например, различают два больших класса:

  • Инкрементальный энкодер – позволяет отследить изменение положения относительно некой начальной точки. Эта начальная точка соответствует положению датчика в момент подачи на него питания.
  • Абсолютный энкодер – в любой момент времени позволяет получить точную однозначную информацию о своем положении в определенном диапазоне и конкретных единицах.

Очевидно, что использование абсолютного энкодера в большинстве задач сильно облегчает жизнь. Но как и всегда, не все так просто, абсолютные энкодеры обычно дороже инкрементальных, что сужает возможность их применения.

Два других крупных класса энкодеров определяют их внутреннее устройство и принцип действия:

  • Оптические энкодеры – состоят из источника света, специального оптического диска и фотоприемника. Диск содержит прозрачные и непрозрачные области, что позволяет по данным фотоприемника получить информацию об изменении положения.
  • Магнитные энкодеры – как уже понятно из названия, в этих устройствах определение положения происходит путем отслеживания изменений магнитного поля. Ключевым элементом таких энкодеров является датчик Холла.

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

Итак, наш датчик является абсолютным магнитным энкодером, позволяющим отследить изменение угла в пределах от 0 до 360 градусов. То есть нам доступен полный оборот! Разрешающая способность энкодера – 14 бит, что соответствует:

По моему опыту использования и подключения энкодера AS5048 этого обычно хватает с запасом 🙂

Для того, чтобы получить данные о положении доступны несколько вариантов:

  • Интерфейс SPI – для AS5048A.
  • Подключение энкодера по I2C – для AS5048B.
  • Выход PWM – этот вариант доступен для всех модификаций. Но для PWM разрешающая способность не 14, а 12 бит.

Именно на третьем способе мы и остановимся. Во-первых, это зачастую удобнее, не надо отправлять никаких команд для запроса данных, ШИМ-сигнал генерируется постоянно, и нам требуется только измерять его параметры. И, во-вторых, для считывания сигнала таким образом требуется меньше сигнальных линий, в некоторых случаях это оказывается ключевым аспектом при выборе интерфейса.

Принцип использования датчика максимально прост – постоянный магнит (идет в комплекте с платой энкодера) закрепляется на подвижном валу, а сам энкодер – на неподвижной части. При вращении происходит изменение магнитного поля, которое фиксируется датчиками Холла и впоследствии преобразуется в электрический сигнал. А с этим сигналом мы уже можем работать.

Минус использования PWM-выхода заключается в том, что функция установки нулевого положения датчика в этом случае недоступна. Идея тут в том, что при установке платы энкодера и магнита их положение друг относительно друга будет, в общем-то, случайным. Из-за этого нулевое положение датчика будет всегда разным, что обычно недопустимо. И поэтому в AS5048 добавлена возможность установить нулевое положение специальной командой, отправляемой по SPI или I2C.

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

С этим разобрались, переходим к формату выходных данных, точнее к механизму, который позволит нам из ШИМ-сигнала получить положение в пространстве. Выходной сигнал выглядит так:

Возьмем за основу наш пример из статьи про режим таймера Input Capture и будем измерять период сигнала и длительность импульса. Кстати по даташиту частота PWM равна 1 КГц, то есть период – 1 мс. На практике, период оказывается несколько другим, по моим наблюдениям, может быть отклонение до 10%. В связи с этим измерение периода позволит нам значительно повысить точность (относительно случая, если бы мы просто приняли его равным 1 мс).

Алгоритм действия будет таким:

1). Измеряем период и длительность импульса ШИМ-сигнала, получаем значения в микросекундах.

2). Пересчитаем длительность в отсчеты энкодера (clocks на картинке выше):

Здесь 4119 отсчетов – это весь период – 16 + 4095 + 8.

3). Из формы выходного сигнала видим, что в случае, если не возникло никакой ошибки длительность импульса составит минимум 16 отсчетов. Это число получается из длительности поля Init (12 отсчетов) и поля Error (4). Максимальная же длительность импульса равна разности между длительностью всего периода и поля Exit, что равно 4119 – 8 = 4111 отсчетов.

4). Если значение длительности удовлетворяет требованиям из пункта 3, то есть лежит в промежутке от 16 до 4111, то определяем из него текущую ширину поля Data в отсчетах:

5). И, наконец, ничего нам не мешает рассчитать значение угла:

Давайте реализуем все эти шаги в программе и для начала определим константы:

Дополняем код прерывания таймера и все готово!

И в завершение статьи несколько осциллограмм с выхода энкодера и соответствующие им результаты работы нашей программы (значения здесь в отсчетах таймера, в нашем примере один отсчет – 1 мкс):

На этом заканчиваем сегодняшний обзор, всем большое спасибо за внимание, надеюсь материал окажется вам полезен!

Использование датчика тока ACS712. Часть 1 — Теория

Allegro ACS712

Измерение и контроль протекающего тока являются принципиальным требованием для широкого круга приложений, включая схемы защиты от перегрузки по току, зарядные устройства, импульсные источники питания, программируемые источники тока и пр. Один из простейших методов измерения тока –использование резистора с малым сопротивлением, – шунта между нагрузкой и общим проводом, падение напряжения на котором пропорционально протекающему току. Несмотря на то, что данный метод очень прост в реализации, точность измерений оставляет желать лучшего, т.к. сопротивление шунта зависит от температуры, которая не является постоянной. Кроме того, такой метод не позволяет организовать гальваническую развязку между нагрузкой и измерителем тока, что очень важно в приложениях, где нагрузка питается высоким напряжением.

Основные недостатки измерения тока с помощью резистивного шунта:

  • нагрузка не имеет прямой связи с «землей»;
  • нелинейность измерений, обусловленная температурным дрейфом сопротивления резистора;
  • отсутствие гальванической развязки между нагрузкой и схемой измерения.

В статье мы рассмотрим экономичный и прецизионный интегральный датчик тока Allegro ACS712, принцип его работы, основанный на эффекте Холла, характеристики и способ подключения к микроконтроллеру для измерения постоянного тока. Статья разделена на две части: первая посвящена устройству и характеристикам датчика, вторая – интерфейсу с микроконтроллером и работе с датчиком.

Датчик тока ACS712 основан на принципе, открытом в 1879 году Эдвином Холлом (Edwin Hall), и названным его именем. Эффект Холла состоит в следующем: если проводник с током помещен в магнитное поле, то на его краях возникает ЭДС, направленная перпендикулярно, как к направлению тока, так и к направлению магнитного поля. Эффект иллюстрируется Рисунком 2. Через тонкую пластину полупроводникового материала, называемую элементом Холла, протекает ток I. При наличии магнитного поля на движущиеся носители заряда (электроны) действует сила Лоренца, искривляющая траекторию движения электронов, что приводит к перераспределению объемных зарядов в элементе Холла. Вследствие этого на краях пластины, параллельных направлению протекания тока, возникает ЭДС, называемая ЭДС Холла. Эта ЭДС пропорциональна векторному произведению индукции B на плотность тока I и имеет типовое значение порядка нескольких микровольт.

Микросхема ACS712 выпускается в миниатюрном 8-выводном корпусе SOIC для поверхностного монтажа (Рисунок 3). Она состоит из прецизионного линейного датчика Холла с малым напряжением смещения и медного проводника, проходящего у поверхности чипа и выполняющего роль сигнального пути для тока (Рисунок 4). Протекающий через этот проводник ток, создает магнитное поле, воспринимаемое встроенным в кристалл элементом Холла. Сила магнитного поля линейно зависит от проходящего тока. Встроенный формирователь сигнала фильтрует создаваемое чувствительным элементом напряжение и усиливает его до уровня, который может быть измерен с помощью АЦП микроконтроллера.

На Рисунке 5 показано расположение выводов ACS712 и типовая схема его включения. Выводы 1, 2 и 3,4 образуют проводящий путь для измеряемого тока с внутренним сопротивлением порядка 1.2 мОм, что определяет очень малые потери мощности. Его толщина выбрана такой, чтобы прибор выдерживал силу тока в пять раз превышающую максимально допустимое значение. Контакты силового проводника электрически изолированы от выводов датчика (выводы 5 – 8). Расчетная прочность изоляции составляет 2.1 кВ с.к.з.

В низкочастотных приложениях часто требуется включить на выходе устройства простой RC фильтр, чтобы улучшить отношение сигнал-шум. ACS712 содержит внутренний резистор RF, соединяющий выход встроенного усилителя сигнала со входом выходной буферной схемы (см. Рисунок 6). Один из выводов резистора доступен на выводе 6 микросхемы, к которому подключается внешний конденсатор CF. Следует отметить, что использование конденсатора фильтра приводит к увеличению времени нарастания выходного сигнала датчика и, следовательно, ограничивает полосу пропускания входного сигнала. Максимальная полоса пропускания составляет 80 кГц при емкости фильтрующего конденсатора равной нулю. С ростом емкости CF полоса пропускания уменьшается. Для снижения уровеня шума при номинальных условиях рекомендуется устанавливать конденсатор CF емкостью 1 нФ.

Чувствительность и выходное напряжение ACS712

Выходное напряжение датчика пропорционально току, протекающему через проводящий путь (от выводов 1 и 2 к выводам 3 и 4). Выпускается три варианта токового датчика для разных диапазонов измерения:

  • ±5 А (ACS712-05B),
  • ±20 А (ACS712-20B),
  • ±30 А (ACS712-30A)

Соответствующие уровни чувствительности составляют 185 мВ/А, 100 мА/В и 66 мВ/A. При нулевом токе, протекающем через датчик, выходное напряжение равно половине напряжения питания (Vcc/2). Необходимо заметить, что выходное напряжение при нулевом токе и чувствительность ACS712 пропорциональны напряжению питания. Это особенно полезно при использовании датчика совместно с АЦП.

Точность любого АЦП зависит от стабильности источника опорного напряжения. В большинстве схем на микроконтроллерах в качестве опорного используется напряжение питания. Поэтому при нестабильном напряжении питания измерения не могут быть точными. Однако если опорным напряжением АЦП сделать напряжение питания датчика ACS712, его выходное напряжение будет компенсировать любые ошибки аналого-цифрового преобразования, обусловленные флуктуациями опорного напряжения.

Рассмотрим эту ситуацию на конкретном примере. Допустим, что для опорного напряжения АЦП и питания датчика ACS712 используется общий источник Vcc = 5.0 В. При нулевом токе через датчик его выходное напряжение составит Vcc/2 = 2.5 В. Если АЦП 10-разрядный (0…1023), то преобразованному выходному напряжению датчика будет соответствовать число 512. Теперь предположим, что вследствие дрейфа напряжение источника питания установилось на уровне 4.5 В. Соответственно, на выходе датчика будет 4.5 В/2 = 2.25 В, но результатом преобразования, все равно, будет число 512, так как опорное напряжение АЦП тоже снизилось до 4.5 В. Точно также, и чувствительность датчика снизится в 4.5/5 = 0.9 раз, составив 166.5 мВ/А вместо 185 мВ/А. Как видите, любые колебания опорного напряжения не будут источником ошибок при аналого-цифровом преобразовании выходного напряжения датчика ACS712.

На Рисунке 7 представлены номинальные передаточные характеристики датчика ACS712-05B при напряжении питания 5.0 В. Дрейф выходного напряжения в рабочем диапазоне температур минимален благодаря инновационной технологии стабилизации.

Часть 2 — Подключение датчика к микроконтроллеру и работа с ним

Перевод: Vadim по заказу РадиоЛоцман

Собираем переносной магнитометр

Перевод статьи с сайта обучающих материалов Instructables

Магнитометр, который иногда ещё называют гауссометром, измеряет силу магнитного поля [в данном случае магнитную индукцию / прим. перев.]. Это прибор, необходимый при измерении силы постоянных магнитов и электромагнитов, а также для установления формы поля нетривиальных комбинаций из магнитов. Он достаточно чувствительный для того, чтобы определить намагниченность металлических предметов. В случае, если зонд будет работать достаточно быстро, он сможет определять изменяющиеся во времени поля от моторов и трансформаторов.

В мобильных телефонах обычно есть трёхосевой магнитометр, однако он оптимизирован для слабого магнитного поля Земли силой в 1 Гаусс = 0,1 мТл [миллитесла] и насыщается в полях с индукцией в несколько мТл. Где именно в телефоне расположен этот датчик, обычно непонятно, и расположить его внутри узкого места типа разреза магнита часто невозможно. Более того, лучше вообще не подносить смартфон к сильным магнитам.

В данной статье я опишу, как сделать простейший переносной магнитометр из распространённых комплектующих: нам потребуются линейный датчик Холла, Arduino, дисплей и кнопка. Общая стоимость прибора не выходит за пределы €5, а измерять он будет индукцию от -100 до +100 мТл с погрешностью в 0,01 мТл – гораздо лучше, чем можно было ожидать. Для получения точных абсолютных показателей его понадобится откалибровать: я опишу, как это делается при помощи длинного самодельного соленоида.

Шаг 1: датчик Холла

Эффект Холла часто применяется для измерения магнитных полей. Когда электроны проходят через проводник, помещённый в магнитное поле, их относит в сторону, в результате чего в проводнике появляется поперечная разность потенциалов. Правильно выбрав материал и геометрию полупроводника, можно получить измеряемый сигнал, который затем можно будет усилить и выдать измерение одной компоненты магнитного поля.

Я использую SS49E, поскольку он дешёвый и доступный. Что стоит отметить из его документации:

  • Питание: 2.7 — 6.5 В, что прекрасно совместимо с 5 В для Arduino.
  • Нулевой сигнал: 2.25-2.75 В, примерно посередине между 0 и 5 В.
  • Чувствительность: 1.0-1.75 мВ/Гс, поэтому для получения точных результатов потребуется калибровка.
  • Выходное напряжение: 1,0 – 4,0 В (при работе от 5 В): диапазон покрывается АЦП Arduino.
  • Диапазон: минимум ± 650 Гс, обычно +/1 1000 Гс.
  • Время отклика: 3 мкс, то есть можно проводить измерения с частотой в десятки кГц.
  • Рабочий ток: 6-10 мА, достаточно немного для батарейки.
  • Температурная ошибка: 0,1% на градус Цельсия. Вроде немного, однако отклонение на 0,1% даёт ошибку в 3 мТл.

Датчик компактный, 4х3х2 мм, и измеряет компоненту магнитного поля, перпендикулярную его лицевой стороне. Он выдаёт положительное значение для полей, идущих от задней части к передней – к примеру, когда он стоит лицом к южному полюсу магнита. У датчика есть три контакта, +5 В, 0 В и выход – слева направо, если смотреть с лица.

Шаг 2: Требуемые материалы

  • Линейный датчик Холла SS49E. €1 за 10 штук.
  • Arduino Uno с доской для прототипирования или Arduino Nano без штырьков для портативного варианта.
  • Монохромный OLED дисплей SSD1306 0.96” с интерфейсом I2C.
  • Кнопка.

Для зонда:

  • Шариковая ручка или другая прочная трубка.
  • 3 тонких провода чуть длиннее трубки.
  • 12 см термоусадки диаметром 1,5 мм.

Для портативной версии:

  • Большая коробка Tic-Tac (18x46x83) или нечто похожее.
  • Контакты для батарейки на 9 В.
  • Выключатель.

Шаг 3: Первая версия – с использованием доски для прототипирования

Сначала всегда собирайте прототип, чтобы проверить работу всех компонентов и софта! Подключение видно на картинке: датчик Холла соединяется с контактами Arduino +5V, GND, A1 (слева направо). Дисплей соединяется с GND, +5V, A5, A4 (слева направо). Кнопка при нажатии должна замыкать землю и A0.

Код написан в Arduino IDE v. 1.8.10. Требуется установка библиотек Adafruit_SSD1306 и Adafruit_GFX.

Если всё сделано правильно, то дисплей должен выдавать значения DC и AC.

Шаг 4: Немного о коде

Если вам неинтересен код, эту часть можно пропустить.

Ключевая особенность кода состоит в том, что магнитное поле измеряется 2000 раз подряд. На это уходит 0,2 – 0,3 сек. Отслеживая сумму и квадрат суммы измерений, можно вычислять среднее и стандартное отклонения, которые выдаются как DC и AC. Усредняя по большому количеству измерений мы увеличиваем точность, теоретически на √2000 ≈ 45. Получается, что используя 10-битное АЦП, мы получаем точность 15-битного АЦП! И это имеет значение: 1 шаг АЦП – 4 мВ, то есть,

0,3 мТл. Благодаря усреднению, мы уменьшаем ошибку от 0,3 мТл до 0,01 мТл.

В качестве бонуса мы получаем стандартное отклонение, определяя таким образом изменяющееся поле. Поле, колеблющееся с частотой 50 Гц проходит порядка 10 циклов за время измерения, поэтому можно измерить величину AC.

У меня после компиляции получилась следующая статистика: Sketch uses 16852 bytes (54%) of program storage space. Maximum is 30720 bytes. Global variables use 352 bytes (17%) of dynamic memory, leaving 1696 bytes for local variables. Maximum is 2048 bytes.

Большую часть места занимают библиотеки Adafruit, однако ещё полно места для добавления функциональности.

Шаг 5: Готовим зонд

Зонд лучше всего закреплять на конце узкой трубки: так его просто будет помещать и удерживать в узких местах. Подойдёт любая трубка из немагнитного материала. Мне идеально подошла старая шариковая ручка.

Подготовьте три тонких гибких провода чуть длиннее трубки. В моём кабеле логики в цветах проводов нет (оранжевый +5 В, красный 0 В, серый – сигнал), просто так мне их проще запомнить.

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

Шаг 6: Собираем переносной прибор

Батарейка на 9В, OLED-экран и Arduino Nano с комфортом умещаются внутри большой коробки Tic-Tac. Её преимущество в прозрачности – экран легко читается, даже находясь внутри. Все фиксированные компоненты (зонд, выключатель и кнопка) ставятся на крышку, чтобы всё можно было вынимать из коробки для замены батареи или обновления кода.

Я никогда не любил батарейки на 9В – у них высокая цена и малая ёмкость. Но в моём супермаркете внезапно стали продавать их перезаряжаемую версию NiMH по €1, и я обнаружил, что их легко зарядить, если подать 11 В через резистор на 100 Ом и оставить на ночь. Я заказал себе дешёвые разъёмы для батареек, но мне их так и не прислали, поэтому я разобрал старую батарейку на 9 В, чтобы сделать из неё коннектор. Плюс батарейки на 9В в её компактности, и в том, что на ней хорошо работает Arduino при подключении её к Vin. На +5 В будет регулируемое напряжение в 5 В, которое понадобится для OLED и датчика Холла.

Датчик Холла, экран и кнопка подсоединяются так же, как было на прототипе. Добавляется только кнопка выключения, между батарейкой и Arduino.

Шаг 7: Калибровка

Калибровочная константа в коде соответствует числу, прописанному в документации (1,4 мВ/Гс), однако в документации разрешён диапазон этого значения (1.0-1.75 мВ/Гс). Чтобы получать точные результаты, нужно откалибровать зонд.

Самый простой способ получить магнитное поле хорошо определённой силы – использовать соленоид. Магнитная индукция поля соленоида равняется B = μ * n * I. Магнитная постоянная (или магнитная проницаемость вакуума) – это природная константа: μ = 1,2566 x 10 -6 Тл/м/А. Поле однородно и зависит только от плотности намотки n и тока I, которые можно измерить с погрешностью около 1%. Формула работает для соленоида бесконечной длины, однако служит очень хорошим приближением для поля в его центре, если соотношение его длины к диаметру превышает 10.

Чтобы собрать подходящий соленоид, возьмите полую цилиндрическую трубу, длина которой в 10 раз больше диаметра, и сделайте намотку из изолированного провода. Я использовал ПВХ-трубку с внешним диаметром 23 мм и сделал 566 витков, протянувшихся на 20,2 см, что даёт нам n = 28/см = 2800 / м. Длина провода 42 м, сопротивление – 10 Ом.

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

Перед калибровкой я получил 6,04 мТл/A, хотя по теории должно было быть 3,50 мТл/A. Поэтому я умножил константу калибровки в 18-й строчке кода на 0,58. Готово – магнитометр откалиброван!