1-Wire ও অন্যান্য লো-পিন-কাউন্ট প্রোটোকল
এই পাঠে যা শিখবেন
- 1-Wire প্রোটোকলের মূল ধারণা -- একটি মাত্র তারে টাইমিং-ভিত্তিক বিট এনকোডিং
- DS18B20-এর মতো বাস্তব ডিভাইসে এর ব্যবহার
- অন্যান্য লো-পিন-কাউন্ট অ্যাপ্রোচের সংক্ষিপ্ত পরিচিতি
- একটি হালকা সিমুলেশন -- লজিক ০ বনাম লজিক ১ পালসের প্রস্থের পার্থক্য গণনা
১ · একটি তারেই সব -- পাওয়ার ও ডেটা
UART দুই তার লাগে, SPI চার (বা বেশি), I2C দুই। 1-Wire1-WireDallas/Maxim-এর তৈরি একটি প্রোটোকল যেখানে মাত্র একটি ডেটা লাইনে (+গ্রাউন্ড) পাওয়ার ও ডেটা দুটোই আদান-প্রদান হয়, বিট এনকোড হয় পালস-প্রস্থ দিয়ে। আরও এক ধাপ এগিয়ে -- মাত্র একটি ডেটা লাইন (+ কমন গ্রাউন্ড) দিয়ে কাজ চালায়। কিছু 1-Wire ডিভাইস এমনকি এই একই লাইন থেকে "চুরি" করা সামান্য পাওয়ারে চলে (একে parasitic power বলা হয়) -- আলাদা পাওয়ার তারও লাগে না।
যেহেতু কোনো আলাদা ক্লক লাইন নেই, রিসিভার কীভাবে বিট ০ আর ১-এর মধ্যে পার্থক্য বোঝে? উত্তর: প্রতিটি বিটের জন্য একটি নির্দিষ্ট দৈর্ঘ্যের "টাইম-স্লট" থাকে, আর সেই স্লটের ভেতরে লাইনটি কতক্ষণ LOW থাকে তার প্রস্থ (pulse width) দিয়েই বিটের মান বোঝা যায় -- একটি সংক্ষিপ্ত LOW পালস মানে লজিক ১, একটি দীর্ঘ LOW পালস মানে লজিক ০। এই ডিভাইস পরিবারের সবচেয়ে পরিচিত উদাহরণ DS18B20 -- একটি সস্তা, ব্যাপকভাবে ব্যবহৃত ডিজিটাল তাপমাত্রা সেন্সর।
২ · পালস-প্রস্থ এনকোডিং সিমুলেশন
নিচের কোড সেলে একটি সরল ফাংশন প্রতিটি বিটের জন্য LOW ও HIGH সময়কাল গণনা করে দেখায় -- ডেটাশিটে সাধারণত উল্লেখ করা ইলাস্ট্রেটিভ টাইমিং (নির্দিষ্ট চিপ-ভেদে সামান্য আলাদা হতে পারে) ব্যবহার করে।
def encode_bit_pulse(bit, slot_time_us=65):
# DS18B20-ধাঁচের 1-Wire টাইম-স্লট এনকোডিং (illustrative, ডেটাশিট-টাইপ সাধারণ মান)
if bit == 1:
low_time_us = 2 # সংক্ষিপ্ত LOW পালস -> লজিক 1
else:
low_time_us = 60 # দীর্ঘ LOW পালস -> লজিক 0
high_time_us = slot_time_us - low_time_us
return low_time_us, high_time_us
bits_to_send = [1, 0, 1, 1, 0]
print("1-Wire বিট -> পালস-প্রস্থ এনকোডিং সিমুলেশন:\n")
total_time_us = 0
for bit in bits_to_send:
low_us, high_us = encode_bit_pulse(bit)
slot_total = low_us + high_us
total_time_us += slot_total
print(f" বিট={bit} -> LOW {low_us:2d}µs তারপর HIGH {high_us:2d}µs "
f"(স্লট মোট {slot_total}µs)")
print(f"\nমোট {len(bits_to_send)}টি বিট পাঠাতে সময় লাগবে: {total_time_us}µs")
print(f"গড়ে প্রতি বিটে: {total_time_us / len(bits_to_send):.1f}µs "
f"-- SPI/I2C-এর তুলনায় (L23-L24) এটি অনেক ধীর, কিন্তু মাত্র ১টি তারেই কাজ চলে।")
৩ · অন্যান্য লো-পিন-কাউন্ট অ্যাপ্রোচ
1-Wire ছাড়াও এমবেডেড ডিজাইনে পিন সাশ্রয়ের কিছু সাধারণ কৌশল দেখা যায়: একটি single UART লাইনকেই TX ও RX দুটোর কাজে ব্যবহার করা (half-duplex "single-wire UART" মোড, কিছু মাইক্রোকন্ট্রোলারের পেরিফেরালে সরাসরি সমর্থিত), অথবা I2C-এর (L24) মতো শেয়ার্ড-বাস অ্যাপ্রোচ যেখানে পিন সংখ্যা ডিভাইস সংখ্যার সাথে বাড়ে না। মূল সাধারণ ট্রেডঅফ সবসময় একই: কম পিন মানে সাধারণত কম গতি ও বেশি জটিল টাইমিং/প্রোটোকল লজিক -- পরের পাঠে (L26) এই ট্রেডঅফগুলো একটি ওয়েটেড-স্কোরিং সিদ্ধান্ত-কাঠামোতে একসাথে তুলনা করা হবে।
1-Wire = ১টি ডেটা লাইন + টাইমিং-ভিত্তিক বিট এনকোডিং -- সর্বনিম্ন পিন-কাউন্ট, কিন্তু সবচেয়ে ধীর ও টাইমিং-সংবেদনশীল প্রোটোকল এই মডিউলে। M6-এর চারটি প্রোটোকলই (UART, SPI, I2C, 1-Wire) এখন কভার হয়ে গেছে -- পরের পাঠে এদের মধ্যে সিদ্ধান্ত নেওয়ার একটি বাস্তব কাঠামো দেখা যাবে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন -- তারপর "→ উত্তর" চাপুন।
প্র ০১
কোড সেলে encode_bit_pulse ফাংশনে slot_time_us=65 ধরা হয়েছে। যদি
low_time_us ভুল করে 70 হয়ে যায় (স্লটের চেয়ে বেশি), তাহলে কী সমস্যা হবে?
high_time_us = slot_time_us - low_time_us নেগেটিভ হয়ে যাবে (65-70 = -5), যা বাস্তব
টাইমিংয়ে অর্থহীন -- অর্থাৎ পালসটি পরবর্তী বিটের স্লটে ঢুকে পড়বে, যা রিসিভারকে বিভ্রান্ত করবে।
এটাই দেখায় কেন 1-Wire-এর মতো টাইমিং-নির্ভর প্রোটোকলে প্রতিটি পালসের সময় নিখুঁতভাবে মাপা এত জরুরি।
প্র ০২ 1-Wire ও UART-এর (L22) মধ্যে টাইমিং-নির্ভরতার দিক থেকে মূল পার্থক্য কী?
UART-এ প্রতিটি বিটের সময়কাল সমান (বড রেট থেকে গণনা করা bit_time_us), শুধু ভোল্টেজ
লেভেল (HIGH/LOW) দিয়ে বিটের মান বোঝা যায়। 1-Wire-এ প্রতিটি বিটের LOW-থাকার সময়কালই
বিটের মান বহন করে -- তাই এখানে টাইমিং নিজেই তথ্যের অংশ, শুধু সিঙ্ক্রোনাইজেশনের মাধ্যম নয়।
প্র ০৩ parasitic power (লাইন থেকেই পাওয়ার নেওয়া) কোন ধরনের অ্যাপ্লিকেশনে সবচেয়ে বেশি সুবিধাজনক হতে পারে বলে আপনার মনে হয়?
যেখানে তার টানার সংখ্যা ন্যূনতম রাখা জরুরি -- যেমন দেয়ালের ভেতরে বসানো তাপমাত্রা সেন্সর, বা দীর্ঘ তারের রান লাগে এমন শিল্প/আউটডোর সেন্সর নোড, যেখানে আলাদা পাওয়ার তার টানা ব্যয়বহুল বা অসুবিধাজনক।
অনুশীলন
-
চিন্তা করুন: কোড সেলে
bits_to_send = [1, 0, 1, 1, 0]-এর বদলে[0, 0, 0, 0, 0]দিলে মোট সময় (total_time_us) আগের চেয়ে বাড়বে না কমবে?বাড়বে -- কারণ প্রতিটি বিট এখন লজিক ০ (দীর্ঘ ৬০µs LOW পালস + ৫µs HIGH = ৬৫µs স্লট প্রতিটি), অথচ প্রতিটি স্লটের মোট সময় (
slot_time_us=65) একই থাকে যেকোনো বিটের জন্যই -- তাই আসলে মোট সময় অপরিবর্তিতই থাকবে ($5 \times 65 = 325\,\mu s$), কারণ এই সিমুলেশনে প্রতিটি স্লট একই সময় নেয়, শুধু ভেতরের LOW/HIGH ভাগ বদলায়। -
পরীক্ষা করুন: কোড সেলে
encode_bit_pulse-এslot_time_us=100পাস করে (যেমনencode_bit_pulse(1, slot_time_us=100)) Run করে দেখুনhigh_time_usকীভাবে বদলায়।low_time_us(বিট=1-এর জন্য ২µs) অপরিবর্তিত থাকবে, কিন্তুhigh_time_us = 100 - 2 = 98µsহয়ে যাবে -- অর্থাৎ স্লট বড় হলে LOW পালসের প্রস্থ একই থাকে, শুধু স্লটের বাকি (HIGH) অংশ বড় হয়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ মাইক্রোপ্রসেসর আর্কিটেকচার, এমবেডেড C, GPIO, টাইমার/PWM/ADC, সিরিয়াল প্রোটোকল, RTOS, সেন্সর/অ্যাকচুয়েটর, IoT আর্কিটেকচার, ওয়্যারলেস প্রোটোকল, MQTT/CoAP ও IoT সিকিউরিটি -- বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- Computer Architecture & Digital Logic কোর্স সহোদর কোর্স সাধারণ বাস আর্কিটেকচারের ভিত্তি সেই কোর্সে -- এই পাঠ তার একধাপ নিচের ডিভাইস-লেভেল সিরিয়াল প্রোটোকলে যায়।
- সব 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 ও আরও অনেক কোর্স -- সব এক জায়গায়।