51

Энкодер на базе HEDR и STM32

Всем привет!

В данной статье я хочу Вам рассказать про датчик HEDR(от компании avago technologies) - это двухканальный инкрементальный оптический датчик, предназначен для измерения пройденного пути, линейной скорости, угловой скорости и направлении вращения вала.
С помощью данного датчика будет реализован энкодер на базе микроконтроллера STM32, который будет производить вычисление пройденного пути.

В данной статье будет рассмотрено:

  • Принцип работы датчика HEDR-5420-ES214;

  • Схема подключения к микроконтроллеру STM32;

  • Программная реализация (расчет пройденного пути и вывод информации на дисплей).

Технические характеристики датчика HEDR-5420-ES214

Документация на датчик

  • Напряжение питания [ 4.5 - 5.5В ];

  • Тип выхода [ квадратурный ];

  • Диаметр вала [ 5 мм ];

  • Разрешение [ 200 отсчетов на оборот ];

  • Рабочая температура [ от -10°C до +85°C ].

Принцип работы датчика HEDR-5420-ES214

Устройство состоит из трех основных компонентов:

  • Источник света (светодиод, формирующий поток света);

  • Оптическая система (линза, обеспечивает фокусировку и отражение света);

  • Фотодетектор.

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

Эти изменения интенсивности света преобразуются в внутренние сигналы А и В, которые проходят через компараторы в составе обработки сигналов, на выходе формируются два цифровых прямоугольных сигнала - канал А и В, находящиеся в квадратурной фазе на 90°, что позволяет микроконтроллеру определять направление вращения вала, к примеру:

  • если канал А опережает канал B - вращение происходит в одну сторону;

  • если канал B опережает канал А - вращение происходит в противоположную сторону.

Для своей задачи применяется следующая последовательность, если канал А опережает канал B - движение энкодера считается положительным, если на оборот, то движение будет отрицательным.

Осциллограмма данных полученных с датчика HEDR-5420-ES214

Осциллограмма данных полученных с датчика HEDR-5420-ES214

Схема подключения к микроконтроллеру STM32

Схема подключения HEDR и дисплея к микроконтроллеру STM32F030CCT6

Схема подключения HEDR и дисплея к микроконтроллеру STM32F030CCT6

 Макет STM32F030CCTx и HEDR

Макет STM32F030CCTx и HEDR

В данной схеме используются преобразователь напряжения DA1 (+12V +5V) и стабилизатор напряжения DA2, дисплей подключается к выводам МК 21_SCL_I2C2 и 22_SDA_I2C2, датчик HEDR подключается к выводам МК 29_CH.A и 30_CH.B, данные сигналы сначала проходят через делители, R17-R18-[CH.A] и R15-R16-[CH.B], так как датчик работает от +5V, сигналы соответственно тоже у него +5V, я всегда стараюсь дополнительно защитить МК, после делителя амплитуда сигналов снизится до +3.3V, копипастить информацию по описанию узлов преобразователя, стабилизатора, узла обвязки напряжения питания и резонатора для МК не особо хочется, поэтому кому интересно можно почитать статью [Модуль обработки и коммутации данных, с внешними управляющими устройствами по RS-485 на STM32]
Настройка микроконтроллера STM32F030CCTx в CubeIDE

Настройка RCC и SYS (в RCC выбираю Crystal/Ceramic Resonator, так как у меня внешний кварц на 8 МГц)

Настройка дисплея

Взаимодействие дисплея с МК будет через I2C2

Настройка выводов узла подключения датчика HEDR

  • TIM1_CH1 (к данному выводу будет подключаться сигнал CH.A);

  • TIM1_CH2 (к данному выводу будет подключаться сигнал CH.B).

Таймер используется в режиме Encoder mode - это специальный аппаратный режим, который позволяет микроконтроллеру автоматически подсчитывать импульсы от инкрементального датчика и определять направление вращения, данная конфигурация освобождает МК от необходимости программно обрабатывать прерывания по каждому импульсу.

Encoder Mode TI1 and TI2 данный параметр указывает, что используется оба канала датчика (A и B), это дает разрешение X4 - т.е. счетчик будет увеличиваться на 4 шага за один полный оборот.

Описание режимов

TI1 - подсчет ведется по фронту одного канала А, направление определяется по уровню В, разрешение 1.8 градусов;

TI2 - аналогично логике TI1, но базируется на канале В;

TI1 and TI2 - подсчет ведется на каждом фронте обоих каналов (А+, А-, В+, В-), направление определяется автоматически, т.е. количеством импульсов на оборот 200, я получаю 800 шагов на оборот, разрешение будет 0.45 градусов.

Input Filter - включает цифровую фильтрацию входного сигнала, помогает убрать дребезг и шум, значения от 0 до 15, чем выше значение, тем надежнее фильтрация, но будет повышаться задержка.

Polarity (Rising Edge) - счетчик реагирует на восходящие фронты сигнала.

Настройка Clock

Программная реализация ведомого устройства

Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код — Исходный код для Encoder_HEDR_5420_STM32F030CCTx].

Модуль process_Encoder

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

  • Количество импульсов на оборот;

  • Пройденную дистанцию;

  • Отображение данных на дисплее.

