Маленький цифровой курвиметр - Своими руками
Своими руками

Маленький цифровой курвиметр

>


Приветы самоделкиным!
Представляю вашему вниманию небольшой электронный приборчик для измерения любой длины: прямой или криволинейной. Данные отображаются на небольшом встроенном дисплее в метрической и дюймовой системе одновременно. На нашем сайте я нашел подобное устройство, но оно большого размера и применимо для больших расстояний. К тому же принцип действия приборов разительно отличается. Если в той статье предлагается устройство на основе обычной связки геркон – магнит, то тут уже используется поворотный энкодер. Предлагаемый же прибор можно назвать настольным, так как измерения отображаются в миллиметрах.
Конечно можно просто купить готовый, механический, например такой, но тогда пропадет весь азарт изобретательства!
НЕОБХОДИМЫЕ МАТЕРИАЛЫ И ИНСТРУМЕНТЫ:
Микроконтроллер ATtiny1614 х 1 шт.
Модуль поворотного энкодера KY-040 х 1 шт.
Триггер Шмитта NC7S14M5X х 2 шт.
Модуль дисплея OLED 128X64 I2C х 1 шт.
Кнопка PTS645 х 1 шт.
Аккумулятор 3,7v х 1 шт.
– Сопротивление 10 кОм 0805 х 2 шт.
– Конденсатор 22 нФ 0805 х 2 шт.
– Конденсатор 0,1 мкФ 0805 х 1 шт.
Arduino IDE
– Паяльник
– 3D-принтер
Посмотреть работу прибора и оценить его габариты и возможности можно проcмотрев это видео:


СХЕМА:
Схема основана на микроконтроллере ATtiny1614. Эта микросхема очень экономична в спящем режиме. Так же основным элементом является поворотный 360 градусов энкодер. Но у него имеется недостаток. Его работа основана на механическом взаимодействии контактов, что может повлиять на правильность считывания данных. Что бы исключить помехи, в схему был добавлен RC-фильтр и парочка триггеров Шмитта. В конечном результате на контроллер поступает чистый сигнал. В качестве источника питания используется литий-полимерная аккумуляторная батарея 3.7v.

Маленький цифровой курвиметр
КОРПУС:
Корпус прибора распечатан на 3D-принтере. В конце статьи будет предоставлена возможность скачать оригинальные файлы проекта. При определенных навыках можно придумать свой корпус.

ПЕЧАТНАЯ ПЛАТА:
Для минимизации электронной части, все возможные детали были выбраны по технологии SMD. В конце статьи так же будут представлена возможность скачать оригинальные файлы.

Маленький цифровой курвиметр
СБОРКА ПРИБОРА:
Первым делом нужно приготовить все для сборки. Проверить наличие радио-компонентов, вытравить самому или заказать печатную плату, распечатать или так же заказать элементы корпуса.
На печатную плату нужно установить микроконтроллер, триггеры, конденсаторы и сопротивления. При монтаже элементов SMD лучше воспользоваться паяльной пастой и термофеном. После мелкого монтажа установите разъем для аккумуляторной батареи.

Маленький цифровой курвиметр
Дальше нужно установить разъем для дисплея. На плате дисплея устанавливается встречный разъем. Какие куда (папа – мама) не имеет значения. Так же устанавливается 3-х пиновый разъем для подключения программатора и поворотный энкодер.

Маленький цифровой курвиметр
К кнопке нужно припаять два проводка. Кнопку можно установить на место в корпусе. Концы проводов от кнопки впаяйте в отведенные места печатной платы. Вставьте батарею между печатной платой и платой энкодера. При правильной установке разъемов (папа – мама) батарея должна войти между платами свободно.

Маленький цифровой курвиметрМаленький цифровой курвиметр
Теперь можно собранную электронную часть установить в корпус. Для программирования контроллера можно использовать программатор на основе Arduino NANO. Во время прошивки контроллера лучше отключить встроенный аккумулятор. Питание будет подаваться по шине UPDI.

Процесс прошивки выглядит так:
– Подключаете плату к Arduino Nano
– Подключите Arduino к компьютеру, в разделе Arduino IDE -> инструменты -> нужно выбрать плату с процессором ATtiny1614, установить тактовую частоту 8 МГц и порт, куда подключили программатор.
– Проверьте установки программатора в установках. Нужно jtag2updi (megaTinyCore).
– Загрузите скачанный скетч в микроконтроллер.

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

Маленький цифровой курвиметр
Сборка почти закончена. Теперь нужно установить ролик (колесико) на вал энкодера. Подойдет вот такое, от сервопривода.

Маленький цифровой курвиметрМаленький цифровой курвиметр
Есть два варианта установки ролика.
Первый – просверлить подходящее отверстие в центре ролика и насадить ролик на вал энкодера.
Второй – распечатать на 3D-принтере свое колесо. Снять резинку с готового ролика и надеть новое, напечатанное.

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

– Скачать схему и печатную плату в разных форматах. Схема в формате .PNG, печатная плата в формате .JPG. Архив с файлами для программ EAGLE
и KiCad скачать можно отсюда

