Большой модульный поворотный стол для 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 == НИЗКИЙ) {
пауза =! пауза;
если (пауза





























