পাঠ ৩৮ · ৫৭-এর মধ্যে · মডিউল ৯
Home / Courses / Microprocessors, Embedded Systems & IoT / মোটর কন্ট্রোল

DC ও সার্ভো মোটর কন্ট্রোল

DC and servo motor control
৯ মিনিট পড়া মধ্যম · Intermediate Python সিমুলেশনসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • PWM ডিউটি সাইকেল থেকে DC মোটরের আনুমানিক গতি কীভাবে গণনা করা হয় (এবং কেন এটি একটি সিমপ্লিফিকেশন)
  • H-ব্রিজ কীভাবে দিক নিয়ন্ত্রণ করে (ধারণাগতভাবে)
  • সার্ভো মোটরের পালস-উইথ কনভেনশন এবং অ্যাঙ্গেল-থেকে-পালস ও পালস-থেকে-অ্যাঙ্গেল রূপান্তর সূত্র
  • PWM (L19) ও ক্যালিব্রেশন (L37)-এর সাথে এই ধারণার সম্পর্ক

১ · DC মোটর — PWM দিয়ে গতি নিয়ন্ত্রণ

একটি DC মোটরে ক্রমাগত পূর্ণ ভোল্টেজ না দিয়ে, L19-এ শেখা PWM (Pulse Width Modulation) সিগন্যাল দেওয়া হয় — দ্রুত ON/OFF টগল করে মোটরের কার্যকর গড় ভোল্টেজ নিয়ন্ত্রণ করা হয়। ডিউটি সাইকেল যত বেশি (সিগন্যাল যত বেশি সময় HIGH থাকে), গড় ভোল্টেজ তত বেশি, মোটরও তত জোরে ঘোরে। বাস্তবে motor speed-এর সাথে duty cycle-এর সম্পর্ক পুরোপুরি লিনিয়ার নয় (লোড, ব্যাক-EMF, ফ্রিকশনের প্রভাব থাকে), তবে এই পাঠে আমরা একটি সরলীকৃত (কিন্তু স্পষ্টভাবে লেবেল করা) অনুমান ব্যবহার করছি:

$$ \text{speed}_{\text{rpm}} \approx \frac{\text{duty}_{\%}}{100} \times \text{speed}_{\text{max\_rpm}} $$

অর্থাৎ ডিউটি সাইকেলের শতাংশ অনুপাতে মোটরের সর্বোচ্চ রেটেড গতির একটি অংশ পাওয়া যায় — এটি একটি বাস্তবসম্মত প্রথম-অনুমান (first-order approximation), নিখুঁত পদার্থবিজ্ঞান মডেল নয়।

২ · দিক নিয়ন্ত্রণ — H-ব্রিজ

একটি DC মোটর ঘোরার দিক তখনই বদলায় যখন তার দুই টার্মিনালের মধ্য দিয়ে কারেন্টের দিক উল্টে দেওয়া হয়। একটি মাইক্রোকন্ট্রোলারের GPIO পিন সরাসরি এই কারেন্ট উল্টাতে পারে না (এবং মোটরের কারেন্ড ড্রাইভও করতে পারে না — L16-এর মতো একটি ড্রাইভার সার্কিট লাগে) — এর জন্য ব্যবহৃত হয় একটি H-ব্রিজ সার্কিট: চারটি সুইচ (সাধারণত MOSFET) H-আকৃতিতে সাজানো, যেখানে নির্দিষ্ট জোড়া সুইচ ON করলে কারেন্ট একদিকে যায়, বিপরীত জোড়া ON করলে উল্টো দিকে যায়। এই কোর্সে বাস্তব সার্কিট চালানো সম্ভব নয় (CLAUDE.md), তাই আমরা এটিকে একটি সরল লজিক টেবিল হিসেবে সিমুলেট করব — নিচের কোড সেলে দেখুন।

PWM ডিউটি + দিক সিগন্যাল (GPIO) H-ব্রিজ (৪-সুইচ কারেন্ট রুটিং) DC মোটর (গতি + দিক) ঘূর্ণন (RPM, CW/CCW)
H-ব্রিজ PWM ডিউটি (গতির জন্য) ও একটি দিক সিগন্যাল উভয়ই নিয়ে DC মোটরের প্রকৃত ঘূর্ণন নিয়ন্ত্রণ করে।

