পাঠ ২০ · ৫৭-এর মধ্যে · মডিউল ৫
Home / Courses / Microprocessors, Embedded Systems & IoT / অ্যানালগ-টু-ডিজিটাল কনভার্সন (ADC)

অ্যানালগ-টু-ডিজিটাল কনভার্সন (ADC)

Analog-to-Digital Conversion (ADC)
১০ মিনিট পড়া মধ্যম · Intermediate Python সিমুলেশনসহ সম্পূর্ণ বাংলায়

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

  • ADC কী এবং কোয়ান্টাইজেশন কীভাবে কাজ করে
  • স্টেপ সাইজ, কোড ও কোয়ান্টাইজেশন এরর গণনার সূত্র
  • কয়েকটি বাস্তব অ্যানালগ ভোল্টেজকে সত্যিকারের কোডে রূপান্তর করে এরর গণনা
  • ৮-বিট, ১০-বিট ও ১২-বিট রেজোলিউশনে একই ইনপুটের এরর তুলনা করে রেজোলিউশনের প্রভাব যাচাই

১ · ADC কী এবং কেন লাগে

বাস্তব জগতের বেশিরভাগ সিগন্যাল — তাপমাত্রা, আলো, শব্দ, ভোল্টেজ — অ্যানালগ: এরা যেকোনো মান নিতে পারে, ধারাবাহিকভাবে বদলায়। কিন্তু মাইক্রোকন্ট্রোলারের CPU শুধু ডিজিটাল বাইনারি সংখ্যা নিয়ে কাজ করতে পারে। এই ফাঁক পূরণ করে ADCAnalog-to-Digital Converterএকটি পেরিফেরাল যা একটি অ্যানালগ ভোল্টেজকে পরিমাপ করে নিকটতম প্রতিনিধিত্বকারী ডিজিটাল সংখ্যায় (কোড) রূপান্তর করে। — একটি পেরিফেরাল যা একটি পিনে আসা অ্যানালগ ভোল্টেজ মেপে তার সবচেয়ে কাছাকাছি ডিজিটাল প্রতিনিধিত্ব (একটি $n$-বিট পূর্ণসংখ্যা কোড) বের করে দেয়।

অ্যানালগ ভোল্টেজ (Continuous, যেকোনো মান) ADC (কোয়ান্টাইজেশন) ডিজিটাল কোড (Discrete, n-bit)
ADC একটি অবিচ্ছিন্ন অ্যানালগ ভোল্টেজকে সসীম সংখ্যক ডিসক্রিট ধাপে (steps) ভাগ করে নিকটতম ধাপের কোড বের করে দেয়।

২ · কোয়ান্টাইজেশনের সূত্র

একটি $n$-বিট ADC মোট $2^n$টি আলাদা কোড দিতে পারে ($0$ থেকে $2^n - 1$)। এই কোডগুলো পুরো রেফারেন্স রেঞ্জ ($0$ থেকে $V_{ref}$) জুড়ে সমান দূরত্বে ছড়ানো থাকে — প্রতিটি ধাপের আকার (স্টেপ সাইজ বা রেজোলিউশন):

$$ \Delta = \dfrac{V_{ref}}{2^{n}} $$

একটি ইনপুট ভোল্টেজ $V_{in}$-কে নিকটতম কোডে রূপান্তর করা হয় রাউন্ড করে:

$$ D = \mathrm{round}\!\left(\dfrac{V_{in}}{\Delta}\right), \qquad V_{quantized} = D \times \Delta $$

যেহেতু $D$ একটি পূর্ণসংখ্যা আর $V_{in}$ প্রায় সবসময়ই একটি ঠিক স্টেপ বাউন্ডারিতে পড়ে না, তাই একটি ছোট কোয়ান্টাইজেশন এরর সবসময় থেকে যায়:

$$ E_{quant} = V_{quantized} - V_{in} $$

৩ · সিমুলেশন — কয়েকটি ভোল্টেজকে কোডে রূপান্তর

নিচের কোড সেলে একটি quantize() ফাংশন উপরের সূত্র সত্যিই প্রয়োগ করে কয়েকটি অ্যানালগ ভোল্টেজকে একটি ১০-বিট ADC-এর কোডে রূপান্তর করছে এবং প্রতিটির কোয়ান্টাইজেশন এরর গণনা করে দেখাচ্ছে।

Python
def quantize(voltage, vref, bits):
    step_size = vref / (2 ** bits)
    max_code = (2 ** bits) - 1
    code = round(voltage / step_size)
    code = max(0, min(code, max_code))  # রেঞ্জের বাইরে গেলে ক্ল্যাম্প করা
    quantized_voltage = code * step_size
    error = quantized_voltage - voltage
    return step_size, code, quantized_voltage, error


