Колесо для измерения расстояний (курвиметр) на Arduino и инкрементальном энкодере


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

Внешний вид курвиметра

В данной статье мы рассмотрим создание электронного аналога курвиметра – цифрового колеса для измерения расстояний с точностью до миллиметра на основе платы Arduino и инкрементального энкодера.

Внешний вид электронного курвиметра на основе платы Arduino и инкрементальном энкодере

А на следующем видео показан принцип работы нашего электронного курвиметра.

Более подробно про подключение инкрементального энкодера к плате Arduino можно прочитать в этой статье.

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

  1. Плата Arduino Pro Mini (купить на AliExpress).
  2. Модуль USB To TTL (для программирования платы Arduino Pro Mini).
  3. Инкрементальный энкодер (с импульсом High на оборот).
  4. OLED дисплей 128х64 с интерфейсом SPI (купить на AliExpress).
  5. Модуль TP4056 (купить на AliExpress).
  6. Литий-полимерная батарея 700mAh.
  7. Кнопка.
  8. Переключатель SPST типа.

Принципы работы нашего проекта

Принцип работы нашего проекта будет основан на принципе работы инкрементального энкодера, который преобразует вращение своей оси в серию импульсов на своем выходе. Серии этих импульсов на двух выходах энкодера сдвинуты относительно друг друга по фазе на 90 градусов. Оценивая направление этого сдвига мы можем определить направление, в котором вращается ось энкодера.

Для сброса показаний счетчика оборотов колеса мы будем использовать кнопку. Управлять всеми процессами в нашем проекте будет плата Arduino Pro Mini – она будет обрабатывать импульсы от инкрементального энкодера и отображать измеренное значение на OLED дисплее, который будет подключаться к плате Arduino через интерфейс SPI.

Схема проекта

Схема цифрового колеса для измерения расстояний на основе платы Arduino представлена на следующем рисунке.

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

Кнопка подключена к контакту 3 платы Arduino – ее нажатия будут обрабатываться с помощью прерываний.

Выходные контакты инкрементального энкодера подключены к контактам 2 и 6 платы Arduino.

0.96” OLED дисплей подключен к контактам 8, 9, 10, 12 и 13 платы Arduino по протоколу SPI.

Объяснение программы для Arduino

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Хотя для обработки импульсов от инкрементального энкодера нам не нужно никаких библиотек, нам необходимы будут библиотеки для работы с OLED дисплеем. Для этого установим библиотеки Adafruit GFX и Adafruit SSD 1306. Запустим менеджер библиотек из меню Tools в Arduino IDE.

Запуск менеджера библиотек из меню Tools в Arduino IDE

Выполним поиск библиотек Adafruit GFX и Adafruit SSD1306 и установим их нажав на кнопку install.

Установка библиотек Adafruit GFX и Adafruit SSD1306 с помощью менеджера библиотек

Первым делом в программе подключим все используемые библиотеки.

Затем дадим используемым контактам осмысленные имена и создадим объект для работы с OLED дисплеем.

Далее мы объявим используемые в нашем проекте константы – это диаметр нашего колеса (70 мм) и число счетов (импульсов) на один оборот (counts per revolution, CPR) для каждой фазы нашего энкодера.

Из даташита на наш инкрементальный энкодер мы знаем, что каждая фаза передает 400 импульсов за один оборот и, поскольку каждый импульс имеет два перехода, мы получаем необходимое нам число 800 (400X2) – его мы и вводим в качестве CPR.

Также мы объявим переменную с именем factor – она будет определять пройденное за один счет (импульс) расстояние. В дальнейшем в программе мы будем умножать ее на число импульсов.

Также объявим ряд дополнительных переменных, которые нам потребуются в программе.

В функции void setup() мы зададим режимы работы используемых контактов (на ввод данных с использованием подтягивающих резисторов), настроим обработку прерываний, инициализируем OLED дисплей и выведем нулевое значение измеренного расстояния на экран дисплея.

В функции void loop() мы будем выполнять сравнительно мало действий поскольку основной функционал нашей программы будет реализован в функциях обработки прерываний, а также в функции updateDisplay(). Мы будем использовать переменную i в качестве флага, который будем устанавливать в 1 всегда при формировании импульса инкрементальным энкодером или при сбросе переменной счетчика. Мы будем вызывать функцию updateDisplay() только когда переменная флага равна 1.

Также мы будем использовать простой код с использованием переменной lastData и функции millis() для сброса счетчика обратно в 0 в случае если нет никакого ввода в течение последних 10 секунд.

Поскольку мы подключили одну фазу инкрементального энкодера к контакту 2 платы Arduino, функция ISR1 будет выполняться всегда при переходе уровня на этом контакте. Из принципа работы инкрементального энкодера мы знаем, что если фазы не равны, то ось энкодера вращается против часовой стрелки, в этом случае мы будем уменьшать значение счетчика, а если фазы равны мы будем увеличивать значение счетчика.

Заметьте, что вместо использования простой функции digitalRead() мы для считывания состояния контакта использовали команду bool(PIND&(1<<6)). Это команда используется для считывания состояния всего порта D, но для целей оценки состояния 6-го контакта используется только 6-й бит считанного значения порта.

Кнопка подключена к контакту 3 и ее нажатие приводит к вызову второй функции обработки прерывания – ISR2. Эта функция просто сбрасывает значение переменной счетчика до нуля.

Функция updateDisplay() используется для очистки экрана OLED дисплея и отображения на нем нового значения измеренного расстояния. Эта функция производит обновление каждые 500 мс чтобы беречь ресурсы процессора и быть уверенным в том, что мы не пропустим какой либо импульс от энкодера. Также это предотвращает мерцание экрана.

Функция displayCenter(), как это следует из ее названия, выравнивает текст на экране дисплея горизонтально по центру.

Сборка конструкции проекта

Для нашего проекта измерительного колеса были разработаны STL файлы, которые можно использовать для печати корпуса проекта на 3D принтере. Скачать их можно по ссылке ниже. На следующем рисунке представлено расположение электронных компонентов проекта внутри данного корпуса.

Расположение компонентов электронного курвиметра внутри корпуса

Колесо прикрепляется к оси инкрементального энкодера.

Внешний вид собранной конструкции проекта

После сборки всей конструкции проекта можно приступать к тестированию его работы.

Исходный код программы (скетча)

Источник статьи

(Проголосуй первым!)
Загрузка...
159 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *