Início›Projetos›CNC Base
⬤ Projeto Integrado · LCD + Motor de Passo

🔩 Posicionador de Precisão — Base CNC

⏱️ 60–75 min 🧩 Motor de passo · LCD posição · Passos → mm · Botões · Homing · Perfil de velocidade

Nesta página

🎯 Objetivo e Resultado

Posicionador linear de precisão que usa um motor de passo para mover uma plataforma. O LCD exibe posição actual em mm, destino, velocidade em RPM e modo de operação. Dois botões definem o destino. Um botão de homing encontra o zero absoluto. Base conceptual de sistemas CNC de eixo único.

Posicionador CNC Pos: 12.4mm Alvo:25Vel: 60RPM SINGLE [++++++++ ]

⚙️ Parâmetros Mecânicos — Calcular Passos/mm

Tipo de transmissãoFórmulaExemplo concreto
Parafuso roscadopassos/mm = PROT ÷ passo_rosca(mm)200 p/rot ÷ 0.8mm/rot (M5) = 250 p/mm
Porca de chumbo (lead screw)passos/mm = PROT ÷ lead(mm)200 ÷ 2mm lead = 100 p/mm
Correia dentada GT2passos/mm = PROT ÷ (dentes × 2mm)200 ÷ (20 × 2) = 5 p/mm
Correia GT3passos/mm = PROT ÷ (dentes × 3mm)200 ÷ (20 × 3) ≈ 3.33 p/mm
💡
Neste projeto usa-se um parafuso M5 como exemplo (250 passos/mm). Altera a constante PASSOS_MM para o teu tipo de transmissão antes de carregar o sketch.

🔌 Ligações

ComponentePino ArduinoNota
LCD 20×4 (I2C)A4 (SDA) / A5 (SCL)Endereço 0x27
Motor de passo (M1+M2)Canal 1 da placaAF_Stepper(200,1)
Botão + (aumentar alvo)D2 (INPUT_PULLUP)Incrementa 1mm por pressão
Botão − (diminuir alvo)D3 (INPUT_PULLUP)Decrementa 1mm por pressão
Botão GO (executar movimento)D4 (INPUT_PULLUP)Inicia movimento para o alvo
Botão HOME (homing)D5 (INPUT_PULLUP)Volta ao zero e redefine posição
Fim de curso (sensor zero)D6 (INPUT_PULLUP)LOW quando plataforma em posição 0

🔨 Fases de Montagem

Fase 1 — Motor e LCD básico

Liga o motor ao canal 1. Carrega um sketch de teste: stepper.step(200, FORWARD, SINGLE). Confirma que roda. Liga o LCD e exibe 'Motor OK'.

Fase 2 — Homing com fim de curso

Liga o botão de fim de curso ao D6. Implementa a função homing(): recua até LOW em D6, define posAtual=0. Testa isoladamente.

Fase 3 — Botões de destino e GO

Implementa os botões + e − para alterar alvomm. Ao premir GO, calcula passos necessários e executa irPara(). Exibe posição e destino no LCD.

Fase 4 — Perfil de velocidade e barra

Adiciona rampa de aceleração no irPara(). Implementa barra gráfica de progresso do movimento na linha 3.

💻 Código Completo

proj_cnc_stepper.ino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AFMotor.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);
AF_Stepper stepper(200, 1);

// ── Parâmetros mecânicos ─────────────────────────────────────
#define PASSOS_MM    250   // Parafuso M5 (0.8mm/rot × 200 p/rot)
#define POS_MAX_MM    80   // Curso máximo em mm
#define RPM_NORMAL    60
#define RPM_MIN       15   // RPM mínimos para a rampa

// ── Botões ────────────────────────────────────────────────────
#define BTN_MAIS  2
#define BTN_MENOS 3
#define BTN_GO    4
#define BTN_HOME  5
#define FIM_CURSO 6

// ── Estado ────────────────────────────────────────────────────
float         posMM  = 0;    // posição actual em mm
float         alvoMM = 0;    // destino em mm
long          posP   = 0;    // posição em passos
unsigned long tBtn   = 0;

