خانه » فروشگاه » شیلد موتور پله‌ای برای درایورهای A4988 یا DRV8825
بازگشت به محصولات
NSM-THSM
ماژول سنسور دما و رطوبت قیمت اصلی: 120,000 تومان بود.قیمت فعلی: 98,000 تومان.هر عدد

شیلد موتور پله‌ای برای درایورهای A4988 یا DRV8825

قیمت اصلی: 235,000 تومان بود.قیمت فعلی: 229,000 تومان.هر عدد

شیلد درایور موتور پله‌ای یک برد توسعه کامل برای کنترل حرفه‌ای موتورهای پله‌ای با استفاده از درایورهای A4988 یا DRV8825 است.

این شیلد امکان کنترل تا ۲ موتور پله‌ای را به صورت همزمان فراهم کرده و با قابلیت‌هایی مانند تنظیم جریان، میکرواستپینگ، حفاظت حرارتی و قطع ارتباط خودکار، انتخاب ایده‌آلی برای پروژه‌های CNC، پرینترهای ۳ بعدی، رباتیک و اتوماسیون صنعتی می‌باشد.

تعداد قیمت تخفیف
10-49 224,420 تومان هر عدد 2%
50+ 222,130 تومان هر عدد 3%

5,000,000 تومان را به سبد خرید اضافه کنید و ارسال رایگان دریافت کنید!

موجود در انبار

Size and packaging guidelines

یکا (واحد) علامت اختصاری شرح انگلیسی مقدار
1 متر m Meter 1
1 سانتی متر cm Canti Meter 2-^10
1 میلی متر mm Mili Meter 3-^10
1 اینچ in Inch 2.54cm
2 اینچ in Inch 5.08cm
3 اینچ in Inch 7.62cm
5 اینچ in Inch 12.7cm
10 افرادی که اکنون این محصول را تماشا می کنند!



توضیحات

شیلد درایور موتور پله‌ای

(A4988/DRV8825)

راه‌حل جامع کنترل موتورهای پله‌ای با دقت و قدرت بالا

شیلد درایور موتور پله‌ای یک برد توسعه کامل برای کنترل حرفه‌ای موتورهای پله‌ای با استفاده از درایورهای A4988 یا DRV8825 است. این شیلد امکان کنترل تا ۲ موتور پله‌ای را به صورت همزمان فراهم کرده و با قابلیت‌هایی مانند تنظیم جریان، میکرواستپینگ، حفاظت حرارتی و قطع ارتباط خودکار، انتخاب ایده‌آلی برای پروژه‌های CNC، پرینترهای ۳ بعدی، رباتیک و اتوماسیون صنعتی می‌باشد.


ویژگی‌های کلیدی

  • پشتیبانی از دو درایور: قابلیت استفاده همزمان از A4988 و DRV8825

  • تنظیم جریان دقیق: پتانسیومتر برای تنظیم جریان هر موتور به صورت مجزا

  • میکرواستپینگ پیشرفته: پشتیبانی تا ۱/۳۲ میکرواستپ (DRV8825) و ۱/۱۶ (A4988)

  • حفاظت کامل: محافظ در برابر اتصال کوتاه، اضافه جریان و اضافه دما

  • خنک‌کننده یکپارچه: هیت‌سینک آلومینیومی برای هر درایور

  • منبع تغذیه دوگانه: ورودی منطقی ۵V و ورودی موتور تا ۳۵V

  • اتصالات صنعتی: ترمینال پیچی برای اتصال آسان موتورها

  • کاهش نویز: خازن‌های سرامیکی و الکترولیتی برای فیلتر نویز

  • سازگاری کامل: پین‌های سازگار با آردوینو Uno، Mega، Nano


مشخصات فنی

مشخصات کلی:

  • ولتاژ ورودی منطق: 3.3V – 5V (از آردوینو)

  • ولتاژ موتور: 8V – 35V (A4988) / 8.2V – 45V (DRV8825)

  • جریان پیوسته: تا 2A در هر فاز (با خنک‌کاری)

  • جریان پالسی: تا 2.5A (A4988) / تا 2.5A (DRV8825)

  • میکرواستپینگ: 1, 1/2, 1/4, 1/8, 1/16 (A4988) + 1/32 (DRV8825)

  • ابعاد برد: 70mm × 54mm (مطابق آردوینو Uno)

  • حفاظت حرارتی: Shutdown در 150°C (A4988) / 165°C (DRV8825)

پین‌های مهم:

موتور 1:
ENABLE1 (D8)   - فعال/غیرفعال کردن درایور
STEP1 (D5)     - پالس قدم
DIR1 (D6)      - جهت چرخش
MS1, MS2, MS3  - انتخاب میکرواستپ

موتور 2:
ENABLE2 (D9)
STEP2 (D7)
DIR2 (D4)
MS1, MS2, MS3

منبع تغذیه:
VMOT  - ولتاژ موتور (8-35V)
GND   - زمین موتور
VDD   - ولتاژ منطق (3.3-5V)

مقایسه درایورها:

ویژگیA4988DRV8825
ولتاژ کاری8-35V8.2-45V
جریان پیوسته1-2A1.5-2.5A
میکرواستپینگتا 1/16تا 1/32
مقاومت سنس جریان0.05Ω0.1Ω
راندمانمتوسطبالا
قیمتارزان‌ترگران‌تر

اتصال موتور پله‌ای NEMA 17

موتور پله‌ای ← شیلد
-------------------
فاز 1A → 1A
فاز 1B → 1B
فاز 2A → 2A
فاز 2B → 2B
گرمایش ← GND (اختیاری)

نکته: ترتیب فازها بسیار مهم است. اگر موتور درست کار نکرد، سیم‌های یک فاز را جابجا کنید.


کد پایه: کنترل موتور پله‌ای

/*
 * کنترل ساده موتور پله‌ای با شیلد A4988/DRV8825
 * حرکت در دو جهت با سرعت‌های مختلف
 */

