با این پروژه کاربردی و جامع شروع به اندازه گیری دنیای اطراف خود کنید.
نکات کلیدی
- Raspberry Pi فاقد ورودی آنالوگ است، اما می توانید ADC های خارجی را برای تبدیل ولتاژ از دنیای واقعی به شکل دیجیتال برای ضبط، دستکاری و کنترل اضافه کنید.
- گزینه های محبوب ADC عبارتند از MCP3004/MCP3008 برای تسویه سرعت و دقت یا ADS111x برای خواندن 16 بیت با سرعت نمونه پایین تر.
- ADS1115 از Adafruit یک گزینه ساده با تقویت کننده افزایش قابل برنامه ریزی (PGA) است که به شما امکان می دهد تفاوت های ولتاژ کوچک را تشخیص دهید و بهره را در طول برنامه تنظیم کنید. سیم کشی آن با Raspberry Pi با استفاده از I2C ساده است.
در خارج از جعبه، Raspberry Pi فاقد ورودی آنالوگ است. این امر آن را در مقایسه با بردهای مبتنی بر میکروکنترلر مانند آردوینو در یک نقطه ضعف قرار می دهد.
اما ناامید نشوید: گزینه های زیادی برای بررسی وجود دارد. با Raspberry Pi و یک ADC خارجی راهاندازی کنید.
چرا ورودی ها را اضافه کنیم؟
دنیای واقعی پر از پدیده هایی است که در صورت داشتن مدارهای مناسب می توان به راحتی با استفاده از ولتاژ توصیف کرد. این ولتاژها را به شکل دیجیتالی درآورید، و می توانید آنها را ضبط کنید، آنها را دستکاری کنید و از آنها برای کنترل سایر پارامترها و دستگاه ها استفاده کنید.
ممکن است به دنبال نظارت بر رطوبت خاک، دمای گلخانه یا وزن همستر خود باشید. ممکن است به دنبال اضافه کردن یک کنترل صدا به Pi خود باشید، یک بانک کامل از فیدرها بسازید، یا یک جوی استیک از ابتدا طراحی کنید. امکانات، کم و بیش، بی حد و حصر هستند.
گزینه هایی برای ADC ها
بنابراین، کدام ADC برای مبتدیان بهترین است؟
از جمله محبوب ترین و ساده ترین گزینه ها، تراشه های MCP3004 (و MCP3008) از Microchip هستند. شما چهار (یا هشت) کانال 10 بیتی دریافت خواهید کرد که می توانند تا 200 kSPS را بخوانند. از سوی دیگر، دستگاه های ADS111x از Texas Instruments وجود دارند که 16 بیت را در 860 SPS می خوانند. بنابراین، بین سرعت و دقت (و طبیعتاً قیمت) تعادلی وجود دارد.
بسیاری از میکروکنترلرها دارای ADC داخلی هستند. ATMega که در آردوینو متوسط پیدا می کنید، علاوه بر همه چیز، چندین کانال 10 بیتی را ارائه می دهد. این همان چیزی است که به آردوینو اجازه می دهد تا ورودی های آنالوگ را در جایی که Raspberry Pi نمی تواند ارائه دهد. اگر قبلاً یک آردوینو در راهاندازی خود دارید و 10 بیت وفاداری کافی است، در واقع این ممکن است سادهترین راه باشد.
در اینجا، ما آن را با یک ADS1115 از Adafruit ساده نگه می داریم.
تقویت کننده افزایش قابل برنامه ریزی چیست؟
این تراشه دارای چند ویژگی جالب است، از جمله تقویت کننده افزایش قابل برنامه ریزی (PGA). این به شما این امکان را می دهد که محدوده مورد نظر مقادیر را به صورت دیجیتالی تا کسری از ولت تنظیم کنید. با تعداد مقادیری که 16 بیت می تواند نشان دهد، این به شما امکان می دهد تفاوت های تنها چند میکرو ولت را تشخیص دهید.
مزیت در اینجا این است که می توانید بهره را در اواسط برنامه تغییر دهید. تراشه های دیگر، مانند MCP3004، رویکرد متفاوتی دارند. آنها با یک پین اضافی عرضه می شوند که می توانید ولتاژ مرجع را به آن تامین کنید.
در مورد Multiplexing چطور؟
مالتی پلکسر (یا mux) سوئیچی است که به شما امکان می دهد ورودی های زیادی را با استفاده از یک ADC بخوانید. اگر تراشه ADC شما دارای تعداد زیادی پین ورودی باشد، در این صورت مالتی پلکس داخلی در حال انجام است. Mux ADS1115 امکان چهار ورودی را فراهم می کند که می توانید آنها را از طریق رجیسترهای داخلی انتخاب کنید.
سر و کار داشتن با ثبت
ADS1115 این گزینه ها و چند گزینه دیگر را فراهم می کند. می توانید با مالتی پلکسر مقابله کنید، بهره را تنظیم کنید، مقایسه کننده داخلی را فعال کنید، نرخ نمونه را تغییر دهید و دستگاه را در حالت خواب کم مصرف قرار دهید، همه اینها با چرخاندن چند سوئیچ.
اما آن سوئیچ ها کجا هستند؟ آنها در داخل بسته، به شکل بیت های بسیار کوچکی از حافظه به نام ثبات هستند. برای فعال کردن یک ویژگی خاص، فقط باید بیت مربوطه را به جای 0 روی 1 تنظیم کنید.
با نگاهی به دیتاشیت ADS111x، متوجه میشوید که این مدلها دارای چهار رجیستر هستند، از جمله ثبتهای پیکربندی که بر رفتار دستگاه نظارت میکنند.
به عنوان مثال، بیت های 14 تا 12 مالتی پلکسر را کنترل می کنند. با استفاده از این سه بیت، می توانید از بین هشت پیکربندی انتخاب کنید. موردی که در اینجا می خواهید “100” است که تفاوت بین ورودی صفر و زمین را نشان می دهد. از سوی دیگر، بیت های 7 تا 5 بر نرخ نمونه حاکم است. اگر حداکثر 860 نمونه در ثانیه را می خواهید، می توانید آنها را روی “111” تنظیم کنید.
هنگامی که می دانید کدام گزینه را تنظیم کنید، دو بایت برای ارسال به ADC خواهید داشت. اگر بعداً می خواهید یک بیت واحد را اینجا یا آنجا تنظیم کنید، می توانید با استفاده از عملگرهای بیتی با آنها به صورت جداگانه برخورد کنید.
اینجا جایی است که ممکن است گیج کننده باشد. در این مورد، باینری یک مقدار را نشان نمی دهد، بلکه مقادیر سوئیچ های جداگانه را نشان می دهد. شما می توانید این متغیرها را به صورت یک عدد بزرگ، به صورت اعشاری یا هگزادسیمال بیان کنید. اما اگر میخواهید از سردرد جلوگیری کنید، باید به نسخه باینری که خواندن آن آسانتر است، پایبند باشید.
سیم کشی آن
می توانید این دستگاه را مستقیماً به تخته نان وصل کنید. ورودی ولتاژ مثبت بین 2 تا 5.5 ولت را می پذیرد، به این معنی که ریل 3.3 ولت در Raspberry Pi به خوبی کار می کند.
ورودی های SDA و SCL را به همتایان روی RPi متصل کنید و همین کارها را با زمین و 3.3 ولت انجام دهید. یک پتانسیومتر بین خطوط زمین و ولتاژ بگیرید و سرب وسط را در اولین ورودی ADC قرار دهید. این تمام چیزی است که برای شروع نیاز دارید!
مقابله با I2C
ADC های مختلف از طریق پروتکل های مختلف کار می کنند. در مورد ADS1115، ما از I2C استفاده خواهیم کرد.
مثال زیر با استفاده از پایتون با ADC تعامل خواهد داشت. اما قبل از انجام این کار، باید آن را تنظیم کنید. نسخه های اخیر سیستم عامل Raspberry Pi این کار را بسیار ساده کرده است. به تنظیمات > پیکربندی Raspberry Pi بروید. سپس، از تب Interfaces، I2C را روشن کنید.
برای بررسی اینکه همه چیز کار می کند، یک ترمینال را باز کنید و اجرا کنید:
sudo i2cdetect -y 1
این دستور یک شبکه خروجی می دهد. با فرض اینکه همه چیز کار می کند، و شما آن را به درستی سیم کشی کرده اید، مقدار جدیدی در شبکه ظاهر می شود. این آدرس ADC شماست. در اینجا به خاطر داشته باشید که این یک مقدار هگزادسیمال است، بنابراین هنگام استفاده از آن در کد زیر باید آن را با “0x” پیشوند بگذارید. در اینجا، 0x48 است:
پس از دریافت آدرس، می توانید از کتابخانه SMBus برای ارسال دستورات I2C استفاده کنید. در اینجا با دو روش سر و کار خواهید داشت. اولین مورد Writ_word_data() است که سه آرگومان را می پذیرد: آدرس دستگاه، ثباتی که در حال نوشتن آن هستید و مقداری که می خواهید بنویسید.
مورد دوم read_word_data() است که فقط آدرس دستگاه و رجیستر را می پذیرد. ADC به طور مداوم ولتاژها را می خواند و نتیجه را در رجیستر تبدیل ذخیره می کند. با این روش می توانید محتویات آن رجیستر را بازیابی کنید.
می توانید نتیجه را کمی زیبا کنید و سپس آن را چاپ کنید. قبل از اینکه به شروع حلقه برگردید، یک تاخیر کوتاه را معرفی کنید. این اطمینان حاصل می کند که با داده ها غرق نشده اید.
from smbus import SMBus
import time
addr = 0x48
bus = SMBus(1)
# set the registers for reading
CONFIGREG = 1
CONVERSIONREG = 0
# set the address register to point to the config register
# write to the config registers
bus.write_word_data(addr, CONFIGREG, (0b00000100 << 8 | 0b10000010))
# define the top of the range
TOP = 26300
while True:
# read the register
b = bus.read_word_data(addr, CONVERSIONREG)
# swap the two bytes
b = ((b & 0xFF) << 8) | ((b >> 8) & 0xFF)
# subtract half the range to set ground to zero
b -= 0x8000
# divide the result by the range to give us a value between zero and one
b /= TOP
# cap at one
b = min(b, 1)
# bottom is zero
b = max(b, 0)
# two decimal places
b = round(b, 2)
print(b)
time.sleep(.01)
شما به تازگی تمام شده اید. محدوده مقادیری را که میگیرید به مقدار دلخواه خود ترسیم کنید و سپس به تعداد ارقام اعشاری دلخواه کوتاه کنید. میتوانید تابع چاپ را طوری تنظیم کنید که فقط زمانی یک مقدار جدید را چاپ کنید که با آخرین مقدار متفاوت باشد. اگر در مورد حداکثر، حداقل و دور مطمئن نیستید، می توانید لیست 20 تابع مهم پایتون را بررسی کنید!
مقابله با نویز
اکنون، مگر اینکه تنظیمات شما فوقالعاده، فوقالعاده مرتب و مرتب باشد، متوجه سروصدا خواهید شد. این نقطه ضعف ذاتی استفاده از 16 بیت به جای ده بیت است: این کمی نویز بیشتر قابل درک خواهد بود.
با گره زدن ورودی مجاور (ورودی 1) به زمین، و تغییر حالت به طوری که ورودی های یک و دو را با هم مقایسه کنید، می توانید نتایج بسیار پایدارتری دریافت کنید. همچنین میتوانید کابلهای بلند و جمعآوری صدا را با کابلهای کوچک تعویض کنید و در حین کار، چند خازن اضافه کنید. مقدار پتانسیومتر شما نیز می تواند تفاوت ایجاد کند.
گزینه های نرم افزاری نیز وجود دارد. شما ممکن است یک میانگین چرخشی ایجاد کنید، یا به سادگی تغییرات کوچک را نادیده بگیرید. نقطه ضعف وجود دارد این است که کد اضافی هزینه محاسباتی را تحمیل می کند. اگر عبارات شرطی را به زبان سطح بالایی مانند پایتون می نویسید و در هر ثانیه هزاران نمونه برداری می کنید، این هزینه ها به سرعت افزایش می یابد.
با بسیاری از گام های احتمالی بعدی به جلوتر بروید
خواندن از طریق I2C بسیار ساده است و همین امر تا حد زیادی در مورد روشهای دیگر مانند SPI صادق است. در حالی که ممکن است به نظر برسد که بین گزینههای موجود ADC تفاوتهای زیادی وجود دارد، حقیقت این است که وقتی یکی از آنها کار میکند، بهآسانی میتوان دانش را برای دیگران به کار برد.
بنابراین، چرا مسائل را جلوتر نمیبریم؟ چندین پتانسیومتر را به هم گره بزنید یا سعی کنید نور، صدا یا دما را بخوانید. کنترلکنندهای را که ساختهاید گسترش دهید و یک راهاندازی Raspberry Pi ایجاد کنید که واقعاً عملی است!