// ── Converter mm → passos ─────────────────────────────────────
long mmToP(float mm) { return (long)(mm * PASSOS_MM); }
float pToMM(long p)  { return (float)p / PASSOS_MM; }

// ── Dashboard LCD ─────────────────────────────────────────────
void dashboard(const char* estado, int rpm) {
  lcd.setCursor(0,0); lcd.print("Posicionador CNC    ");
  lcd.setCursor(0,1);
  lcd.print("Pos:"); lcd.print(posMM,1); lcd.print("mm Alv:");
  lcd.print(alvoMM,0); lcd.print("mm  ");
  lcd.setCursor(0,2);
  lcd.print("Vel:"); lcd.print(rpm); lcd.print("RPM  ");
  lcd.print(estado); lcd.print("  ");
}

// ── Barra de progresso do movimento ──────────────────────────
void barraProgresso(long atual, long total) {
  int b = (total > 0) ? (int)(abs(atual) * 20 / total) : 20;
  b = constrain(b, 0, 20);
  lcd.setCursor(0,3); lcd.print("[");
  for(int i=0;i<18;i++) i<b-1 ? lcd.write(0xFF) : (i==b-1 ? lcd.write('+') : lcd.write(' '));
  lcd.print("]");
}

// ── Homing ────────────────────────────────────────────────────
void homing() {
  lcd.setCursor(0,2); lcd.print("HOMING...           ");
  stepper.setSpeed(RPM_MIN);
  while(digitalRead(FIM_CURSO) == HIGH)
    stepper.step(1, BACKWARD, SINGLE);
  posP = 0; posMM = 0; alvoMM = 0;
  stepper.release();
  stepper.setSpeed(RPM_NORMAL);
  lcd.setCursor(0,2); lcd.print("HOME OK   pos=0     ");
  delay(800);
}

// ── Ir para posição com rampa ─────────────────────────────────
void irPara(float mm) {
  mm = constrain(mm, 0, POS_MAX_MM);
  long alvoP = mmToP(mm);
  long delta  = alvoP - posP;
  if(delta == 0) return;

  uint8_t dir  = (delta > 0) ? FORWARD : BACKWARD;
  long    absD = abs(delta);
  int     ramp = min(absD/3, (long)60);

  for(long i=0; i<absD; i++) {
    int rpm;
    if     (i < ramp)        rpm = map(i, 0, ramp, RPM_MIN, RPM_NORMAL);
    else if(i > absD-ramp)   rpm = map(absD-i, 0, ramp, RPM_MIN, RPM_NORMAL);
    else                     rpm = RPM_NORMAL;

    stepper.setSpeed(rpm);
    stepper.step(1, dir, SINGLE);
    posP += (dir==FORWARD) ? 1 : -1;
    posMM = pToMM(posP);

    if(i % 20 == 0) {  // actualiza LCD a cada 20 passos
      dashboard("EM CURSO", rpm);
      barraProgresso(i, absD);
    }
  }
  alvoMM = mm;
  stepper.release();
  dashboard("NO ALVO ", 0);
  barraProgresso(1, 1); // barra cheia
}

void setup() {
  lcd.init(); lcd.backlight();
  stepper.setSpeed(RPM_NORMAL);
  for(int p : {BTN_MAIS,BTN_MENOS,BTN_GO,BTN_HOME,FIM_CURSO})
    pinMode(p, INPUT_PULLUP);
  homing();
  dashboard("PRONTO  ", 0);
}

void loop() {
  if(millis()-tBtn < 200) return;  // debounce global

  if(digitalRead(BTN_MAIS)==LOW)  { alvoMM=constrain(alvoMM+1,0,POS_MAX_MM); tBtn=millis(); }
  if(digitalRead(BTN_MENOS)==LOW) { alvoMM=constrain(alvoMM-1,0,POS_MAX_MM); tBtn=millis(); }
  if(digitalRead(BTN_GO)==LOW)    { irPara(alvoMM); tBtn=millis(); }
  if(digitalRead(BTN_HOME)==LOW)  { homing(); tBtn=millis(); }

  dashboard("PRONTO  ", 0);
}

🚀 Como Expandir

🏆 Para ir mais longe

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