// پایه‌های موتور 1
const int ENABLE1 = 8;
const int STEP1 = 5;
const int DIR1 = 6;

// پایه‌های موتور 2
const int ENABLE2 = 9;
const int STEP2 = 7;
const int DIR2 = 4;

// پایه‌های میکرواستپ (مشترک برای هر دو موتور)
const int MS1 = 10;
const int MS2 = 11;
const int MS3 = 12;

// تنظیمات موتور
const int STEPS_PER_REV = 200; // برای موتور NEMA 17
int microstep = 16; // مقدار میکرواستپ (1, 2, 4, 8, 16, 32)
int totalStepsPerRev; // مراحل کامل در هر دور

// سرعت موتور (تأخیر بین استپ‌ها در میکروثانیه)
int stepDelay = 1000; // 1000 میکروثانیه = 1ms

void setup() {
  Serial.begin(9600);
  
  // تنظیم پایه‌ها به عنوان خروجی
  pinMode(ENABLE1, OUTPUT);
  pinMode(STEP1, OUTPUT);
  pinMode(DIR1, OUTPUT);
  
  pinMode(ENABLE2, OUTPUT);
  pinMode(STEP2, OUTPUT);
  pinMode(DIR2, OUTPUT);
  
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(MS3, OUTPUT);
  
  // غیرفعال کردن موتورها در ابتدا (LOW = فعال)
  digitalWrite(ENABLE1, HIGH);
  digitalWrite(ENABLE2, HIGH);
  
  // تنظیم میکرواستپ
  setupMicrostepping(microstep);
  
  // محاسبه مراحل کامل
  totalStepsPerRev = STEPS_PER_REV * microstep;
  
  Serial.println("\n\n========================================");
  Serial.println("   Stepper Motor Shield Controller");
  Serial.println("========================================");
  Serial.print("Motor: NEMA 17 (");
  Serial.print(STEPS_PER_REV);
  Serial.println(" steps/rev)");
  Serial.print("Microstepping: 1/");
  Serial.println(microstep);
  Serial.print("Total steps/rev: ");
  Serial.println(totalStepsPerRev);
  Serial.println("Commands: F=Forward, B=Backward, S=Stop");
  Serial.println("         +=Faster, -=Slower, ?=Help");
  Serial.println("----------------------------------------");
}

void loop() {
  if (Serial.available()) {
    char command = Serial.read();
    processCommand(command);
  }
  
  // می‌توانید حرکات خودکار را اینجا اضافه کنید
  // autoDemo();
  
  delay(10);
}

void processCommand(char cmd) {
  switch (cmd) {
    case 'F':
    case 'f':
      Serial.println("Moving FORWARD");
      moveMotor(1, true, totalStepsPerRev); // 1 دور به جلو
      break;
      
    case 'B':
    case 'b':
      Serial.println("Moving BACKWARD");
      moveMotor(1, false, totalStepsPerRev); // 1 دور به عقب
      break;
      
    case 'S':
    case 's':
      Serial.println("STOPPING");
      stopMotors();
      break;
      
    case '+':
      increaseSpeed();
      break;
      
    case '-':
      decreaseSpeed();
      break;
      
    case '1':
      moveMotor(1, true, totalStepsPerRev / 4); // 90 درجه
      break;
      
    case '2':
      moveMotor(2, true, totalStepsPerRev / 2); // 180 درجه
      break;
      
    case '3':
      moveBothMotors(true, totalStepsPerRev); // هر دو موتور
      break;
      
    case '?':
      showHelp();
      break;
      
    case 'M': // تغییر میکرواستپ
      changeMicrostepping();
      break;
  }
}

void moveMotor(int motor, bool forward, int steps) {
  // فعال کردن موتور
  if (motor == 1) {
    digitalWrite(ENABLE1, LOW);
    digitalWrite(DIR1, forward ? HIGH : LOW);
  } else {
    digitalWrite(ENABLE2, LOW);
    digitalWrite(DIR2, forward ? HIGH : LOW);
  }
  
  delay(10); // تأخیر برای فعال شدن
  
  // ارسال پالس‌های استپ
  for (int i = 0; i < steps; i++) {
    if (motor == 1) {
      digitalWrite(STEP1, HIGH);
      delayMicroseconds(stepDelay);
      digitalWrite(STEP1, LOW);
    } else {
      digitalWrite(STEP2, HIGH);
      delayMicroseconds(stepDelay);
      digitalWrite(STEP2, LOW);
    }
    delayMicroseconds(stepDelay);
  }
  
  // غیرفعال کردن موتور پس از حرکت
  if (motor == 1) {
    digitalWrite(ENABLE1, HIGH);
  } else {
    digitalWrite(ENABLE2, HIGH);
  }
  
  Serial.print("Motor ");
  Serial.print(motor);
  Serial.print(" moved ");
  Serial.print(steps);
  Serial.print(" steps (");
  Serial.print((steps * 360.0) / totalStepsPerRev, 1);
  Serial.println(" degrees)");
}

void moveBothMotors(bool forward, int steps) {
  // فعال کردن هر دو موتور
  digitalWrite(ENABLE1, LOW);
  digitalWrite(ENABLE2, LOW);
  
  digitalWrite(DIR1, forward ? HIGH : LOW);
  digitalWrite(DIR2, forward ? HIGH : LOW);
  
  delay(10);
  
  // حرکت همزمان
  for (int i = 0; i < steps; i++) {
    digitalWrite(STEP1, HIGH);
    digitalWrite(STEP2, HIGH);
    delayMicroseconds(stepDelay);
    
    digitalWrite(STEP1, LOW);
    digitalWrite(STEP2, LOW);
    delayMicroseconds(stepDelay);
  }
  
  // غیرفعال کردن
  digitalWrite(ENABLE1, HIGH);
  digitalWrite(ENABLE2, HIGH);
  
  Serial.print("Both motors moved ");
  Serial.print(steps);
  Serial.println(" steps");
}

void stopMotors() {
  digitalWrite(ENABLE1, HIGH);
  digitalWrite(ENABLE2, HIGH);
  Serial.println("Motors disabled");
}

