// ======= ЛИФТ: Два положения (низ/верх), два мотора =======
// BOOT: переключение положения
// Пины:
// STEP/DIR лифта -> пины 1 и 2 (оба драйвера сидят на этих же линиях)
// Нижний концевик -> пин 3
#include <Arduino.h>
// ====================== НАСТРОЙКИ ======================
#define PIN_BOOT 0 // Кнопка BOOT (на плате)
#define LIFT_STEP_PIN 1 // STEP для обоих драйверов
#define LIFT_DIR_PIN 2 // DIR для обоих драйверов
#define LIM_BOTTOM_PIN 3 // Концевик внизу (АКТИВЕН при нажатии)
// Параметры движения
const int STEPS_PER_MM = 100; // 100 шагов на мм (примерно как в старом коде)
const int LIFT_SPEED_SPS = 1500; // Скорость ~1500 шаг/сек
const int STEP_INTERVAL_US = 1000000 / LIFT_SPEED_SPS;
const int STEP_PULSE_US = 3;
// Ход лифта
const int TRAVEL_MM = 200; // 20 см
const long TRAVEL_STEPS = (long)TRAVEL_MM * STEPS_PER_MM;
// ====================== ПЕРЕМЕННЫЕ =================
bool buttonPressed = false;
unsigned long lastButtonPress = 0;
unsigned long lastStatusPrint = 0;
long currentPositionSteps = 0; // 0 = низ (по концевику). Наверху ~ TRAVEL_STEPS
// ====================== ВСПОМОГАТЕЛЬНЫЕ =================
bool isBottomActive() {
// Предполагаем, что концевик тянет к GND, а подтяжка к VCC -> активен при LOW
return (digitalRead(LIM_BOTTOM_PIN) == LOW);
}
void doStepOnce() {
digitalWrite(LIFT_STEP_PIN, HIGH);
delayMicroseconds(STEP_PULSE_US);
digitalWrite(LIFT_STEP_PIN, LOW);
delayMicroseconds(STEP_INTERVAL_US - STEP_PULSE_US);
}
// Подъем строго на TRAVEL_STEPS шагов (20 см) от низа
void moveUpFromBottom() {
Serial.println("\n=== ДВИЖЕНИЕ ВВЕРХ (20 см) ===");
Serial.printf("TRAVEL_STEPS = %ld\n", TRAVEL_STEPS);
// Как в старом коде: вверх было при LOW на DIR
digitalWrite(LIFT_DIR_PIN, LOW);
delayMicroseconds(10);
for (long i = 0; i < TRAVEL_STEPS; i++) {
doStepOnce();
currentPositionSteps++;
}
Serial.println("Подъем завершен (предположительно ВЕРХ)");
}
// Опускание до срабатывания нижнего концевика (но не более, чем TRAVEL_STEPS + запас)
void moveDownToBottom() {
Serial.println("\n=== ДВИЖЕНИЕ ВНИЗ до нижнего концевика ===");
digitalWrite(LIFT_DIR_PIN, HIGH); // Вниз
delayMicroseconds(10);
long stepsDone = 0;
long maxSteps = TRAVEL_STEPS + STEPS_PER_MM * 10; // небольшой запас, чтобы не крутиться бесконечно
while (!isBottomActive() && stepsDone < maxSteps) {
doStepOnce();
stepsDone++;
if (currentPositionSteps > 0) currentPositionSteps--;
}
if (isBottomActive()) {
Serial.printf("Достигнут нижний концевик за %ld шагов\n", stepsDone);
currentPositionSteps = 0;
} else {
Serial.println("ВНИМАНИЕ: нижний концевик не сработал, остановка по лимиту шагов!");
}
}
// ====================== SETUP ======================
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("\n\n=====================================");
Serial.println(" ЛИФТ: 2 положения (низ/верх)");
Serial.println(" Два мотора на общих STEP/DIR (1,2)");
Serial.println(" Нижний концевик на пине 3");
Serial.println("=====================================\n");
pinMode(PIN_BOOT, INPUT_PULLUP);
pinMode(LIFT_STEP_PIN, OUTPUT);
pinMode(LIFT_DIR_PIN, OUTPUT);
pinMode(LIM_BOTTOM_PIN, INPUT_PULLUP);
digitalWrite(LIFT_STEP_PIN, LOW);
digitalWrite(LIFT_DIR_PIN, LOW);
// Проверка начального состояния концевика
Serial.printf("Начальное состояние концевика (низ): %s\n",
isBottomActive() ? "АКТИВЕН (лифт внизу)" : "неактивен (лифт НЕ внизу)");
if (isBottomActive()) {
currentPositionSteps = 0;
} else {
// Нет нижнего концевика — считаем, что лифт "примерно наверху"
currentPositionSteps = TRAVEL_STEPS;
}
Serial.println("\nНажмите BOOT для первого движения (вверх или вниз).");
}
// ====================== LOOP ======================
void loop() {
// -------- Обработка кнопки BOOT с антидребезгом --------
bool buttonState = (digitalRead(PIN_BOOT) == LOW); // Нажата при LOW
if (buttonState && !buttonPressed && (millis() - lastButtonPress > 200)) {
buttonPressed = true;
lastButtonPress = millis();
// ЛОГИКА:
// Если концевик нажат -> лифт внизу -> едем ВВЕРХ на 20 см
// Если концевик не нажат -> лифт наверху -> едем ВНИЗ до концевика
if (isBottomActive()) {
Serial.println("\n[BOOT] Концевик нажат -> лифт внизу -> едем ВВЕРХ");
moveUpFromBottom();
} else {
Serial.println("\n[BOOT] Концевик не нажат -> лифт наверху -> едем ВНИЗ");
moveDownToBottom();
}
}
if (!buttonState) {
buttonPressed = false;
}
// -------- Периодический вывод статуса --------
if (millis() - lastStatusPrint > 1000) {
lastStatusPrint = millis();
long posMM = currentPositionSteps / STEPS_PER_MM;
Serial.printf("Статус: позиция ~%ld мм | концевик=%s\n",
posMM,
isBottomActive() ? "АКТИВЕН (низ)" : "неактивен");
}
}
концевик N2. нижний
концевик N3. верхний
дравер и мотор редуктор
pin IN1
GND
pin IN2
N1 концевик лифта (обнуляет)
5v
12v
boot