Top.Mail.Ru

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

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

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

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

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

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

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

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

Подключение энкодера AS5048.

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

\frac{360\degree}{16384} = 0,02197\degree

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

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

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

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

Магниты.

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

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

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

ШИМ-сигнал энкодера.

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

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

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

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

t_{clocks} = 4119 * \frac{t}{T}

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

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

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

t_{data\medspace clocks} = t_{clocks} - 16

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

\alpha = \frac{t_{data\medspace clocks}}{4095} * 360\degree

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

#define PERIOD_CLOCKS                                                   4119
#define ANGLE_MAX                                                       360
#define PULSE_CLOCKS_MIN                                                16
#define PULSE_CLOCKS_MAX                                                4111
#define DATA_CLOCKS_MAX                                                 4095

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

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM2)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			period = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
			pulseWidth = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);

			TIM2->CNT = 0;

			if (pulseWidth < period)
			{
				uint16_t pulseWidthClocks = PERIOD_CLOCKS * pulseWidth / period;

				if ((pulseWidthClocks >= PULSE_CLOCKS_MIN) && (pulseWidthClocks <= PULSE_CLOCKS_MAX))
				{
					uint16_t dataClocks = pulseWidthClocks - PULSE_CLOCKS_MIN;
					angle = ((float)dataClocks) / DATA_CLOCKS_MAX * ANGLE_MAX;
				}
			}
		}
	}
}

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

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

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

Ссылка на проект - MT_Encoder_AS5048.

Подписаться
Уведомить о
guest

7 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
marshallab
marshallab
3 лет назад

Спасибо. Эта статья наталкнула на идею, которая кажется хорошей.

Дмитрий
Дмитрий
1 год назад

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

Дмитрий
Дмитрий
Ответ на комментарий  Aveal
1 год назад

Спасибо!

Юрий
Юрий
1 год назад

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

7
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x