void setupMicrostepping(int mode) {
  // جدول تنظیمات میکرواستپ:
  // MS1 MS2 MS3 | Microstep Resolution
  //  L   L   L  | Full Step
  //  H   L   L  | Half Step
  //  L   H   L  | 1/4 Step
  //  H   H   L  | 1/8 Step
  //  H   H   H  | 1/16 Step (A4988) / 1/32 Step (DRV8825)
  
  switch (mode) {
    case 1: // Full Step
      digitalWrite(MS1, LOW);
      digitalWrite(MS2, LOW);
      digitalWrite(MS3, LOW);
      break;
      
    case 2: // Half Step
      digitalWrite(MS1, HIGH);
      digitalWrite(MS2, LOW);
      digitalWrite(MS3, LOW);
      break;
      
    case 4: // 1/4 Step
      digitalWrite(MS1, LOW);
      digitalWrite(MS2, HIGH);
      digitalWrite(MS3, LOW);
      break;
      
    case 8: // 1/8 Step
      digitalWrite(MS1, HIGH);
      digitalWrite(MS2, HIGH);
      digitalWrite(MS3, LOW);
      break;
      
    case 16: // 1/16 Step (A4988)
      digitalWrite(MS1, HIGH);
      digitalWrite(MS2, HIGH);
      digitalWrite(MS3, HIGH);
      break;
      
    case 32: // 1/32 Step (DRV8825)
      // برای DRV8825 تنظیمات متفاوت است
      digitalWrite(MS1, HIGH);
      digitalWrite(MS2, HIGH);
      digitalWrite(MS3, HIGH);
      break;
  }
  
  // به‌روزرسانی مراحل کامل
  totalStepsPerRev = STEPS_PER_REV * mode;
}

void changeMicrostepping() {
  // چرخش بین حالت‌های مختلف میکرواستپ
  int modes[] = {1, 2, 4, 8, 16, 32};
  static int modeIndex = 2; // شروع از 1/4 استپ
  
  modeIndex = (modeIndex + 1) % 6;
  microstep = modes[modeIndex];
  
  setupMicrostepping(microstep);
  
  Serial.print("Microstepping changed to: 1/");
  Serial.println(microstep);
  Serial.print("Total steps/rev: ");
  Serial.println(totalStepsPerRev);
}

void increaseSpeed() {
  if (stepDelay > 100) {
    stepDelay -= 100;
    Serial.print("Speed increased. Delay: ");
    Serial.print(stepDelay);
    Serial.println("µs");
  } else {
    Serial.println("Maximum speed reached");
  }
}

void decreaseSpeed() {
  if (stepDelay < 5000) {
    stepDelay += 100;
    Serial.print("Speed decreased. Delay: ");
    Serial.print(stepDelay);
    Serial.println("µs");
  } else {
    Serial.println("Minimum speed reached");
  }
}

void showHelp() {
  Serial.println("\n=== Stepper Motor Control Help ===");
  Serial.println("F / f  - Move motor 1 forward 1 revolution");
  Serial.println("B / b  - Move motor 1 backward 1 revolution");
  Serial.println("S / s  - Stop/disables motors");
  Serial.println("+      - Increase speed");
  Serial.println("-      - Decrease speed");
  Serial.println("1      - Move motor 1 90 degrees");
  Serial.println("2      - Move motor 2 180 degrees");
  Serial.println("3      - Move both motors together");
  Serial.println("M      - Change microstepping mode");
  Serial.println("?      - Show this help");
  Serial.println("\nCurrent Settings:");
  Serial.print("  Step delay: ");
  Serial.print(stepDelay);
  Serial.println(" µs");
  Serial.print("  Microstepping: 1/");
  Serial.println(microstep);
  Serial.print("  Steps per revolution: ");
  Serial.println(totalStepsPerRev);
  Serial.println("==============================\n");
}

void autoDemo() {
  // نمایش خودکار قابلیت‌ها
  static unsigned long lastDemo = 0;
  static int demoState = 0;
  
  if (millis() - lastDemo > 3000) {
    switch (demoState) {
      case 0:
        Serial.println("Demo: Moving forward 180 degrees");
        moveMotor(1, true, totalStepsPerRev / 2);
        break;
      case 1:
        Serial.println("Demo: Moving backward 180 degrees");
        moveMotor(1, false, totalStepsPerRev / 2);
        break;
      case 2:
        Serial.println("Demo: Changing microstepping to 1/8");
        microstep = 8;
        setupMicrostepping(microstep);
        break;
      case 3:
        Serial.println("Demo: Moving both motors");
        moveBothMotors(true, totalStepsPerRev / 4);
        break;
    }
    
    demoState = (demoState + 1) % 4;
    lastDemo = millis();
  }
}

کد پیشرفته: کنترل موقعیت با شتاب

/*
 * کنترل موقعیت موتور پله‌ای با شتاب/کاهش شتاب
 * مناسب برای CNC و پرینترهای 3 بعدی
 */

#include <AccelStepper.h>

// تعریف موتورها با کتابخانه AccelStepper
// استفاده از حالت Driver (پین STEP و DIR)
AccelStepper stepper1(AccelStepper::DRIVER, 5, 6); // STEP, DIR
AccelStepper stepper2(AccelStepper::DRIVER, 7, 4); // STEP, DIR

// پایه‌های کنترل
const int ENABLE_PIN = 8;
const int LIMIT_SWITCH_X = 9;  // سوئیچ محدودیت محور X
const int LIMIT_SWITCH_Y = 10; // سوئیچ محدودیت محور Y
const int EMERGENCY_STOP = 11; // توقف اضطراری

// تنظیمات موتور
const float STEPS_PER_MM = 80.0; // مراحل بر میلی‌متر (بسته به موتور و پولی)
const int MAX_SPEED = 1000;      // حداکثر سرعت (steps/sec)
const int MAX_ACCEL = 500;       // حداکثر شتاب (steps/sec^2)
const float TRAVEL_X = 200.0;    // محدوده حرکت X (mm)
const float TRAVEL_Y = 200.0;    // محدوده حرکت Y (mm)