Прошивка контроллера в формате .ino или скопировать текст кода из спойлера:
Маленький цифровой курвиметр Показать / Скрыть текст
/**************************************************************************
Measuring Wheel

Based on “DIY Simple Measuring Wheel with Rotary Encoder” by Mirko Pavleski

2021-05-03 John Bradnam (jbrad2089@gmail.com)
Create program for ATtiny1614

————————————————————————–
Arduino IDE:
————————————————————————–
BOARD: ATtiny1614/1604/814/804/414/404/214/204
Chip: ATtiny1614
Clock Speed: 1MHz
Programmer: jtag2updi (megaTinyCore)

ATTiny1614 Pins mapped to Ardunio Pins

+——–+
VCC + 1 14 + GND
(SS) 0 PA4 + 2 13 + PA3 10 (SCK)
1 PA5 + 3 12 + PA2 9 (MISO)
(DAC) 2 PA6 + 4 11 + PA1 8 (MOSI)
3 PA7 + 5 10 + PA0 11 (UPDI)
(RXD) 4 PB3 + 6 9 + PB0 7 (SCL)
(TXD) 5 PB2 + 7 8 + PB1 6 (SDA)
+——–+

PA0 to PA7 can be analog or digital
PWM on D0, D1, D6, D7, D10

**************************************************************************/

#include “Tiny8kOLED.h”
#include

#define BUTTON 10 //PA3
#define ENC_B 1 //PA5
#define ENC_A 5 //PB2

//Uncomment next line to clear out EEPROM and reset all high scores
//#define RESET_EEPROM

#define SLEEP_TIMEOUT 10000 //Amount of time no switch is pressed before going to sleep
uint32_t sleepTimeout = 0; //Used to timeout mode switch function to sleep function

bool volatile ignoreNextPress = false;
int8_t volatile rotaryDirection = 0;
bool volatile lastRotA = false;

#define MAX_ROTARY_COUNT 25374 //999 inches
long volatile ruler = 0; //ruler measurement
bool volatile rulerChanged = false;

#define PI 3.14
#define WHEEL_RADIUS 3.00 //in cm
#define RESOLUTION 20 //Steps per revolution

//——————————————————————–
//Program Setup
void setup()
{
pinMode(BUTTON, INPUT_PULLUP);
pinMode(ENC_A, INPUT);
pinMode(ENC_B, INPUT);

//Attach interrupt handlers for handling rotary encoder
attachRotaryPinChangeInterrupt();

//Attach interrupt handler to wake up from sleep mode
attachInterrupt(digitalPinToInterrupt(BUTTON),switchInterrupt,CHANGE);

oled.begin();
rulerChanged = true; //force display update
sleepTimeout = millis() + SLEEP_TIMEOUT;
}

//——————————————————————–
//Handle pin change interrupt when button is pressed
void switchInterrupt()
{
}

//——————————————————–
// Attach the pin change interrupts for the rotary encoder
void attachRotaryPinChangeInterrupt()
{
attachInterrupt(ENC_A, rotaryInterrupt, CHANGE);
}

//——————————————————–
// Detach the pin change interrupts for the rotary encoder
void detachRotaryPinChangeInterrupt()
{
detachInterrupt(ENC_A);
}

//———————————————————————
// Interrupt Handler: Rotary encoder has moved
void rotaryInterrupt()
{
if (!digitalRead(ENC_A) && lastRotA)
{
if (digitalRead(ENC_B))
{
ruler = min(ruler + 1, MAX_ROTARY_COUNT – 1);
}
else
{
ruler = max(ruler – 1, 0);
}
rulerChanged = true;
}
lastRotA = digitalRead(ENC_A);
}

//——————————————————————–
//Program Loop
void loop()
{
if (millis() >= sleepTimeout)
{
system_sleep();
}
else if (digitalRead(BUTTON) == LOW)
{
delay(10); //Debounce
if (digitalRead(BUTTON) == LOW)
{
//Zero ruler
ruler = 0;
displayRuler();
//Wait for button release
while (digitalRead(BUTTON) == LOW)
{
yield();
}
}
sleepTimeout = millis() + SLEEP_TIMEOUT;
}
else if (rulerChanged)
{
displayRuler();
rulerChanged = false;
sleepTimeout = millis() + SLEEP_TIMEOUT;
}
else
{
delay(100);
}
}

//——————————————————————–
// display current distance
void displayRuler()
{
float cm = (2 * PI * WHEEL_RADIUS * ruler) / RESOLUTION;
long mm10 = floor(cm * 100 + 0.5);

//oled.clear(); //all black
oled.setFont(FONT16X32);
oled.setCursor(4,0);
displayNumber(mm10,true);
oled.setCursor(4,4);
displayNumber(mm10 * 100 / 254,false);
oled.setFont(FONT8X16);
oled.setCursor(108,2);
oled.print(“mm”);
oled.setCursor(108,6);
oled.print(“in”);
}

//——————————————————————–
// display current distance
void displayNumber(uint32_t number, bool isMM)
{
char buffer[10];
if (isMM)
{
sprintf(buffer,”%4dx2e%01d”,(int)number / 10, (int)(number % 10));
}
else
{
sprintf(buffer, “%3dx2e%02d”, (int)(number / 100), (int)(number % 100));
}
oled.print(buffer);
}

//——————————————————————–
//Shut down OLED and put ATtiny to sleep
//Will wake up when LEFT button is pressed
void system_sleep()
{
detachRotaryPinChangeInterrupt();
interrupts();
oled.ssd1306_sleep();
delay(100);
attachRotaryPinChangeInterrupt();
sleepTimeout = millis() + SLEEP_TIMEOUT;
}

Скачать библиотеку для скетча

Скачать файлы корпуса для печати на принтере в формате .STL

Всем добра!!!

SitesReady

Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного. - Альберт Эйнштейн

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.