Электронный курвиметр

от автора

Идея создания электронного курвиметра возникла в процессе разработки инструментальной выверки вращающейся печи. Для точного измерения диаметров опорных роликов и определения их износа необходимо было создать специальный прибор.

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

Виды износа опорных роликов

Виды износа опорных роликов

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

Энкодер — представляет собой датчик угла поворота, который может быть нескольких типов: инкрементальный, абсолютный, оптический, магнитный и механический. Для своего проекта я выбрал 14-битный магнитный энкодер MT6701.

Энкодер MT6701

Энкодер MT6701

Контролёр, ответственный за обработку данных, выбрал ESP32, который уже был в наличии, и запрограммировал его на языке Micropython, в котором я немного разбираюсь. Затем подключил дисплей и энкодер, используя протокол I2C.

Чтобы точно определить диаметр измеряемого объекта, будь то ролик, колесо или что-то другое, необходимо знать, где начинается и заканчивается его оборот. Для этого нужен триггер — устройство, которое будет указывать на начало и конец вращения.

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

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

Далее проводим дополнительно несколько измерений с целью усреднения результата. В моём случае получилось добиться точности в десятые миллиметра.

Теоретическая точность получилось:

·       14bit = 2^14 = 16384

·       при, D = 110 мм, L= π × D = 345,575 мм

·       Расчетная теоретическая точность за импульс = D/16384 = 345,575/16384 = 0,02 мм.

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

В качестве источника питания применил аккумулятор 18650 + модуль заряда.

Схему подключения приводить не буду.

Код  выглядит примерно так (это один из вариантов, отлаженный код в контроллере):

import machine from time import sleep_ms import math from machine import Pin, ADC from i2c_lcd1602 import I2C_LCD1602  i2c = machine.I2C(1,sda=machine.Pin(6), scl=machine.Pin(7), freq=400000) LCD = I2C_LCD1602(i2c)  napr = 0  # Направление вращения 0 против часовой стрелки 1 по часовой diameter = 110       # Диаметр колеса, мм alfa_sum = 0 dtt = []             # Предыдущее значение cz = []              # Счетчик оборотов по часовой стрелки ct = []              # Счетчик оборотов по часовой стрелки data_0 = [] booll=0 booll_per=[] LCD.puts("Hello") LCD.puts("kurva ", 2, 1)             sleep_ms(1000)  response=i2c.readfrom_mem(0x06, 3, 2)      # Подключаемся к датчику potentiometr = machine.ADC(28)                # Подключаем аналоговый Pin (0) potentiometr_value = potentiometr.read_u16()    str_return_data = str(response.hex())      # Подключаемся к датчику feedback_data = int(str_return_data, 16)   # Преобжаем в 10 ричной код x = feedback_data/4                       # Убираем лишние цифры  for dat in x:     data = dat     if 0 <= data <= 4096:         dt = 0     if 4096 <= data <= 8192:         dt = 1     if 8192 <= data <= 12288:         dt = 2     if 12288 <= data <= 16384:         dt = 3     dtt.append(dt)                             # Предыдущее значение записываем в массив     data_0.append(data)     if len(dtt)>=3:                             # Если массив меньше 2-х начинаем работу         dt_t = int(dtt.pop(-3))                # Предыдущее значение извлекаем из массива         if dtt[0] == 0 and dtt[1] == 3:          # Ищем переход по часовой стрелки             cz.append(1)                      # Если есть переход записываем в массив         if dtt[0] == 3 and dtt[1] == 0:          # Ищем переход по часовой стрелки             ct.append(3)                      # Если есть переход записываем в массив         data_1 = int(data_0.pop(-2))                # Предыдущее значение извлекаем из массива                  if data != data_1:             alfa = float(data-data_1)             alfa_sum += alfa                          dz = int(len(cz)*16384)             dt = int(len(ct)*16384)             alfa_real = round((360/(16384)*(alfa_sum+dt-dz)),2)             l_max = round(((math.pi*diameter)/360)*alfa_real,3)             d_nom = round(l_max/math.pi,1)             LCD.puts("%s: %s"% (round(alfa_real,1), round(l_max,1)))         if potentiometr_value >8000:             booll=1         if potentiometr_value <8000:             booll=0         booll_per.append(booll)         if len(booll_per)>2:             dt_booll_per = int(booll_per.pop(-2))                 if booll == 0 and int(dt_booll_per) == 1:                 alfa_sum = int(0)                 cz = [0,0]                               ct = [0,0]                 LCD.clear()                 LCD.puts(0.000)                 LCD.puts("D=%s - mm" % abs(d_nom), 0, 1)      sleep_ms(50)

Дальше последовала разработка и печать корпуса.

Готовый проект выглядит так.

Всем спасибо на оригинальность не претендую. В проекте много чего можно изменить (доработать). Например переписать код на С провести оптимизацию.

P.S. проект по прямому назначению так и не пригодился.


ссылка на оригинал статьи https://habr.com/ru/articles/921170/


Комментарии

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

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