// متغیرهای سیستم
bool motorsEnabled = false;
bool homingComplete = false;
float currentX = 0;
float currentY = 0;
float targetX = 0;
float targetY = 0;

enum MachineState {
  STATE_IDLE,
  STATE_HOMING,
  STATE_MOVING,
  STATE_EMERGENCY
};

MachineState currentState = STATE_IDLE;

void setup() {
  Serial.begin(115200);
  
  // تنظیم پایه‌ها
  pinMode(ENABLE_PIN, OUTPUT);
  pinMode(LIMIT_SWITCH_X, INPUT_PULLUP);
  pinMode(LIMIT_SWITCH_Y, INPUT_PULLUP);
  pinMode(EMERGENCY_STOP, INPUT_PULLUP);
  
  // غیرفعال کردن موتورها در ابتدا
  disableMotors();
  
  // تنظیمات موتورها
  setupSteppers();
  
  Serial.println("\n\n========================================");
  Serial.println("   CNC Stepper Control System");
  Serial.println("========================================");
  Serial.print("Steps per mm: ");
  Serial.println(STEPS_PER_MM);
  Serial.print("Travel X: ");
  Serial.print(TRAVEL_X);
  Serial.println(" mm");
  Serial.print("Travel Y: ");
  Serial.print(TRAVEL_Y);
  Serial.println(" mm");
  Serial.println("\nCommands:");
  Serial.println("  HOME    - Home both axes");
  Serial.println("  ENABLE  - Enable motors");
  Serial.println("  DISABLE - Disable motors");
  Serial.println("  G0 X Y  - Rapid move to position");
  Serial.println("  G1 X Y F - Linear move with feedrate");
  Serial.println("  POS     - Show current position");
  Serial.println("  STATUS  - Show system status");
  Serial.println("  ?       - Show help");
  Serial.println("----------------------------------------");
}

void loop() {
  // خواندن دستورات سریال
  checkSerialCommands();
  
  // بررسی توقف اضطراری
  checkEmergencyStop();
  
  // بررسی سوئیچ‌های محدودیت
  checkLimitSwitches();
  
  // اجرای منطق بر اساس حالت
  switch (currentState) {
    case STATE_IDLE:
      idleState();
      break;
      
    case STATE_HOMING:
      homingState();
      break;
      
    case STATE_MOVING:
      movingState();
      break;
      
    case STATE_EMERGENCY:
      emergencyState();
      break;
  }
  
  // اجرای موتورها
  stepper1.run();
  stepper2.run();
  
  delay(1);
}

void setupSteppers() {
  // تنظیمات موتور 1 (محور X)
  stepper1.setMaxSpeed(MAX_SPEED);
  stepper1.setAcceleration(MAX_ACCEL);
  stepper1.setEnablePin(ENABLE_PIN);
  stepper1.setPinsInverted(false, false, true); // DIR, STEP, ENABLE
  
  // تنظیمات موتور 2 (محور Y)
  stepper2.setMaxSpeed(MAX_SPEED);
  stepper2.setAcceleration(MAX_ACCEL);
  stepper2.setPinsInverted(false, false, true);
}

void enableMotors() {
  if (!motorsEnabled) {
    digitalWrite(ENABLE_PIN, LOW);
    motorsEnabled = true;
    Serial.println("Motors ENABLED");
  }
}

void disableMotors() {
  if (motorsEnabled) {
    digitalWrite(ENABLE_PIN, HIGH);
    motorsEnabled = false;
    Serial.println("Motors DISABLED");
  }
}

void checkSerialCommands() {
  if (Serial.available()) {
    String command = Serial.readStringUntil('\n');
    command.trim();
    command.toUpperCase();
    
    processGCode(command);
  }
}

void processGCode(String gcode) {
  if (gcode == "HOME") {
    startHoming();
  }
  else if (gcode == "ENABLE") {
    enableMotors();
  }
  else if (gcode == "DISABLE") {
    disableMotors();
  }
  else if (gcode == "POS") {
    showPosition();
  }
  else if (gcode == "STATUS") {
    showStatus();
  }
  else if (gcode == "?") {
    showHelp();
  }
  else if (gcode.startsWith("G0")) {
    // حرکت سریع: G0 X100 Y50
    parseMoveCommand(gcode, true);
  }
  else if (gcode.startsWith("G1")) {
    // حرکت خطی: G1 X100 Y50 F500
    parseMoveCommand(gcode, false);
  }
  else if (gcode.startsWith("G28")) {
    // رفتن به home
    startHoming();
  }
  else if (gcode.startsWith("M84")) {
    // غیرفعال کردن موتورها
    disableMotors();
  }
  else if (gcode.startsWith("M17")) {
    // فعال کردن موتورها
    enableMotors();
  }
  else {
    Serial.print("Unknown command: ");
    Serial.println(gcode);
  }
}

void parseMoveCommand(String gcode, bool rapidMove) {
  // تجزیه دستور حرکت
  float x = currentX;
  float y = currentY;
  float f = MAX_SPEED / STEPS_PER_MM; // سرعت پیش‌فرض mm/sec
  
  // پیدا کردن مقادیر X و Y و F
  int xIndex = gcode.indexOf('X');
  int yIndex = gcode.indexOf('Y');
  int fIndex = gcode.indexOf('F');
  
  if (xIndex != -1) {
    String xStr = gcode.substring(xIndex + 1);
    // حذف هر چیزی بعد از عدد
    xStr = splitValue(xStr);
    x = xStr.toFloat();
  }
  
  if (yIndex != -1) {
    String yStr = gcode.substring(yIndex + 1);
    yStr = splitValue(yStr);
    y = yStr.toFloat();
  }
  
  if (fIndex != -1) {
    String fStr = gcode.substring(fIndex + 1);
    fStr = splitValue(fStr);
    f = fStr.toFloat();
  }
  
  // بررسی محدوده
  if (x < 0 || x > TRAVEL_X || y < 0 || y > TRAVEL_Y) {
    Serial.println("ERROR: Target position out of range");
    return;
  }
  
  // حرکت به موقعیت هدف
  moveToPosition(x, y, f, rapidMove);
}