৩ · সার্ভো মোটর — পালস-উইথ কনভেনশন

সার্ভো মোটর সম্পূর্ণ ভিন্নভাবে কাজ করে — এটি ডিউটি সাইকেল অনুযায়ী গতি বাড়ায় না, বরং একটি নির্দিষ্ট পালস-উইথের ভিত্তিতে একটি নির্দিষ্ট অ্যাঙ্গেলে স্থির হয়ে থাকে। সবচেয়ে প্রচলিত কনভেনশন: প্রতি ~20ms পিরিয়ডে একটি পালস পাঠানো হয়, যার প্রস্থ (pulse width) সাধারণত ~1ms থেকে ~2ms এর মধ্যে থাকে — 1ms মানে 0° (এক প্রান্ত), 2ms মানে 180° (অন্য প্রান্ত), এবং মাঝখানে লিনিয়ারলি ইন্টারপোলেট হয় (L37-এর ২-পয়েন্ট ক্যালিব্রেশনের মতোই একটি লিনিয়ার ম্যাপিং, শুধু ভিন্ন প্রেক্ষাপটে):

$$ \text{angle}_{\text{deg}} = \frac{\text{pulse}_{\text{ms}} - 1.0}{2.0 - 1.0} \times 180 $$

এবং এর উল্টোটাও দরকারি হয় — একটি টার্গেট অ্যাঙ্গেলের জন্য কত পালস-উইথ পাঠাতে হবে তা বের করা:

$$ \text{pulse}_{\text{ms}} = 1.0 + \frac{\text{angle}_{\text{deg}}}{180} \times (2.0 - 1.0) $$
Python
# --- DC মোটর: PWM ডিউটি -> সিমুলেটেড গতি (সরলীকৃত, স্পষ্টভাবে লেবেল করা) ---
RATED_MAX_RPM = 3000   # এই মোটরের সর্বোচ্চ রেটেড গতি (illustrative)

def duty_to_speed_rpm(duty_pct):
    duty_pct = max(0, min(100, duty_pct))   # ডিউটি ০-১০০%-এর মধ্যে ক্ল্যাম্প করা
    # সিমপ্লিফিকেশন: গতি প্রায় ডিউটির সমানুপাতিক (বাস্তবে লোড/ব্যাক-EMF-এর প্রভাব উপেক্ষা করা হচ্ছে)
    return (duty_pct / 100) * RATED_MAX_RPM

print("DC মোটর -- PWM ডিউটি সাইকেল বনাম সিমুলেটেড গতি:")
for duty in [0, 25, 50, 75, 100]:
    print(f"  duty = {duty:3d}%\t-> speed ≈ {duty_to_speed_rpm(duty):.0f} RPM")

# --- H-ব্রিজ: দিক সিগন্যাল -> সুইচ প্যাটার্ন (সরল লজিক টেবিল সিমুলেশন) ---
def hbridge_direction(direction):
    # (IN1, IN2) সুইচ স্টেট -- সরলীকৃত মডেল
    table = {
        "forward": (1, 0),
        "reverse": (0, 1),
        "stop":    (0, 0),
    }
    return table[direction]

print("\nH-ব্রিজ -- দিক নির্দেশ বনাম (IN1, IN2) সুইচ স্টেট:")
for d in ["forward", "reverse", "stop"]:
    in1, in2 = hbridge_direction(d)
    print(f"  {d:8s}\t-> IN1={in1}, IN2={in2}")

# --- সার্ভো মোটর: পালস-উইথ <-> অ্যাঙ্গেল (স্ট্যান্ডার্ড ~1-2ms / ~20ms পিরিয়ড কনভেনশন) ---
PULSE_MIN_MS = 1.0
PULSE_MAX_MS = 2.0
PERIOD_MS = 20.0
ANGLE_MIN = 0
ANGLE_MAX = 180

def pulse_to_angle(pulse_ms):
    return (pulse_ms - PULSE_MIN_MS) / (PULSE_MAX_MS - PULSE_MIN_MS) * (ANGLE_MAX - ANGLE_MIN) + ANGLE_MIN

def angle_to_pulse(angle_deg):
    return PULSE_MIN_MS + (angle_deg - ANGLE_MIN) / (ANGLE_MAX - ANGLE_MIN) * (PULSE_MAX_MS - PULSE_MIN_MS)

