Большой модульный поворотный стол для 3D-сканирования - E..

Источник:

Обзор

Это моторизованный поворотный стол, сделанный своими руками, предназначенный в первую очередь для 3D-сканирования, но его также можно использовать в качестве поворотного стола для демонстрации продукции.

Проект был разработан в Fusion 360 и создан как проект выходного дня для моих личных нужд. У меня он работает надежно, и я делюсь им на случай, если другие найдут его полезным или захотят его улучшить.

Электроника и управление

Проигрыватель питается от:

ЭСП32

Шаговый двигатель 28BYJ-48

драйвер ULN2003

Поворотный энкодер для:

Контроль скорости

Контроль направления

Запуск/остановка нажатием на энкодер

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

➡ Код Arduino (.ino) и схема подключения приведены ниже.

Механический дизайн

Большой диаметр пластины: 430 мм.

Табличка разделена на 4 части, поэтому ее можно распечатать на небольших принтерах, а затем склеить.

Используются подшипники 608Z (x5) для плавного вращения.

Съемные ножки для удобства хранения и транспортировки.

Ножки можно закрепить винтами М3.

Или даже зубочистки для быстрой установки без инструментов.

Печать заметок

После печати секции пластины необходимо склеить.

Никаких особых допусков не требуется

Необходимые детали

Подшипники 608Z × 5

ЭСП32 × 1

Шаговый двигатель 28BYJ-48 × 1

Драйвер ULN2003 × 1

Поворотный энкодер × 1

Перемычки

Винты M3 × 4 (или 12 для постоянного крепления на ножке)

Будущие улучшения

Этот дизайн хорош�� подходит для моего использования, но он не идеален. Я могу улучшить его в будущем и приглашаю всех модифицировать, перерабатывать или улучшать его по своему усмотрению.

Если вы что-то создадите или измените — поделитесь этим!

Код и Readme:

#include

const uint8_t StepPins[4] = {21, 19, 18, 5};

const uint8_t кодерCLK = 15;
const uint8_t encoderDT = 2;
const uint8_t encoderSW = 4;

const uint8_t StepSequence[8][4] = {
{1, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{1, 0, 0, 1}
};

изменчивый int16_t encoderDelta = 0;
int8_t currentStep = 0;

int16_t SpeedSetting = 0;
int16_t currentSpeed ​​= 0;

const int16_t SpeedIncrement = 2; // Множитель фиксации энкодера
const int16_t maxSpeedSetting = 160; // Зажим для устойчивости
const uint32_t maxStepInterval = 4500; // Самый медленный (мкс)
const uint32_t minStepInterval = 900; // Самый быстрый (мкс)
const uint8_t AccelStep = 1; // Шаг ускорения

const uint32_t debounceMs = 50;
bool пауза = ложь;
Bool LastButtonState = ВЫСОКИЙ;
uint32_t LastButtonChange = 0;

uint32_t LastStepMicros = 0;

void IRAM_ATTR handleEncoder() {
статический uint8_t LastState = 0;

uint8_t состояние = (digitalRead(encoderCLK) << 1) | digitalRead (энкодерDT);
uint8_t переход = (lastState << 2) | состояние;

переключатель (переход) {
случай 0b0001:
случай 0b0111:
случай 0b1110:
случай 0b1000:
кодерДельта++;
перерыв;
случай 0b0010:
случай 0b0100:
случай 0b1101:
случай 0b1011:
кодировщикDelta--;
перерыв;
по умолчанию:
перерыв;
}

LastState = состояние;
}

void applyStep(int8_t StepIndex) {
для (uint8_t я = 0; я <4; я++) {
digitalWrite(stepPins[i], StepSequence[stepIndex][i]);
}
}

void StepMotor (int направление) {
currentStep = (currentStep + направление + 8) % 8;
ApplyStep (текущийШаг);
}

недействительная настройка() {
для (uint8_t контакт: StepPins) {
pinMode (контакт, ВЫХОД);
digitalWrite(контакт, НИЗКИЙ);
}

pinMode (энкодерCLK, INPUT_PULLUP);
pinMode (энкодерDT, INPUT_PULLUP);
pinMode (encoderSW, INPUT_PULLUP);

AttachInterrupt (digitalPinToInterrupt (encoderCLK), handleEncoder, CHANGE);
AttachInterrupt (digitalPinToInterrupt (encoderDT), handleEncoder, CHANGE);
}

недействительный цикл() {
int16_t дельта;

нетПрерывания();
дельта = кодировщикDelta;
энкодерДельта = 0;
прерывания();

const bool buttonState = digitalRead(encoderSW);
const uint32_t nowMs = millis();

if (buttonState != LastButtonState && (nowMs — LastButtonChange) > debounceMs) {
LastButtonChange = nowMs;
LastButtonState = buttonState;

если (buttonState == НИЗКИЙ) {
пауза =! пауза;
если (пауза

19:22
37
Нет комментариев. Ваш будет первым!

Ссылка появится после регистрации

Похожие модели

Посещая этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.