String splitValue(String str) {
  // جدا کردن مقدار عددی از رشته
  for (int i = 0; i < str.length(); i++) {
    if (!isdigit(str.charAt(i)) && str.charAt(i) != '.' && str.charAt(i) != '-') {
      return str.substring(0, i);
    }
  }
  return str;
}

void startHoming() {
  if (currentState == STATE_IDLE) {
    Serial.println("Starting homing sequence...");
    currentState = STATE_HOMING;
    homingComplete = false;
    enableMotors();
    
    // تنظیم سرعت کم برای homing
    stepper1.setMaxSpeed(200);
    stepper2.setMaxSpeed(200);
    stepper1.setAcceleration(200);
    stepper2.setAcceleration(200);
    
    // حرکت به سمت سوئیچ‌های محدودیت
    stepper1.moveTo(-10000); // حرکت به سمت منفی
    stepper2.moveTo(-10000);
  }
}

void homingState() {
  // بررسی برخورد با سوئیچ‌ها
  bool xHomed = (digitalRead(LIMIT_SWITCH_X) == LOW);
  bool yHomed = (digitalRead(LIMIT_SWITCH_Y) == LOW);
  
  // توقف موتور وقتی سوئیچ فشرده شد
  if (xHomed && stepper1.isRunning()) {
    stepper1.stop();
    stepper1.setCurrentPosition(0);
    Serial.println("X axis homed");
  }
  
  if (yHomed && stepper2.isRunning()) {
    stepper2.stop();
    stepper2.setCurrentPosition(0);
    Serial.println("Y axis homed");
  }
  
  // اگر هر دو محور هوم شدند
  if (xHomed && yHomed && !homingComplete) {
    // حرکت کمی به عقب برای آزاد کردن سوئیچ‌ها
    stepper1.moveTo(10);
    stepper2.moveTo(10);
    
    // انتظار برای حرکت
    delay(500);
    
    // تنظیم موقعیت صفر
    stepper1.setCurrentPosition(0);
    stepper2.setCurrentPosition(0);
    currentX = 0;
    currentY = 0;
    
    // بازگرداندن سرعت‌ها به حالت عادی
    stepper1.setMaxSpeed(MAX_SPEED);
    stepper2.setMaxSpeed(MAX_SPEED);
    stepper1.setAcceleration(MAX_ACCEL);
    stepper2.setAcceleration(MAX_ACCEL);
    
    homingComplete = true;
    currentState = STATE_IDLE;
    
    Serial.println("Homing complete!");
    Serial.println("All axes at zero position");
  }
}

void moveToPosition(float x, float y, float feedrate, bool rapid) {
  if (!homingComplete) {
    Serial.println("ERROR: Please home axes first");
    return;
  }
  
  // تبدیل میلی‌متر به استپ
  long xSteps = x * STEPS_PER_MM;
  long ySteps = y * STEPS_PER_MM;
  
  // تنظیم سرعت
  float speed = feedrate * STEPS_PER_MM; // تبدیل به steps/sec
  if (rapid) {
    speed = MAX_SPEED; // حداکثر سرعت برای حرکت سریع
  }
  
  stepper1.setMaxSpeed(speed);
  stepper2.setMaxSpeed(speed);
  
  // حرکت به موقعیت
  stepper1.moveTo(xSteps);
  stepper2.moveTo(ySteps);
  
  targetX = x;
  targetY = y;
  currentState = STATE_MOVING;
  
  Serial.print("Moving to: X");
  Serial.print(x, 1);
  Serial.print(" Y");
  Serial.print(y, 1);
  Serial.print(" at ");
  Serial.print(feedrate);
  Serial.println(" mm/sec");
}

void movingState() {
  // بررسی رسیدن به موقعیت
  if (!stepper1.isRunning() && !stepper2.isRunning()) {
    // به‌روزرسانی موقعیت فعلی
    currentX = stepper1.currentPosition() / STEPS_PER_MM;
    currentY = stepper2.currentPosition() / STEPS_PER_MM;
    
    currentState = STATE_IDLE;
    
    Serial.print("Move complete. Current position: X");
    Serial.print(currentX, 1);
    Serial.print(" Y");
    Serial.println(currentY, 1);
  }
}

void idleState() {
  // حالت آماده‌باش
  // می‌توانید عملیات پس‌زمینه را اینجا انجام دهید
}

void checkEmergencyStop() {
  if (digitalRead(EMERGENCY_STOP) == LOW) {
    emergencyStop();
  }
}

void emergencyStop() {
  stepper1.stop();
  stepper2.stop();
  disableMotors();
  currentState = STATE_EMERGENCY;
  
  Serial.println("!!! EMERGENCY STOP !!!");
  Serial.println("System halted. Reset required.");
}

void emergencyState() {
  // حالت توقف اضطراری
  // فقط منتظر ریست شدن سیستم
  digitalWrite(ENABLE_PIN, HIGH);
  
  // چشمک زدن LED یا بوق هشدار
  static unsigned long lastBlink = 0;
  static bool blinkState = false;
  
  if (millis() - lastBlink > 500) {
    blinkState = !blinkState;
    // digitalWrite(LED_BUILTIN, blinkState);
    lastBlink = millis();
  }
}

void checkLimitSwitches() {
  // اگر در حال حرکت هستیم و سوئیچ فشرده شد، توقف اضطراری
  if (currentState == STATE_MOVING || currentState == STATE_HOMING) {
    if (digitalRead(LIMIT_SWITCH_X) == LOW && !homingComplete) {
      Serial.println("X limit switch triggered!");
      stepper1.stop();
    }
    
    if (digitalRead(LIMIT_SWITCH_Y) == LOW && !homingComplete) {
      Serial.println("Y limit switch triggered!");
      stepper2.stop();
    }
  }
}

