Início›Stepper
⬤ Stepper · Avançado

🔩 Motor de Passo — Controlo Preciso

⏱️ 40 min 🧩 AF_Stepper · Full/half step · Posicionamento absoluto · Homing · LCD

Nesta página

⚙️ Comparar os 4 Modos em Código

ℹ️
Em modo INTERLEAVE, o número de passos é o dobro do SINGLE para a mesma rotação (400 vs 200 para 1 volta). Em MICROSTEP é 8× mais (1600 para 1 volta num motor 200 passos/rot).
ex_stepper_modos.ino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AFMotor.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);
AF_Stepper stepper(200, 1);  // 200 p/rot, canal 1

struct Modo { uint8_t tipo; const char* nome; int mult; };
const Modo modos[] = {
  {SINGLE,     "SINGLE    1.80grau", 1},
  {DOUBLE,     "DOUBLE    1.80grau", 1},
  {INTERLEAVE, "INTERLEAVE 0.90gra", 2},
  {MICROSTEP,  "MICROSTEP 0.225gra", 8}
};

void setup() {
  lcd.init(); lcd.backlight();
  stepper.setSpeed(60);
  lcd.setCursor(0,0); lcd.print("Motor de Passo Test ");
}

void loop() {
  for (auto& m : modos) {
    lcd.setCursor(0,1); lcd.print(m.nome);
    lcd.setCursor(0,2); lcd.print("FORWARD 1 rotacao   ");
    stepper.step(200 * m.mult, FORWARD, m.tipo);
    delay(500);

    lcd.setCursor(0,2); lcd.print("BACKWARD 1 rotacao  ");
    stepper.step(200 * m.mult, BACKWARD, m.tipo);
    stepper.release();
    delay(1200);
  }
}

📍 Posicionamento Absoluto com LCD

ex_stepper_abs.ino
#define PROT 200   // passos por rotação do teu motor
AF_Stepper stepper(PROT, 1);
long posAtual = 0;  // posição atual em passos (pode ser negativa)

float toGraus(long p) { return (float)p * 360.0 / PROT; }

void irPara(long alvo) {
  long    delta = alvo - posAtual;
  uint8_t dir   = (delta > 0) ? FORWARD : BACKWARD;
  long    abs_d = delta > 0 ? delta : -delta;

  lcd.setCursor(0,2);
  lcd.print(delta > 0 ? "→ " : "← ");
  lcd.print(abs(delta)); lcd.print(" passos  ");

  stepper.step((int)abs_d, dir, SINGLE);
  posAtual = alvo;

  lcd.setCursor(0,1); lcd.print("Pos: "); lcd.print(posAtual); lcd.print("   ");
  lcd.setCursor(0,3); lcd.print("Ang: ");
  lcd.print(toGraus(posAtual), 1); lcd.print("       ");
}

void setup() {
  lcd.init(); lcd.backlight();
  stepper.setSpeed(60);
  lcd.setCursor(0,0); lcd.print("Posicionamento Abs. ");
}

void loop() {
  irPara(100);  delay(1000);  // 180°
  irPara(200);  delay(1000);  // 360°
  irPara(50);   delay(1000);  // 90°
  irPara(0);    delay(1000);  // Regresso a zero
  stepper.release();
  delay(2000);
}
Posicionamento Abs. Pos: +200 → 200 passos Ang: 360.0

🏠 Homing — Encontrar o Zero com Fim de Curso

⚠️
O motor de passo não tem memória de posição — ao desligar a alimentação perde a referência. O homing move o motor em sentido negativo até activar um sensor (botão de fim de curso ou IR) e define esse ponto como posição zero absoluta.
ex_stepper_homing.ino
#define FIM_CURSO 2   // INPUT_PULLUP — LOW quando activado
#define VEL_HOMING 30 // RPM lentos para precisão

bool homing() {
  stepper.setSpeed(VEL_HOMING);
  lcd.setCursor(0,0); lcd.print("HOMING...           ");

  // Move BACKWARD até activar o fim de curso
  while(digitalRead(FIM_CURSO) == HIGH) {
    stepper.step(1, BACKWARD, SINGLE);
    lcd.setCursor(0,1); lcd.print("Recuando...  ");
  }

  posAtual = 0;  // Zero definido aqui
  stepper.release();
  lcd.setCursor(0,0); lcd.print("HOMING CONCLUIDO    ");
  lcd.setCursor(0,1); lcd.print("Zero definido       ");
  delay(1000);
  stepper.setSpeed(60);  // Restaurar velocidade normal
  return true;
}

void setup() {
  lcd.init(); lcd.backlight();
  pinMode(FIM_CURSO, INPUT_PULLUP);
  homing();   // Sempre faz homing ao arrancar
}

📈 Perfil de Aceleração por Alteração de RPM

ex_stepper_accel.ino
// Aceleração progressiva: aumenta RPM passo a passo
void moverComAceleracao(int n, uint8_t dir,
                         int rpmMin, int rpmMax) {
  int rampaPasos = min(n/3, 30);  // 1/3 do total para rampa

  for(int i=0; i<n; i++) {
    int rpm;
    if     (i < rampaPasos)   rpm = map(i, 0, rampaPasos, rpmMin, rpmMax);
    else if(i > n-rampaPasos) rpm = map(n-i, 0, rampaPasos, rpmMin, rpmMax);
    else                       rpm = rpmMax;

    stepper.setSpeed(rpm);
    stepper.step(1, dir, SINGLE);

    lcd.setCursor(0,2); lcd.print("RPM: "); lcd.print(rpm); lcd.print("   ");
  }
  posAtual += (dir==FORWARD) ? n : -n;
}

// 1 rotação com aceleração: 10 → 80 → 10 RPM
void loop() {
  moverComAceleracao(200, FORWARD, 10, 80);
  delay(500);
  moverComAceleracao(200, BACKWARD, 10, 80);
  stepper.release(); delay(2000);
}

🔩 Base Conceptual CNC

Num sistema CNC simples, a posição linear é calculada a partir dos passos do motor e do passo mecânico (passo do parafuso ou passo da correia):

ParâmetroFórmulaExemplo
Passos por mm200 ÷ passo_parafuso (mm/rot)Motor 200p/rot + parafuso M5 0.8mm/rot → 250 p/mm
Passos por mm (correia)200 ÷ (dentes_polia × passo_correia)Motor 200p + polia 20t + GT2 (2mm) → 200÷40 = 5 p/mm
Posição em mmposAtual ÷ passos_por_mm500 passos ÷ 250 = 2.0 mm
Mover X mmround(X × passos_por_mm)Mover 5mm = 5 × 250 = 1250 passos

🏆 Para ir mais longe

PR.FT9_5 · LCD 20×4 · L293D Motor Driver · Arduino UNO Rev3 · Início · led.dge.medu.pt