print("\nসার্ভো মোটর -- পালস-উইথ -> অ্যাঙ্গেল:")
for p in [1.0, 1.25, 1.5, 1.75, 2.0]:
    print(f"  pulse = {p:.2f} ms\t-> angle = {pulse_to_angle(p):.1f}°"
          f"\t(PWM ডিউটি = {p / PERIOD_MS * 100:.2f}% @ {PERIOD_MS:.0f}ms পিরিয়ড)")

print("\nসার্ভো মোটর -- টার্গেট অ্যাঙ্গেল -> প্রয়োজনীয় পালস-উইথ (রিভার্স ম্যাপিং, রাউন্ড-ট্রিপ যাচাই):")
for angle in [0, 45, 90, 135, 180]:
    pw = angle_to_pulse(angle)
    back = pulse_to_angle(pw)
    print(f"  target = {angle:3d}°\t-> pulse = {pw:.3f} ms\t-> ফিরিয়ে গণনা করলে angle = {back:.1f}°")

    
লক্ষ্য করুন সার্ভোর অংশে পালস-উইথ (1.0-2.0ms) সবসময় ২০ms পিরিয়ডের তুলনায় খুবই কম সময় HIGH থাকে (ডিউটি সাইকেল মাত্র ~৫-১০%) — কিন্তু এখানে PWM ডিউটি নয়, বরং পালসের প্রস্থ-ই তথ্য বহন করছে, এটাই সার্ভো কন্ট্রোলের মূল পার্থক্য DC মোটরের PWM স্পিড-কন্ট্রোল থেকে। রিভার্স ম্যাপিং-এর শেষ কলামে দেখা যাচ্ছে অ্যাঙ্গেল -> পালস -> অ্যাঙ্গেল রাউন্ড-ট্রিপ করলে ঠিক আসল অ্যাঙ্গেলই ফিরে আসে, যা সূত্র দুটোর সামঞ্জস্য নিশ্চিত করে।
মূল কথা · Key takeaway

DC মোটরে PWM ডিউটি সাইকেল গতি নিয়ন্ত্রণ করে (একটি সরলীকৃত সমানুপাতিক মডেলে) আর H-ব্রিজ দিক নিয়ন্ত্রণ করে; সার্ভো মোটরে একই ~20ms পিরিয়ডের মধ্যে পালসের প্রস্থ (~1-2ms) একটি নির্দিষ্ট অ্যাঙ্গেল নির্দেশ করে। দুটোই L19-এর PWM ভিত্তির উপর দাঁড়িয়ে, কিন্তু ভিন্ন উপায়ে তথ্য এনকোড করে। পরের পাঠ (L39) স্টেপার মোটরের সম্পূর্ণ ভিন্ন, ধাপে-ধাপে (step-sequence) নিয়ন্ত্রণ পদ্ধতি কভার করবে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ উপরের কোড সেলে duty_to_speed_rpm(duty_pct)-এ কেন max(0, min(100, duty_pct)) দিয়ে ইনপুট ক্ল্যাম্প করা হয়েছে?

কারণ ডিউটি সাইকেল বাস্তবে সবসময় 0% থেকে 100%-এর মধ্যে থাকতে হয় (এর কম বা বেশি অর্থহীন — L19 দেখুন)। যদি কোনো ভুল ইনপুটে (যেমন 120%) এই ক্ল্যাম্পিং না থাকত, ফাংশনটি একটি ভুল, রেঞ্জের-বাইরের গতি মান ফেরত দিত — এই ধরনের ইনপুট-স্যানিটাইজেশন বাস্তব এমবেডেড ফার্মওয়্যারেও অত্যন্ত গুরুত্বপূর্ণ, কারণ একটি ভুল সেন্সর রিডিং বা নয়েজি ইনপুট থেকে ফাংশনকে রক্ষা করা দরকার।

প্র ০২ সার্ভো মোটরের ~20ms পিরিয়ড PWM-এর ফ্রিকোয়েন্সিতে রূপান্তর করলে তা প্রায় কত হার্টজ হবে, এবং এটি L19-এর LED ডিমিং-এর জন্য ব্যবহৃত সাধারণ PWM ফ্রিকোয়েন্সির (কয়েক kHz) তুলনায় কেমন?