void showPosition() {
  Serial.print("Current position: X");
  Serial.print(currentX, 2);
  Serial.print("mm Y");
  Serial.print(currentY, 2);
  Serial.println("mm");
  
  Serial.print("Motor steps: X");
  Serial.print(stepper1.currentPosition());
  Serial.print(" Y");
  Serial.println(stepper2.currentPosition());
}

void showStatus() {
  Serial.println("\n=== SYSTEM STATUS ===");
  Serial.print("State: ");
  switch (currentState) {
    case STATE_IDLE: Serial.println("IDLE"); break;
    case STATE_HOMING: Serial.println("HOMING"); break;
    case STATE_MOVING: Serial.println("MOVING"); break;
    case STATE_EMERGENCY: Serial.println("EMERGENCY STOP"); break;
  }
  
  Serial.print("Motors: ");
  Serial.println(motorsEnabled ? "ENABLED" : "DISABLED");
  
  Serial.print("Homing: ");
  Serial.println(homingComplete ? "COMPLETE" : "NOT HOMED");
  
  Serial.print("Position: X");
  Serial.print(currentX, 1);
  Serial.print("mm Y");
  Serial.print(currentY, 1);
  Serial.println("mm");
  
  Serial.print("Limit switches: X=");
  Serial.print(digitalRead(LIMIT_SWITCH_X) ? "OPEN" : "TRIGGERED");
  Serial.print(" Y=");
  Serial.println(digitalRead(LIMIT_SWITCH_Y) ? "OPEN" : "TRIGGERED");
  
  Serial.print("Emergency stop: ");
  Serial.println(digitalRead(EMERGENCY_STOP) ? "READY" : "TRIGGERED");
  
  Serial.println("===================\n");
}

void showHelp() {
  Serial.println("\n=== CNC Control System Help ===");
  Serial.println("G-Code Commands:");
  Serial.println("  G0 X[pos] Y[pos]     - Rapid move (maximum speed)");
  Serial.println("  G1 X[pos] Y[pos] F[feedrate] - Linear move");
  Serial.println("  G28                  - Home all axes");
  Serial.println("  M84                  - Disable steppers");
  Serial.println("  M17                  - Enable steppers");
  Serial.println("\nSystem Commands:");
  Serial.println("  HOME    - Home both axes");
  Serial.println("  ENABLE  - Enable motors");
  Serial.println("  DISABLE - Disable motors");
  Serial.println("  POS     - Show current position");
  Serial.println("  STATUS  - Show system status");
  Serial.println("  ?       - Show this help");
  Serial.println("\nExamples:");
  Serial.println("  G0 X100 Y50          - Move to X100 Y50 rapidly");
  Serial.println("  G1 X50 Y75 F300      - Move to X50 Y75 at 300mm/sec");
  Serial.println("==============================\n");
}

کد تنظیم جریان موتور

/*
 * تنظیم جریان موتور برای A4988/DRV8825
 * مهم: تنظیم نادرست جریان می‌تواند به موتور آسیب بزند!
 */

// فرمول محاسبه جریان:
// Vref = I_max * 8 * R_sense
// A4988: R_sense = 0.05Ω
// DRV8825: R_sense = 0.1Ω

const int MOTOR_CURRENT_POT = A0; // پتانسیومتر تنظیم جریان
const int TEST_BUTTON = 2;        // دکمه تست
const int MOTOR_ENABLE = 8;
const int MOTOR_STEP = 5;
const int MOTOR_DIR = 6;

// تنظیمات موتور
const float RSENSE = 0.1; // اهم (برای DRV8825)
const float MAX_CURRENT = 1.5; // آمپر (برچسب موتور را بررسی کنید)
float targetCurrent = 0.5; // جریان هدف (آمپر)

void setup() {
  Serial.begin(9600);
  
  pinMode(MOTOR_ENABLE, OUTPUT);
  pinMode(MOTOR_STEP, OUTPUT);
  pinMode(MOTOR_DIR, OUTPUT);
  pinMode(TEST_BUTTON, INPUT_PULLUP);
  
  digitalWrite(MOTOR_ENABLE, HIGH); // غیرفعال در ابتدا
  
  Serial.println("\n\n========================================");
  Serial.println("   Stepper Motor Current Calibration");
  Serial.println("========================================");
  Serial.println("WARNING: Adjust current slowly!");
  Serial.println("Too high current can damage motor/driver.");
  Serial.println();
  Serial.print("R_sense: ");
  Serial.print(RSENSE);
  Serial.println(" Ω");
  Serial.print("Max motor current: ");
  Serial.print(MAX_CURRENT);
  Serial.println(" A");
  Serial.println();
  Serial.println("Turn potentiometer to adjust current.");
  Serial.println("Press button to test motor.");
  Serial.println("----------------------------------------");
}

void loop() {
  // خواندن پتانسیومتر
  int potValue = analogRead(MOTOR_CURRENT_POT);
  
  // تبدیل به جریان (0 تا MAX_CURRENT)
  targetCurrent = (potValue / 1023.0) * MAX_CURRENT;
  
  // محاسبه Vref مورد نیاز
  float vref = targetCurrent * 8.0 * RSENSE;
  
  // نمایش وضعیت
  static unsigned long lastDisplay = 0;
  if (millis() - lastDisplay > 500) {
    Serial.print("Current: ");
    Serial.print(targetCurrent, 2);
    Serial.print("A | Vref: ");
    Serial.print(vref, 3);
    Serial.print("V | Pot: ");
    Serial.print(potValue);
    
    // نمایش پیشنهاد
    Serial.print(" | Suggestion: ");
    if (targetCurrent < MAX_CURRENT * 0.3) {
      Serial.println("TOO LOW - Motor may skip steps");
    } else if (targetCurrent < MAX_CURRENT * 0.7) {
      Serial.println("GOOD - Normal operation");
    } else if (targetCurrent < MAX_CURRENT * 0.9) {
      Serial.println("HIGH - Good for high torque");
    } else {
      Serial.println("MAX - Use with caution!");
    }
    
    lastDisplay = millis();
  }
  
  // تست موتور با دکمه
  if (digitalRead(TEST_BUTTON) == LOW) {
    testMotor();
    delay(300); // Debouncing
  }
  
  // نکته: در این کد Vref به صورت نرم‌افزاری محاسبه می‌شود
  // در عمل باید پتانسیومتر روی درایور را تنظیم کنید
  
  delay(10);
}

