
آموزش گام به گام آردوینو بخش چهارم پروژههای ترکیبی و نمایشگرها
در بخشهای قبلی، با مفاهیم پایه الکترونیک، اصول برنامهنویسی آردوینو، و کار با سیگنالهای آنالوگ آشنا شدیم. تا الان، خروجیهای ما mostly LEDهای ساده بودند و ورودیها را از طریق Serial Monitor مشاهده میکردیم. اما در دنیای واقعی، نیاز داریم اطلاعات را به شکلی خوانا و کاربرپسند به کاربر نمایش دهیم. در این بخش، با نمایشگرهای ۷ سگمنت و LCD آشنا میشویم و یاد میگیریم چگونه پروژههای ترکیبی با سنسورها و نمایشگرها بسازیم.
فهرست محتوای بخش چهارم
- قسمت ۱: آشنایی با نمایشگر ۷ سگمنت
- قسمت ۲: کار با LCD کاراکتری (LCD 1602)
- قسمت ۳: کتابخانه LiquidCrystal I2C
- پروژه عملی پایان بخش چهارم: ایستگاه هواشناسی ساده
- خلاصه بخش چهارم
قسمت ۱: آشنایی با نمایشگر ۷ سگمنت
۱.۱ ساختار داخلی نمایشگر ۷ سگمنت
نمایشگر ۷ سگمنت در واقع از ۸ LED تشکیل شده است: ۷ LED به شکل عدد ۸ و یک LED کوچک به عنوان نقطه اعشار (dp). هر کدام از این LEDها با حروف a تا g نامگذاری میشوند .
![نمایشگر ۷ سگمنت: شکل عدد ۸ با نامگذاری بخشها a تا g و dp]
دو نوع رایج نمایشگر ۷ سگمنت:
- کاتد مشترک (Common Cathode): پایههای منفی همه LEDها به هم وصل شده و به GND متصل میشود. برای روشن کردن هر سگمنت، باید پایه مربوطه را HIGH کنیم .
- آند مشترک (Common Anode): پایههای مثبت همه LEDها به هم وصل شده و به VCC (۵ ولت) متصل میشود. برای روشن کردن هر سگمنت، باید پایه مربوطه را LOW کنیم .
۱.۲ اتصال نمایشگر ۷ سگمنت به آردوینو
برای کنترل یک نمایشگر ۷ سگمنت، به ۷ یا ۸ پین دیجیتال نیاز داریم (با احتساب نقطه اعشار). هر سگمنت باید از طریق یک مقاومت محدودکننده جریان (حدود ۲۲۰ تا ۳۳۰ اهم) به آردوینو متصل شود .
اتصالات پیشنهادی:
- سگمنت a → پین ۲
- سگمنت b → پین ۳
- سگمنت c → پین ۴
- سگمنت d → پین ۵
- سگمنت e → پین ۶
- سگمنت f → پین ۷
- سگمنت g → پین ۸
- پایه مشترک → GND (برای نوع کاتد مشترک) یا ۵ ولت (برای نوع آند مشترک)
۱.۳ نمایش اعداد با جدول حقیقت
برای نمایش هر رقم، باید ترکیب خاصی از سگمنتها را روشن کنیم. به این ترکیب، “جدول حقیقت” یا “کد نویسه” میگویند .
جدول کدهای هگز برای نمایش اعداد ۰ تا ۹ (برای نمایشگر کاتد مشترک):
| رقم | سگمنتهای روشن | باینری (dp g f e d c b a) | کد هگز |
|---|---|---|---|
| ۰ | a, b, c, d, e, f | 0011 1111 | 0x3F |
| ۱ | b, c | 0000 0110 | 0x06 |
| ۲ | a, b, d, e, g | 0101 1011 | 0x5B |
| ۳ | a, b, c, d, g | 0100 1111 | 0x4F |
| ۴ | b, c, f, g | 0110 0110 | 0x66 |
| ۵ | a, c, d, f, g | 0110 1101 | 0x6D |
| ۶ | a, c, d, e, f, g | 0111 1101 | 0x7D |
| ۷ | a, b, c | 0000 0111 | 0x07 |
| ۸ | a, b, c, d, e, f, g | 0111 1111 | 0x7F |
| ۹ | a, b, c, d, f, g | 0110 1111 | 0x6F |
۱.۴ کد نمونه: شمارنده ۰ تا ۹
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
// تعریف پینهای سگمنتها int segA = 2; int segB = 3; int segC = 4; int segD = 5; int segE = 6; int segF = 7; int segG = 8; // آرایهای از پینها برای دسترسی آسانتر int segmentPins[] = {segA, segB, segC, segD, segE, segF, segG}; // آرایهای از کدهای نمایش ارقام (برای کاتد مشترک) // ترتیب: a, b, c, d, e, f, g byte digitCodes[10][7] = { {1, 1, 1, 1, 1, 1, 0}, // 0 {0, 1, 1, 0, 0, 0, 0}, // 1 {1, 1, 0, 1, 1, 0, 1}, // 2 {1, 1, 1, 1, 0, 0, 1}, // 3 {0, 1, 1, 0, 0, 1, 1}, // 4 {1, 0, 1, 1, 0, 1, 1}, // 5 {1, 0, 1, 1, 1, 1, 1}, // 6 {1, 1, 1, 0, 0, 0, 0}, // 7 {1, 1, 1, 1, 1, 1, 1}, // 8 {1, 1, 1, 1, 0, 1, 1} // 9 }; void setup() { // تنظیم همه پینها به عنوان خروجی for (int i = 0; i < 7; i++) { pinMode(segmentPins[i], OUTPUT); } } void loop() { // نمایش اعداد ۰ تا ۹ به ترتیب for (int digit = 0; digit < 10; digit++) { displayDigit(digit); delay(1000); // هر عدد یک ثانیه نمایش داده شود } } // تابع نمایش یک رقم void displayDigit(int digit) { for (int i = 0; i < 7; i++) { digitalWrite(segmentPins[i], digitCodes[digit][i]); } } |
نسخه سادهتر با استفاده از آرایه کدهای هگز :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
int segmentPins[] = {2, 3, 4, 5, 6, 7, 8}; // a, b, c, d, e, f, g byte hexCodes[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; void setup() { for (int i = 0; i < 7; i++) { pinMode(segmentPins[i], OUTPUT); } } void loop() { for (int digit = 0; digit < 10; digit++) { setSegments(hexCodes[digit]); delay(1000); } } void setSegments(byte code) { for (int i = 0; i < 7; i++) { // بررسی بیت مربوطه در کد هگز digitalWrite(segmentPins[i], (code >> i) & 1); } } |
۱.۵ نمایشگرهای چندرقمی و مفهوم مالتیپلکس
برای نمایش اعداد چندرقمی، به جای استفاده از چندین نمایشگر مجزا (که نیاز به پینهای زیادی دارد)، از روش مالتیپلکس استفاده میکنیم. در این روش، سگمنتهای متناظر همه ارقام به یک پین مشترک وصل میشوند و هر رقم یک پایه انتخاب جداگانه دارد. با سوئیچ کردن سریع بین ارقام (با سرعت بیشتر از ۵۰ هرتز)، چشم انسان همه ارقام را همزمان میبیند .
قسمت ۲: کار با LCD کاراکتری (LCD 1602)
۲.۱ معرفی LCD 1602
LCD 1602 یک نمایشگر کریستال مایع است که میتواند ۱۶ کاراکتر در ۲ سطر (مجموعاً ۳۲ کاراکتر) نمایش دهد . این نمایشگرها بر پایه کنترلکننده معروف Hitachi HD44780 ساخته میشوند و تقریباً همه نسخههای موجود در بازار از نظر دستورات با هم سازگار هستند .
مشخصات:
- ولتاژ کاری: ۵ ولت
- قابلیت نمایش حروف، اعداد و نمادها
- دارای نور پسزمینه (Backlight)
- قابلیت تعریف کاراکترهای سفارشی
۲.۲ پایههای LCD 1602
LCD 1602 دارای ۱۶ پایه است که وظایف زیر را دارند :
| شماره پایه | نماد | توضیح |
|---|---|---|
| ۱ | VSS | زمین (GND) |
| ۲ | VDD | برق مثبت (۵ ولت) |
| ۳ | V0 | تنظیم کنتراست (به پتانسیومتر وصل میشود) |
| ۴ | RS | انتخاب ثبات (Register Select) – ۰: فرمان، ۱: داده |
| ۵ | RW | خواندن/نوشتن (معمولاً به GND وصل میشود برای حالت نوشتن) |
| ۶ | E | پایه فعالساز (Enable) |
| ۷-۱۴ | D0-D7 | پایههای داده (۸ بیت) |
| ۱۵ | A | آند نور پسزمینه (۵ ولت از طریق مقاومت) |
| ۱۶ | K | کاتد نور پسزمینه (GND) |
۲.۳ دو روش اتصال: ۸ بیتی و ۴ بیتی
برای صرفهجویی در پایههای آردوینو، معمولاً از حالت ۴ بیتی استفاده میکنیم. در این حالت، فقط از پایههای D4 تا D7 استفاده میشود و دادهها در دو مرحله (۴ بیت اول و ۴ بیت دوم) ارسال میگردند .
اتصالات در حالت ۴ بیتی:
- RS → پین دیجیتال آردوینو (مثلاً ۱۲)
- RW → GND (همیشه در حالت نوشتن)
- E → پین دیجیتال آردوینو (مثلاً ۱۱)
- D4 → پین دیجیتال آردوینو (مثلاً ۵)
- D5 → پین دیجیتال آردوینو (مثلاً ۴)
- D6 → پین دیجیتال آردوینو (مثلاً ۳)
- D7 → پین دیجیتال آردوینو (مثلاً ۲)
۲.۴ کتابخانه LiquidCrystal
خوشبختانه آردوینو کتابخانه آماده LiquidCrystal را دارد که کار با LCD را بسیار ساده میکند .
کد نمونه: نمایش “Hello World!” روی LCD
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <LiquidCrystal.h> // تعریف پینهای متصل شده (مطابق با اتصالات بالا) LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { lcd.begin(16, 2); // تنظیم تعداد ستونها و سطرها lcd.print("Hello World!"); // چاپ متن } void loop() { lcd.setCursor(0, 1); // قرار دادن مکاننما در سطر دوم، ستون اول lcd.print(millis() / 1000); // نمایش زمان بر حسب ثانیه lcd.print(" sec"); delay(1000); } |
۲.۵ توابع مهم کتابخانه LiquidCrystal
| تابع | توضیح |
|---|---|
lcd.begin(cols, rows) |
مقداردهی اولیه LCD (مثلاً ۱۶ ستون و ۲ سطر) |
lcd.print(data) |
چاپ متن یا اعداد روی LCD |
lcd.setCursor(col, row) |
تنظیم موقعیت مکاننما (ستون از ۰، سطر از ۰) |
lcd.clear() |
پاک کردن صفحه و برگرداندن مکاننما به خانه |
lcd.home() |
برگرداندن مکاننما به موقعیت (۰,۰) |
lcd.cursor() |
نمایش مکاننما به صورت خط زیرین |
lcd.noCursor() |
مخفی کردن مکاننما |
lcd.blink() |
چشمک زدن مکاننما |
lcd.noBlink() |
خاموش کردن چشمک مکاننما |
lcd.display() |
روشن کردن صفحه (پس از خاموش کردن) |
lcd.noDisplay() |
خاموش کردن صفحه (بدون پاک کردن حافظه) |
lcd.scrollDisplayLeft() |
اسکرول محتوا به چپ |
lcd.scrollDisplayRight() |
اسکرول محتوا به راست |
lcd.createChar(num, data[]) |
ایجاد کاراکتر سفارشی (۰ تا ۷) |
۲.۶ تنظیم کنتراست با پتانسیومتر
برای اینکه متن به وضوح دیده شود، باید پایه V0 (پایه ۳) LCD را به یک پتانسیومتر ۱۰ کیلواهم وصل کنیم. پتانسیومتر بین ۵ ولت و GND قرار میگیرد و خروجی آن به V0 میرود .
نکته عیبیابی: اگر صفحه روشن است اما کاراکتر نمیبیند، یا فقط مربعهای توپر میبینید، معمولاً مشکل از تنظیم نبودن کنتراست است .
قسمت ۳: کتابخانه LiquidCrystal I2C
۳.۱ مشکل LCD معمولی و راهحل I2C
اتصال LCD به روش ۴ بیتی هنوز هم ۶ پایه از آردوینو اشغال میکند (RS, E, D4-D7). برای پروژههای بزرگ که به سنسورهای زیادی نیاز دارند، این تعداد پایه زیاد است. راهحل استفاده از ماژول آداپتور I2C است که روی پشت LCD نصب میشود .
مزایا:
- فقط به ۴ سیم نیاز دارد: VCC, GND, SDA, SCL
- نویز کمتر و اتصالات سادهتر
- نیاز به پتانسیومتر جداگانه برای کنتراست ندارد (روی ماژول تعبیه شده)
۳.۲ اتصال ماژول I2C به آردوینو
ماژول I2C به پینهای زیر متصل میشود :
- VCC → ۵ ولت
- GND → GND
- SDA → A4 (در آردوینو Uno)
- SCL → A5 (در آردوینو Uno)
نکته: در آردوینوهای جدیدتر (مانند Uno R3)، پینهای SDA و SCL در نزدیکی پین AREF نیز وجود دارند.
۳.۳ نصب کتابخانه LiquidCrystal I2C
برای کار با LCD I2C، باید کتابخانه مناسب را نصب کنیم. دو کتابخانه معروف وجود دارد:
- LiquidCrystal_I2C توسط Frank de Brabander
- NewLiquidCrystal (پشتیبانی از آداپتورهای مختلف)
روش نصب:
- از منوی Sketch → Include Library → Manage Libraries
- جستجوی “LiquidCrystal I2C”
- نصب کتابخانه توسط Frank de Brabander
۳.۴ کد نمونه با LCD I2C
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <Wire.h> #include <LiquidCrystal_I2C.h> // آدرس I2C معمولاً 0x27 یا 0x3F است LiquidCrystal_I2C lcd(0x27, 16, 2); void setup() { lcd.begin(16, 2); // مقداردهی اولیه lcd.backlight(); // روشن کردن نور پسزمینه lcd.print("Hello World!"); } void loop() { lcd.setCursor(0, 1); lcd.print("Time: "); lcd.print(millis() / 1000); delay(1000); } |
۳.۵ پیدا کردن آدرس I2C
اگر آدرس I2C را نمیدانید، میتوانید از کد جستجوگر زیر استفاده کنید :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices = 0; for (address = 1; address < 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } } if (nDevices == 0) Serial.println("No I2C devices found"); delay(5000); } |
پروژه عملی پایان بخش چهارم: ایستگاه هواشناسی ساده
حالا همه مفاهیم این بخش را در یک پروژه جامع ترکیب میکنیم. هدف: ساخت یک ایستگاه هواشناسی ساده که دما و رطوبت را با سنسور DHT11 اندازهگیری کرده و روی LCD نمایش دهد .
قطعات مورد نیاز:
- برد آردوینو Uno
- سنسور DHT11 (دما و رطوبت)
- LCD 1602 با ماژول I2C
- مقاومت ۱۰ کیلو اهم (برای DHT11، اگر روی ماژول نیست)
- برد بورد و سیم جامپر
نحوه بستن مدار:
| قطعه | پایه | اتصال به آردوینو |
|---|---|---|
| DHT11 | VCC | ۵ ولت |
| DHT11 | DATA | پین ۲ |
| DHT11 | GND | GND |
| LCD I2C | VCC | ۵ ولت |
| LCD I2C | GND | GND |
| LCD I2C | SDA | A4 |
| LCD I2C | SCL | A5 |
نکته: اگر از DHT11 ماژولدار استفاده میکنید، معمولاً مقاومت pull-up روی ماژول وجود دارد. در غیر این صورت، یک مقاومت ۱۰ کیلو اهم بین پایه DATA و VCC قرار دهید.
نصب کتابخانههای مورد نیاز:
- DHT sensor library توسط Adafruit
- Adafruit Unified Sensor (پیشنیاز کتابخانه DHT)
- LiquidCrystal_I2C (برای LCD)
کد پروژه:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <DHT.h> // تعریف ثابتها #define DHTPIN 2 // پین متصل به DHT11 #define DHTTYPE DHT11 // نوع سنسور DHT // آدرس I2C برای LCD (ممکن است 0x27 یا 0x3F باشد) LiquidCrystal_I2C lcd(0x27, 16, 2); // ایجاد شیء برای سنسور DHT DHT dht(DHTPIN, DHTTYPE); // متغیرها float temperature = 0; float humidity = 0; unsigned long lastReadTime = 0; const unsigned long readInterval = 2000; // هر ۲ ثانیه یکبار بخوان void setup() { Serial.begin(9600); // مقداردهی اولیه LCD lcd.begin(16, 2); lcd.backlight(); // نمایش پیام خوشآمدگویی lcd.setCursor(0, 0); lcd.print("Weather Station"); lcd.setCursor(0, 1); lcd.print("Initializing..."); // شروع سنسور DHT dht.begin(); delay(2000); lcd.clear(); } void loop() { // خواندن سنسور در بازههای زمانی مشخص if (millis() - lastReadTime >= readInterval) { readSensors(); lastReadTime = millis(); // نمایش روی LCD displayOnLCD(); // نمایش روی Serial Monitor برای دیباگ displayOnSerial(); } } void readSensors() { // خواندن رطوبت humidity = dht.readHumidity(); // خواندن دما (به سلسیوس) temperature = dht.readTemperature(); // بررسی خطا در خواندن if (isnan(humidity) || isnan(temperature)) { Serial.println("Failed to read from DHT sensor!"); humidity = 0; temperature = 0; } } void displayOnLCD() { lcd.clear(); // نمایش دما در سطر اول lcd.setCursor(0, 0); lcd.print("Temp: "); lcd.print(temperature, 1); // یک رقم اعشار lcd.print(" C"); // نمایش رطوبت در سطر دوم lcd.setCursor(0, 1); lcd.print("Humidity: "); lcd.print(humidity, 0); // بدون اعشار lcd.print("%"); } void displayOnSerial() { Serial.print("Temperature: "); Serial.print(temperature); Serial.print(" C\tHumidity: "); Serial.print(humidity); Serial.println("%"); } |
توضیح کد:
- کتابخانهها: سه کتابخانه اصلی را وارد کردهایم: Wire برای I2C، LiquidCrystal_I2C برای LCD، و DHT برای سنسور دما و رطوبت .
- مقداردهی اولیه: در تابع
setup، LCD را مقداردهی کرده و نور پسزمینه را روشن میکنیم. سنسور DHT نیز باdht.begin()راهاندازی میشود. - خواندن سنسور: برای اینکه سنسور DHT فرصت کافی برای اندازهگیری داشته باشد، هر ۲ ثانیه یکبار آن را میخوانیم (DHT11 حداکثر ۱ هرتز سرعت دارد).
- نمایش روی LCD: از توابع
setCursorوprintبرای نمایش مقادیر در موقعیتهای مناسب استفاده میکنیم. باtemperature, 1مشخص میکنیم که فقط یک رقم اعشار نمایش داده شود. - عیبیابی: اگر سنسور خراب باشد یا اتصال درستی نداشته باشد، تابع
isnanخطا را تشخیص داده و مقدار پیشفرض نمایش میدهد .
توسعه پروژه (تمرین بیشتر):
- اضافه کردن سنسور نور LDR: مقدار نور محیط را نیز اندازهگیری کرده و روی LCD نمایش دهید.
- تاریخ و زمان: با اضافه کردن ماژول RTC (Real Time Clock)، تاریخ و زمان را نیز نمایش دهید.
- ثبت حداکثر و حداقل: حداکثر و حداقل دما و رطوبت ثبت شده را محاسبه و نمایش دهید.
- صرفهجویی در انرژی: با اضافه کردن یک دکمه، LCD را فقط در صورت نیاز روشن کنید.
- کاراکترهای سفارشی: با تابع
createChar، یک نماد درجه سانتیگراد (°) زیباتر یا یک آیکون قطره برای رطوبت بسازید .
خلاصه بخش چهارم
در این بخش یاد گرفتیم:
- با نمایشگر ۷ سگمنت و نحوه نمایش اعداد با استفاده از جدول حقیقت آشنا شویم .
- تفاوت بین نمایشگرهای کاتد مشترک و آند مشترک را درک کنیم .
- از روش مالتیپلکس برای کنترل نمایشگرهای چندرقمی استفاده کنیم .
- با LCD 1602 کاراکتری و پایههای آن آشنا شویم .
- از کتابخانه LiquidCrystal برای کنترل LCD در حالت ۴ بیتی استفاده کنیم .
- با توابع مهم این کتابخانه مانند
print,setCursor,clearکار کنیم . - مشکل اشغال پایههای زیاد را با استفاده از ماژول I2C حل کنیم .
- کتابخانه LiquidCrystal_I2C را نصب و استفاده کنیم.
- آدرس I2C دستگاهها را با کد اسکنر I2C پیدا کنیم .
- یک پروژه جامع ایستگاه هواشناسی ساده با سنسور DHT11 و LCD I2C پیادهسازی کنیم .
در بخش پنجم، به سراغ ارتباط سریال و کتابخانههای پیشرفته میرویم و با پروتکلهای ارتباطی I2C و SPI، کنترل موتورها، و سنسورهای پیشرفتهتر آشنا خواهیم شد.