$f = 1 / T = 1 / 0.020\text{s} = 50$ Hz — এটি LED ডিমিং-এর জন্য ব্যবহৃত সাধারণ কয়েক kHz PWM ফ্রিকোয়েন্সির তুলনায় অনেক কম। এর কারণ সার্ভোর অভ্যন্তরীণ কন্ট্রোল সার্কিট প্রতি পালসের প্রস্থ নির্ভুলভাবে পরিমাপ করতে সময় নেয় এবং যান্ত্রিক মোটরের প্রতিক্রিয়া সময়ও সীমিত — তাই খুব দ্রুত পালস পাঠালে সার্ভো ঠিকভাবে পালস-উইথ শনাক্ত করতে পারবে না।

প্র ০৩ কেন একটি DC মোটরকে সরাসরি একটি GPIO পিন থেকে চালানো যায় না, H-ব্রিজ বা ড্রাইভার সার্কিট লাগে কেন — এই প্রশ্নটি L16-এর কোন ধারণার সাথে সরাসরি সম্পর্কিত?

এটি L16-এ কভার করা GPIO-এর সীমিত সোর্স/সিংক কারেন্ট ক্ষমতার সাথে সরাসরি সম্পর্কিত — একটি GPIO পিন সাধারণত মাত্র কয়েক মিলিঅ্যাম্পিয়ার (~২০mA) কারেন্ট নিরাপদে দিতে পারে, কিন্তু একটি DC মোটর সাধারণত কয়েকশ মিলিঅ্যাম্পিয়ার থেকে কয়েক অ্যাম্পিয়ার কারেন্ট টানে — তাই সরাসরি সংযোগ GPIO পিনটিকে নষ্ট করে দেবে। H-ব্রিজ মূলত একটি ট্রানজিস্টর/MOSFET-ভিত্তিক ড্রাইভার যা GPIO-এর কম-কারেন্ট সিগন্যাল দিয়ে মোটরের উচ্চ-কারেন্ট পাথ সুইচ করে — L16-এর "ট্রানজিস্টর মধ্যস্থতাকারী" ধারণারই একটি বিশেষ (দ্বিমুখী) রূপ।

অনুশীলন

  1. চিন্তা করুন: উপরের কোড সেলে RATED_MAX_RPM-এর মান ৬০০০ (দ্বিগুণ) করলে duty = 50%-এ সিমুলেটেড গতি কত হবে বলে আপনার ধারণা?

    $\text{speed} = (50/100) \times 6000 = 3000$ RPM — অর্থাৎ বর্তমান আউটপুটের (1500 RPM) ঠিক দ্বিগুণ, কারণ সূত্রটি RATED_MAX_RPM-এর সাথে সরাসরি রৈখিকভাবে (linearly) সম্পর্কিত।

  2. পরীক্ষা করুন: উপরের কোড সেলে angle_to_pulse(90)-এর ফলাফল হাতে ক্যালকুলেটর দিয়ে সূত্র বসিয়ে যাচাই করুন, তারপর Run চেপে কোডের আউটপুটের সাথে মেলান।

    $\text{pulse} = 1.0 + (90/180) \times (2.0 - 1.0) = 1.0 + 0.5 = 1.5$ ms — এবং কোডের আউটপুটেও target = 90° সারিতে ঠিক pulse = 1.500 ms দেখা যাবে, যা হাতের গণনার সাথে হুবহু মিলে যায়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ মাইক্রোপ্রসেসর আর্কিটেকচার, এমবেডেড C, GPIO, টাইমার/PWM/ADC, সিরিয়াল প্রোটোকল, RTOS, সেন্সর/অ্যাকচুয়েটর, IoT আর্কিটেকচার, ওয়্যারলেস প্রোটোকল, MQTT/CoAP ও IoT সিকিউরিটি — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • Computer Architecture & Digital Logic কোর্স সহোদর কোর্স GPIO-এর সাধারণ ডিজিটাল-লজিক ভিত্তি সেই কোর্সের সাথে সম্পর্কিত এই কোর্সের L14-এ কভার করা হয়েছে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Design and Analysis of Algorithms ও আরও অনেক কোর্স — সব এক জায়গায়।
আগের পাঠ
সিগন্যাল কন্ডিশনিং ও ক্যালিব্রেশন