void testMotor() {
  Serial.println("\n--- Motor Test ---");
  Serial.print("Testing at ");
  Serial.print(targetCurrent, 2);
  Serial.println("A");
  
  // فعال کردن موتور
  digitalWrite(MOTOR_ENABLE, LOW);
  
  // حرکت کوچک به جلو
  digitalWrite(MOTOR_DIR, HIGH);
  for (int i = 0; i < 100; i++) {
    digitalWrite(MOTOR_STEP, HIGH);
    delayMicroseconds(500);
    digitalWrite(MOTOR_STEP, LOW);
    delayMicroseconds(500);
  }
  
  // حرکت کوچک به عقب
  digitalWrite(MOTOR_DIR, LOW);
  for (int i = 0; i < 100; i++) {
    digitalWrite(MOTOR_STEP, HIGH);
    delayMicroseconds(500);
    digitalWrite(MOTOR_STEP, LOW);
    delayMicroseconds(500);
  }
  
  // غیرفعال کردن موتور
  digitalWrite(MOTOR_ENABLE, HIGH);
  
  // بررسی عملکرد
  Serial.println("Test complete. Check motor behavior:");
  Serial.println("- Smooth movement: Good current");
  Serial.println("- Jerky/skipping: Current too low");
  Serial.println("- Overheating: Current too high");
  Serial.println("--- End Test ---\n");
}

// تابع برای تنظیم دستی Vref با مولتی‌متر
void manualCalibrationGuide() {
  Serial.println("\n=== Manual Calibration Guide ===");
  Serial.println("1. Connect multimeter to Vref pin on driver");
  Serial.println("2. Adjust potentiometer on driver board");
  Serial.println("3. Measure and set Vref according to formula:");
  Serial.println("   Vref = I_max × 8 × R_sense");
  Serial.println();
  Serial.println("Example calculations:");
  Serial.println("For 1A current with DRV8825 (R_sense=0.1Ω):");
  Serial.println("   Vref = 1.0 × 8 × 0.1 = 0.8V");
  Serial.println();
  Serial.println("For 1.5A current with A4988 (R_sense=0.05Ω):");
  Serial.println("   Vref = 1.5 × 8 × 0.05 = 0.6V");
  Serial.println("===============================\n");
}

نکات حیاتی نصب و استفاده

تنظیم جریان صحیح:

  1. محاسبه Vref:

    Vref = جریان_موردنیاز × 8 × R_sense
    
    مثال برای موتور 1.2A با DRV8825:
    Vref = 1.2 × 8 × 0.1 = 0.96V
  2. روش تنظیم:

    • مولتی‌متر را روی ولتاژ DC تنظیم کنید

    • پراب مثبت به پین Vref درایور

    • پراب منفی به GND درایور

    • پتانسیومتر را تا رسیدن به ولتاژ محاسبه‌شده بچرخانید

خنک‌کاری ضروری:

// مانیتور دمای درایور
void monitorTemperature() {
  // A4988: Shutdown at 150°C, Thermal hysteresis 25°C
  // DRV8825: Shutdown at 165°C
  
  // علائم گرمای بیش از حد:
  // 1. کاهش گشتاور
  // 2. توقف ناگهانی
  // 3. بوی سوختگی
  
  // راه‌حل‌ها:
  // 1. اضافه کردن هیت‌سینک بزرگتر
  // 2. استفاده از فن 5V یا 12V
  // 3. کاهش جریان موتور
  // 4. افزایش زمان خاموش بودن
}

اتصالات صحیح:

مشکلعلتراه‌حل
موتور حرکت نمی‌کنداتصال نادرست فازهاسیم‌های یک فاز را جابجا کنید
موتور داغ می‌شودجریان بیش از حدکاهش Vref
درایور داغ می‌شودعدم خنک‌کاریاضافه کردن هیت‌سینک و فن
حرکت ناصافمیکرواستپ نادرستتنظیم صحیح MS1, MS2, MS3
نویز در سیستمسیم‌کندی ضعیفاستفاده از کانکتورهای مناسب

کاهش نویز و EMI:

  1. خازن‌های بای‌پس:

    • 100µF الکترولیتی نزدیک ورودی VMOT

    • 0.1µF سرامیکی بین هر VMOT و GND

  2. سیم‌کندی:

    • استفاده از کابل به هم تابیده برای موتور

    • جدا کردن سیم‌های سیگنال از سیم‌های قدرت

    • اتصال زمین صحیح

  3. شیلدینگ:

    • محفظه فلزی برای درایور

    • فریت‌بید روی کابل موتور


پروژه‌های پیشنهادی

1. پرینتر 3 بعدی DIY

// کنترل 3 محور X, Y, Z با اکستروژر

2. دستگاه CNC کوچک

// کنترل محورهای X, Y برای حکاکی

3. ربات پلوتار

// کنترل 4 موتور برای حرکت ربات

4. اسکنر 3 بعدی

// کنترل موتور برای چرخش قطعه

5. تلسکوپ ردیاب ستاره‌ها

// کنترل دقیق موتور برای ردیابی اجرام آسمانی

جدول انتخاب موتور مناسب

کاربردنوع موتورجریانمیکرواستپنکات
پرینتر 3 بعدیNEMA 171.2-1.5A1/16 یا 1/32دقت بالا، نویز کم
CNC کوچکNEMA 171.5-1.8A1/8 یا 1/16گشتاور متوسط
رباتیکNEMA 140.8-1.2A1/8سبک، کم مصرف
صنعتی سبکNEMA 232.0-2.5A1/4گشتاور بالا
میکرو موقعیت‌یابیNEMA 80.5-0.8A1/32دقت بسیار بالا