#define ENCODER_MODE_X4 4

Данный параметр отражает режим подсчета импульсов, привожу формулу

Этот режим обеспечивает максимальную точность - 0.45 на один шаг.

#define WHEEL_DIAMETR_M 0.230f // 230 мм
#define WHEEL_RADIUS_M (WHEEL_DIAMETR_M / 2.0f)

Здесь я задаю геометрические размеры колеса, на валу которого установлен датчик%

Диаметр колеса 230 мм (0.230м);

Радиус вычисляется так:

#define STEPS_PER_REV (ENCODER_PPR * ENCODER_MODE_X4)

Максимальное количество шагов за один оборот

#define CIRCUMFERENCE_M (2.0f *M_PI * WHEEL_RADIUS_M)

Длина окружности колеса - это путь, который проходит колесо за один оборот

т.е. при моем радиусе 0.115, получится за один полный оборот 0.72 м.

Функция display_init() - инициализация дисплея

  • Инициализируется драйвер дисплея;

  • Выполняется заливка экрана черным цветом;

  • На дисплее на 2 секунды отображается стартовый экран с надписью ''ChipCraft";

  • После задержки экран очищается для дальнейшей работы.

библиотеку для работы с дисплеем я взял с [https://github.com/afiskon/stm32-ssd1306/tree/master]

Функция display_update()

Отвечает за визуализацию информации на дисплее:

  • Экран предварительно очищается с помощью ssd1306_Fill(Black);

  • В верхней части по центру отображается надпись «Encoder»;

  • Ниже последовательно выводятся:

    • количество импульсов;

    • дистанция;

  • Буфер графики передается на дисплей вызовом ssd1306_UpdateScreen()

Функция encoder_Handler()

Логика работы:

  • считывание текущего значения таймера;

  • определение разницы (delta) между текущим и предыдущим значениями;

  • накопление общего счетчика enocoder_position;

  • вызов функций для вычисления дистанции и обновление дисплея.

Функция get_distance_m() - вычисление пройденной дистанции

Переводит количество импульсов датчика в физическую длину пути в (метрах).

process_Encoder.c

#include "./Project/process_Encoder.h"
#include "./Project/shared.h"
#include "./Project/ssd1306.h"
#include "./Project/ssd1306_fonts.h"
#include "main.h"
#include <stdlib.h>//abs
#include <string.h>//memset
#include <stdio.h>
#include <stdint.h>
#include <math.h>

#define ENCODER_PPR 200 // импульсов на оборот
#define ENCODER_MODE_X4 4

#define WHEEL_DIAMETR_M 0.230f // 230 мм
#define WHEEL_RADIUS_M (WHEEL_DIAMETR_M / 2.0f)

#define STEPS_PER_REV (ENCODER_PPR * ENCODER_MODE_X4)
#define CIRCUMFERENCE_M (2.0f *M_PI * WHEEL_RADIUS_M)

uint16_t current_count= 0;
int16_t delta = 0;
float distance = 0.0f;
int32_t encoder_position = 0;

uint8_t ssd1306_buffer[SSD1306_BUFFER_SIZE];


void display_init(void) {
ssd1306_Init();

ssd1306_Fill(Black);
ssd1306_SetCursor(20, 25);
ssd1306_WriteString("ChipCraft", Font_11x18, White);
ssd1306_UpdateScreen();

HAL_Delay(2000);

ssd1306_Fill(Black);
ssd1306_UpdateScreen();
}

void encoder_Handler(void) {

static uint16_t last_count = 0;
current_count = __HAL_TIM_GET_COUNTER(&htim1);

delta = (int16_t)(current_count - last_count);
encoder_position += delta;

last_count = current_count;

get_distance_m();

display_update(encoder_position, distance);

}
void display_update(int32_t pulses, float distance) {

char buf[32];

ssd1306_Fill(Black);

ssd1306_SetCursor(25, 2);
ssd1306_WriteString("Encoder" ,Font_11x18, White);

sprintf(buf, "Pulses: %ld", pulses);
ssd1306_SetCursor(2, 22);
ssd1306_WriteString(buf, Font_7x10, White);

sprintf(buf, "Dist: %.2f m", distance);
ssd1306_SetCursor(2, 36);
ssd1306_WriteString(buf, Font_7x10, White);

ssd1306_UpdateScreen();
}

float get_distance_m(void){

distance = ((float) encoder_position / STEPS_PER_REV) * CIRCUMFERENCE_M;

return distance;
}

Модуль proj_main() - главный метод

  • Выполняется инициализация дисплея;

  • Запуск таймера;

  • Запуск функции encoder_Handler().

proj_main.c

#include "./Project/shared.h"
#include "./Project/proj_main.h"
#include "./Project/process_Encoder.h"
#include "./Project/process_Encoder.h"

void proj_main()
{
volatile const char *ch = ";V-F-BIN;ver: "VER_PROG(VER_a,VER_b,VER_c);(void)ch;//0x8008b00

display_init();

HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);

while (1){

//хэндлеры
encoder_Handler();

}//while (1)
}


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

Инженериум DIY

571 пост5.4K подписчика

Правила сообщества

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

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

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества