#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);
}
}#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);
}#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
}// 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);
}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âmetro | Fórmula | Exemplo |
|---|---|---|
| Passos por mm | 200 ÷ 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 mm | posAtual ÷ passos_por_mm | 500 passos ÷ 250 = 2.0 mm |
| Mover X mm | round(X × passos_por_mm) | Mover 5mm = 5 × 250 = 1250 passos |