vref = 3.3
bits = 10
test_voltages = [0.837, 1.650, 3.000]

step_size = vref / (2 ** bits)
print(f"{bits}-bit ADC, Vref={vref}V -> স্টেপ সাইজ (Δ) = {step_size:.6f} V")
print()

for v in test_voltages:
    step_size, code, qv, err = quantize(v, vref, bits)
    print(f"ইনপুট = {v:.3f}V  ->  code = {code:4d}  ->  কোয়ান্টাইজড = {qv:.6f}V  "
          f"->  এরর = {err:+.6f}V")

    

৪ · রেজোলিউশন বাড়ালে এরর কমে — সত্যিকারের তুলনা

একটি গুরুত্বপূর্ণ, সহজেই ভুল বোঝা সম্ভাবনাযুক্ত ধারণা হলো — বেশি বিট মানেই কম এরর, এবং এটি শুধু দাবি নয়, গাণিতিকভাবে নিশ্চিত: যেহেতু $V_{ref}$ প্রতিবার ২-এর গুণিতক দিয়ে ভাগ হয়, একটি নিম্ন-রেজোলিউশন গ্রিডের প্রতিটি কোড-পয়েন্ট একটি উচ্চ-রেজোলিউশন গ্রিডেও ঠিক উপস্থিত থাকে — তাই সূক্ষ্ম গ্রিডে নিকটতম পয়েন্ট কখনও মোটা গ্রিডের চেয়ে দূরে হতে পারে না। নিচের কোড সেলে এই দাবিটি একই ইনপুট ভোল্টেজে ৮-বিট, ১০-বিট ও ১২-বিট ADC-এর জন্য সত্যিই গণনা করে দেখানো হয়েছে।

Python
def quantize(voltage, vref, bits):
    step_size = vref / (2 ** bits)
    max_code = (2 ** bits) - 1
    code = round(voltage / step_size)
    code = max(0, min(code, max_code))
    quantized_voltage = code * step_size
    error = quantized_voltage - voltage
    return step_size, code, quantized_voltage, error


vref = 3.3
target_voltage = 2.017  # একই ইনপুট, বিভিন্ন রেজোলিউশনে টেস্ট করা হচ্ছে

print(f"ইনপুট ভোল্টেজ = {target_voltage}V (Vref={vref}V) -- একই ইনপুট, ভিন্ন রেজোলিউশন:\n")

prev_abs_error = None
for bits in (8, 10, 12):
    step_size, code, qv, err = quantize(target_voltage, vref, bits)
    abs_err = abs(err)
    trend = ""
    if prev_abs_error is not None:
        trend = "  (আগের চেয়ে কম বা সমান এরর)" if abs_err <= prev_abs_error else "  (আগের চেয়ে বেশি এরর!)"
    print(f"{bits:2d}-bit  ->  Δ={step_size:.6f}V  code={code:4d}  "
          f"কোয়ান্টাইজড={qv:.6f}V  |এরর|={abs_err:.6f}V{trend}")
    prev_abs_error = abs_err

    
এই ফলাফল কাকতালীয় নয় — ১০-বিট গ্রিডের প্রতিটি ধাপ আসলে ৮-বিট গ্রিডের প্রতিটি ধাপকে চারভাগে ভাগ করে তৈরি (কারণ $2^{10}/2^{8} = 4$), অর্থাৎ ৮-বিট গ্রিডের প্রতিটি বৈধ পয়েন্ট ১০-বিট গ্রিডেও ঠিক বিদ্যমান। তাই ১০-বিট গ্রিডে নিকটতম পয়েন্ট কখনও ৮-বিট গ্রিডের নিকটতম পয়েন্টের চেয়ে দূরে হতে পারে না — একই যুক্তি ১০-বিট থেকে ১২-বিটেও প্রযোজ্য। এই কারণেই |এরর| প্রতিটি ধাপে কখনও বাড়ে না, শুধু কমে বা সমান থাকে।
মূল কথা · Key takeaway

ADC রেজোলিউশন একটি ট্রেড-অফ — বেশি বিট মানে কম কোয়ান্টাইজেশন এরর কিন্তু সাধারণত ধীর কনভার্সন এবং বেশি হার্ডওয়্যার জটিলতা। L21-এ আমরা ঠিক উল্টো দিকটা দেখব — একটি ডিজিটাল কোড থেকে অ্যানালগ ভোল্টেজ ফিরিয়ে আনা (DAC), একই স্টেপ-সাইজ সূত্র ব্যবহার করে।

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

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

প্র ০১ একটি ADC কি কখনও শূন্য কোয়ান্টাইজেশন এরর দিতে পারে? কখন?