پکیج خرید

پکیج پایه:

  • 1x شیلد درایور موتور پله‌ای

  • 2x درایور A4988 با هیت‌سینک

  • 1x موتور پله‌ای NEMA 17

  • 1x آداپتور 12V/2A

  • کابل اتصال موتور

  • پیچ و مهره نصب

پکیج پرینتر 3 بعدی:

  • 1x شیلد درایور

  • 4x درایور DRV8825 با فن خنک‌کننده

  • 4x موتور NEMA 17

  • 1x منبع تغذیه 24V/10A

  • 1x کیت CNC shield

  • 1x مجموعه ابزار تنظیم

پکیج توسعه‌دهنده:

  • 1x شیلد درایور

  • 2x A4988 + 2x DRV8825

  • 4x موتور مختلف (NEMA 8, 14, 17, 23)

  • 1x کیت تست جریان و دما

  • 1x مولتی‌متر دیجیتال

  • کتابچه 20 پروژه عملی


گارانتی و پشتیبانی

  • پشتیبانی فنی: رایگان از طریق واتس‌اپ
  • آموزش: ویدیوهای تنظیم جریان و میکرواستپ

  • کتابخانه: دسترسی به آخرین نسخه AccelStepper

  • جامعه: گروه کاربران موتور پله‌ای


سؤالات متداول

Q1: تفاوت A4988 و DRV8825 چیست؟
A4988 ارزان‌تر و برای کاربردهای عمومی. DRV8825 با میکرواستپ 1/32 و ولتاژ بالاتر برای دقت بیشتر.

Q2: چرا موتور من داغ می‌شود؟
جریان بیش از حد تنظیم شده. Vref را کاهش دهید یا از خنک‌کننده استفاده کنید.

Q3: میکرواستپ چیست و کدام بهتر است؟
تقسیم هر استپ به بخش‌های کوچک‌تر برای حرکت نرم‌تر. 1/16 تعادل خوبی بین دقت و گشتاور دارد.

Q4: حداکثر سرعت چقدر است؟
حدود 2000-3000 استپ بر ثانیه بسته به موتور و ولتاژ.

Q5: چگونه از سوختن درایور جلوگیری کنم؟

  1. جریان صحیح تنظیم شود

  2. خنک‌کننده مناسب

  3. اتصال کوتاه نشود

  4. ولتاژ ورودی از حد مجاز بیشتر نباشد


هشدار: تنظیم نادرست جریان می‌تواند به موتور و درایور آسیب جدی بزند. همیشه با کمترین جریان شروع کنید و به تدریج افزایش دهید. برای کاربردهای حساس با مهندسین ما مشورت کنید.

توضیحات تکمیلی
ابعاد 2 × 2 × 2 سانتیمتر
ساختار محصول تعیین نوع محصول فیزیکی و مجازی ( شامل نقشه ی شماتیک، مدار چاپی و .. بصورت دانلودی )

لایه های مدارچاپی

نوع مدار

کشور سازنده

نظرات (0)
0 بررسی
0
0
0
0
0

هیچ دیدگاهی برای این محصول نوشته نشده است.

.فقط مشتریانی که این محصول را خریداری کرده اند و وارد سیستم شده اند میتوانند برای این محصول دیدگاه ارسال کنند.

حمل و نقل و تحویل

در تهران فقط

پیک موتوری

تحویل حضوری

روشهای ارسال تهران و شهرستان ها

اداره پست جمهوری اسلامی ایران

پست سفارشی، پیشتاز، بین‌المللی، تیپاکس و پست پیشتاز خارج از کشور

در حال حاضر امکان رهگیری مرسوله های پستی با کد مرسوله، دریافت گواهی کد پستی، مشاهده تعرفه های پستی به صورت آنلاین و ... در سایت شرکت ملی پست جمهوری اسلامی ایران فراهم شده است. تمامی مردم می توانند با ورود به این سایت، از خدمات مربوط به شرکت و اداره پست استفاده کنند.

در اداره پست جمهوری اسلامی ایران، برای ارسال مرسولات، روش‌های مختلفی وجود دارد که عبارتند از:

۱. پست سفارشی: این روش برای ارسال کالاهای کوچک و سبک و با ارزش کمتر از ۱۰۰ هزار تومان استفاده می‌شود. در این روش، هزینه ارسال بر اساس وزن و مسافت محاسبه می‌شود و زمان تحویل ۳ تا ۷ روز کاری است.

۲. پیشتاز: این روش برای ارسال کالاهایی با ارزش بیشتر از ۱۰۰ هزار تومان و یا کالاهایی که به سرعت باید تحویل داده شوند، استفاده می‌شود. در این روش، هزینه ارسال بر اساس وزن و مسافت محاسبه می‌شود و زمان تحویل ۱ تا ۳ روز کاری است.

۳. بین‌المللی: این روش برای ارسال کالاهایی به خارج از کشور استفاده می‌شود. در این روش، هزینه ارسال بر اساس وزن و مسافت و هزینه گمرکی محاسبه می‌شود و زمان تحویل بسته به مقصد و روش ارسال، متفاوت است.

۴. تیپاکس: این روش برای ارسال کالاهایی است که به سرعت باید تحویل داده شوند. در این روش، هزینه ارسال بر اساس وزن و مسافت و زمان تحویل مورد نظر مشتری محاسبه می‌شود.

۵. پست پیشتاز خارج از کشور: این روش برای ارسال کالاها به خارج از کشور استفاده می‌شود و هزینه ارسال بر اساس وزن و مسافت و هزینه گمرکی محاسبه می‌شود.

در کل، برای ارسال مرسوله در اداره پست جمهوری اسلامی ایران، می‌توانید یکی از روش‌های فوق را انتخاب کنید که بسته به نیاز و شرایط شما، مناسب‌تر است.