হ্যাঁ, তাত্ত্বিকভাবে — যদি ইনপুট ভোল্টেজ ঠিক একটি স্টেপ বাউন্ডারিতে পড়ে (অর্থাৎ $V_{in}$ ঠিক কোনো $D \times \Delta$-এর সমান হয়), তাহলে $V_{quantized} = V_{in}$ হবে এবং এরর শূন্য হবে। কোড সেলের প্রথম উদাহরণে $1.650V$ ইনপুটটি এরকম একটি বিশেষ ক্ষেত্রে পড়তে পারে, কারণ এটি $V_{ref}/2$-এর কাছাকাছি একটি "সুন্দর" ভগ্নাংশ। তবে বাস্তব-জীবনের এলোমেলো ভোল্টেজে এটি বিরল — সাধারণত একটি ছোট অ-শূন্য এরর থেকেই যায়।

প্র ০২ কোয়ান্টাইজেশন এরর সম্পূর্ণভাবে দূর করা কি সম্ভব?

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

প্র ০৩ কোড সেলে code = max(0, min(code, max_code)) লাইনটি কেন দরকার?

এই লাইনটি কোডকে বৈধ রেঞ্জের ($0$ থেকে $2^{bits}-1$) মধ্যে "ক্ল্যাম্প" (আটকে) রাখে। যদি ইনপুট ভোল্টেজ $V_{ref}$-এর চেয়ে বেশি হয়ে যায় (অথবা নেগেটিভ হয়ে যায়, ভুল ওয়্যারিং বা সেন্সর নয়েজের কারণে), রাউন্ড করা কোড সর্বোচ্চ বৈধ কোডের চেয়ে বড় (বা ০-এর চেয়ে ছোট) হয়ে যেতে পারে — বাস্তব হার্ডওয়্যার ADC-ও এই রেঞ্জের বাইরে গেলে সর্বোচ্চ/সর্বনিম্ন কোডেই "স্যাচুরেট" করে, ভুল বা ওভারফ্লো-করা মান দেয় না।

অনুশীলন

  1. চিন্তা করুন: vref=5.0, bits=8 হলে স্টেপ সাইজ কত হবে বলে আপনার ধারণা? কোড সেলে বসিয়ে যাচাই করুন।

    সূত্র অনুযায়ী $\Delta = 5.0 / 2^{8} = 5.0 / 256 \approx 0.019531$ V, অর্থাৎ প্রায় ১৯.৫৩ মিলিভোল্ট প্রতি স্টেপ। কোড সেলে vref = 5.0, bits = 8 বসিয়ে quantize() কল করলে step_size-এ এই মানই আসবে।

  2. পরীক্ষা করুন: চতুর্থ কোড সেলে target_voltage-এর মান বদলে 0.005 (প্রায় শূন্যের কাছাকাছি) করে Run চাপুন — তিনটি রেজোলিউশনেই এরর কেমন দেখায়?

    এত ছোট ইনপুটে সবচেয়ে কাছের বৈধ কোড সাধারণত code=0 হবে (কারণ ০.০০৫V স্টেপ সাইজের চেয়েও ছোট), তাই quantized_voltage=0 আর এরর হবে প্রায় $-0.005$V প্রতিটি রেজোলিউশনেই কাছাকাছি — এখানে পার্থক্যটা তুলনামূলক কম স্পষ্ট হবে কারণ ইনপুটটি সব রেজোলিউশনেই "প্রথম স্টেপের নিচে" পড়ে যাচ্ছে, তবে বিট বাড়ার সাথে সাথে |এরর| তখনও কখনও বাড়বে না, শুধু কমবে বা সমান থাকবে — গাণিতিক গ্যারান্টিটি এখনও প্রযোজ্য।

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

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ মাইক্রোপ্রসেসর আর্কিটেকচার, এমবেডেড C, GPIO, টাইমার/PWM/ADC, সিরিয়াল প্রোটোকল, RTOS, সেন্সর/অ্যাকচুয়েটর, IoT আর্কিটেকচার, ওয়্যারলেস প্রোটোকল, MQTT/CoAP ও IoT সিকিউরিটি — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • Computer Architecture & Digital Logic কোর্স সহোদর কোর্স সংখ্যা পদ্ধতি ও বাইনারি প্রতিনিধিত্বের সাধারণ ভিত্তি সেই কোর্সেই তৈরি হয়েছে — এই কোর্স ADC-এর মতো পেরিফেরাল-স্পেসিফিক হার্ডওয়্যারে গভীরে যায়।
  • সব 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 ও আরও অনেক কোর্স — সব এক জায়গায়।
আগের পাঠ
PWM জেনারেশন ও অ্যাপ্লিকেশন