در قسمت قبل از آموزش آردوینو با نحوه اتصال و راهاندازی نمایشگر متنی HD44780 و کتابخانه LiquidCrystal آشنا شدیم. در قسمت 61 آموزش آردوینو کار با LCD را ادامه میدهیم و یاد میگیریم چگونه محل نمایش متن را مشخص کنیم، مکاننما را کنترل کنیم، صفحه را روشن و خاموش کنیم و متنهای طولانی را روی نمایشگر حرکت دهیم.
در این آموزش با توابع مهمی مانند lcd.setCursor()، lcd.clear()، lcd.blink()، lcd.noBlink()، lcd.display()، lcd.noDisplay()، lcd.scrollDisplayLeft() و lcd.scrollDisplayRight() کار خواهیم کرد.
قالببندی متن روی LCD با آردوینو
زمانی که از یک LCD در پروژه استفاده میکنیم، معمولاً نمیخواهیم تمام اطلاعات پشت سر هم روی صفحه نوشته شوند. در بسیاری از پروژهها لازم است مقادیر مختلف در محلهای مشخصی از نمایشگر قرار بگیرند. برای مثال ممکن است بخواهیم مقدار یک سنسور را در یک ستون، وضعیت سیستم را در ستون دیگر و یک شمارنده را در نقطه مشخصی از صفحه نمایش دهیم.
کتابخانه LiquidCrystal امکان تعیین محل دقیق چاپ متن را با استفاده از تابع lcd.setCursor() فراهم میکند.
مثال قالببندی متن روی LCD
کد زیر ابتدا یک شمارش معکوس از 9 انجام میدهد و سپس اعداد را با فاصلههای مشخص در چند ستون LCD نمایش میدهد. اگر نمایشگر شما تعداد سطر یا ستون متفاوتی دارد، مقادیر numRows و numCols را متناسب با 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 |
/* * LiquidCrystal Library - FormatText */ #include <LiquidCrystal.h> const int numRows = 2; const int numCols = 16; int count; LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { lcd.begin(numCols, numRows); lcd.print("Starting in "); for(int i=9; i > 0; i--) { lcd.setCursor(12,0); lcd.print(i); delay(1000); } } void loop() { int columnWidth = 4; int displayColumns = 3; lcd.clear(); for(int col=0; col < displayColumns; col++) { lcd.setCursor(col * columnWidth, 0); count = count + 1; lcd.print(count); } delay(1000); } |

تابع lcd.setCursor چگونه کار میکند؟
دستور lcd.print() هر کاراکتر جدید را بعد از کاراکتر قبلی نمایش میدهد. اما با استفاده از lcd.setCursor() میتوان تعیین کرد چاپ بعدی دقیقاً از کدام ستون و سطر آغاز شود.
ساختار این دستور به شکل زیر است:
|
1 |
lcd.setCursor(column, row); |
برای مثال:
|
1 2 |
lcd.setCursor(12, 0); lcd.print(i); |
این دستور مکاننما را روی ستون 12 و سطر صفر قرار میدهد و سپس مقدار i در همان موقعیت چاپ میشود.
lcd.setCursor(4,0) به معنی ستون پنجم در سطر اول است.ایجاد چند ستون روی LCD
در مثال بالا، متغیر columnWidth فاصله بین ستونها را مشخص میکند:
|
1 |
int columnWidth = 4; |
سپس موقعیت هر ستون از طریق ضرب شماره ستون در عرض آن محاسبه میشود:
|
1 2 3 4 |
lcd.setCursor(col * columnWidth, 0); count = count + 1; lcd.print(count); |
به این ترتیب هر مقدار با فاصلهای ثابت از مقدار قبلی روی LCD چاپ میشود.
پاککردن LCD با lcd.clear
دستور زیر تمام محتوای نمایشگر را پاک میکند:
|
1 |
lcd.clear(); |
پس از اجرای این دستور، مکاننما نیز دوباره به گوشه بالا و سمت چپ نمایشگر منتقل میشود.
استفاده از تمام سطرهای LCD
نسخه بعدی برنامه از تمام سطرهای موجود در LCD استفاده میکند. برای این کار دو حلقه for تو در تو داریم؛ حلقه اول بین سطرها و حلقه دوم بین ستونها حرکت میکند.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void loop() { int columnWidth = 4; int displayColumns = 3; lcd.clear(); for(int row=0; row < numRows; row++) { for(int col=0; col < displayColumns; col++) { lcd.setCursor(col * columnWidth, row); count = count + 1; lcd.print(count); } } delay(1000); } |
حلقه بیرونی سطرهای LCD را پیمایش میکند و حلقه داخلی مقادیر را در ستونهای مختلف همان سطر قرار میدهد.
محاسبه خودکار تعداد ستونها
بهجای اینکه تعداد ستونهای قابل نمایش را بهصورت ثابت مشخص کنیم:
|
1 |
int displayColumns = 3; |
میتوان تعداد ستونها را بر اساس عرض LCD و فاصله هر ستون محاسبه کرد:
|
1 |
int displayColumns = numCols / columnWidth; |
در این حالت تعداد ستونها متناسب با تعداد کاراکترهای LCD بهصورت خودکار محاسبه میشود.
چشمکزدن Cursor و روشن و خاموش کردن LCD
بخش بعدی آموزش مربوط به کنترل مکاننما و خود نمایشگر است. گاهی اوقات میخواهیم توجه کاربر را به یک قسمت خاص جلب کنیم یا نمایشگر را برای مدتی خاموش کنیم. کتابخانه LiquidCrystal برای این کار چند تابع آماده در اختیار ما قرار میدهد.
مثال کنترل Cursor و Display
|
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 |
/* * blink */ #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("cursor blink"); lcd.blink(); delay(2000); lcd.noBlink(); lcd.print(" noBlink"); delay(2000); lcd.clear(); lcd.print("Display off ..."); delay(1000); lcd.noDisplay(); delay(2000); lcd.display(); lcd.setCursor(0, 0); lcd.print(" display flash !"); displayBlink(2, 250); displayBlink(2, 500); lcd.clear(); } void displayBlink(int blinks, int duration) { while(blinks--) { lcd.noDisplay(); delay(duration); lcd.display(); delay(duration); } } |

فعالکردن چشمکزدن Cursor
برای فعالکردن حالت چشمکزن مکاننما از دستور زیر استفاده میشود:
|
1 |
lcd.blink(); |
در این حالت یک بلوک چشمکزن در محل چاپ کاراکتر بعدی دیده میشود.
برای غیرفعالکردن این حالت کافی است بنویسیم:
|
1 |
lcd.noBlink(); |
خاموشکردن متن LCD بدون پاککردن آن
دستور lcd.noDisplay() نمایش متن روی LCD را غیرفعال میکند:
|
1 |
lcd.noDisplay(); |
نکته مهم این است که این دستور اطلاعات را از حافظه داخلی LCD پاک نمیکند. بنابراین با دستور زیر میتوان همان اطلاعات را دوباره نمایش داد:
|
1 |
lcd.display(); |
این ویژگی به ما اجازه میدهد کل صفحه را بدون پاککردن محتوای آن چشمکزن کنیم.
ساخت تابع چشمکزدن کل Display
در مثال کتاب تابعی با نام displayBlink() ساخته شده است:
|
1 2 3 4 5 6 7 8 9 10 11 |
void displayBlink(int blinks, int duration) { while(blinks--) { lcd.noDisplay(); delay(duration); lcd.display(); delay(duration); } } |
پارامتر blinks تعداد دفعات چشمکزدن و پارامتر duration مدت روشن یا خاموشبودن صفحه را تعیین میکند.
برای مثال:
|
1 |
displayBlink(2, 250); |
نمایشگر را دو مرتبه با فاصله زمانی 250 میلیثانیه خاموش و روشن میکند.
اسکرول متن روی LCD با آردوینو
یکی از محدودیتهای LCDهای متنی، تعداد کم کاراکترهای قابل نمایش در هر سطر است. برای مثال، روی یک LCD 16×2 فقط 16 کاراکتر در هر سطر قابل مشاهده است. اگر متن طولانیتر باشد، میتوان آن را روی نمایشگر حرکت داد یا Scroll کرد.
در مثال کتاب، جهت حرکت متن با استفاده از یک Tilt Sensor کنترل میشود. یک سمت سنسور Tilt به پایه 7 Arduino و سمت دیگر آن به GND متصل میشود.

کد اسکرول متن با Tilt Sensor
|
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 |
/* * Scroll * this sketch scrolls text left when tilted * text scrolls right when not tilted. */ #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); const int numRows = 2; const int numCols = 16; const int tiltPin = 7; const char textString[] = "tilt to scroll"; const int textLen = sizeof(textString) - 1; bool isTilted = false; void setup() { lcd.begin(numCols, numRows); pinMode(tiltPin, INPUT_PULLUP); lcd.print(textString); } void loop() { if(digitalRead(tiltPin) == LOW && isTilted == false) { isTilted = true; for(int position = 0; position < textLen; position++) { lcd.scrollDisplayLeft(); delay(150); } } if(digitalRead(tiltPin) == HIGH && isTilted == true) { isTilted = false; for(int position = 0; position < textLen; position++) { lcd.scrollDisplayRight(); delay(150); } } } |
حرکت متن به سمت چپ
دستور زیر تمام محتوای نمایشگر را یک موقعیت به سمت چپ حرکت میدهد:
|
1 |
lcd.scrollDisplayLeft(); |
در این مثال، زمانی که سنسور Tilt در وضعیت فعال قرار دارد و ورودی LOW خوانده میشود، متن به سمت چپ حرکت میکند.
حرکت متن به سمت راست
برای حرکت متن در جهت مخالف از دستور زیر استفاده میشود:
|
1 |
lcd.scrollDisplayRight(); |
زمانی که وضعیت سنسور دوباره به HIGH برگردد، برنامه متن را در جهت راست حرکت میدهد.
تعیین سرعت اسکرول
سرعت حرکت متن در این مثال با مقدار delay() کنترل میشود:
|
1 |
delay(150); |
اگر متن بیش از حد سریع حرکت میکند میتوانید مقدار Delay را افزایش دهید و اگر حرکت بیش از حد کند است مقدار آن را کاهش دهید.
ساخت متن روان یا Marquee روی LCD
قابلیت اسکرول زمانی بسیار مفید است که متن بیشتر از عرض یک سطر LCD باشد. مثال بعدی یک تابع marquee() ایجاد میکند تا متنهای طولانی روی صفحه حرکت کنند.
|
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 |
/* * Marquee * this sketch can scroll a very long line of text */ #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); const int numRows = 2; const int numCols = 16; void setup() { lcd.begin(numCols, numRows); marquee("This is a very long string of text that will scroll"); } void loop() { } void marquee(char *text) { lcd.print(text); delay(1000); for(int position = 0; position < strlen(text) - numCols; position++) { lcd.scrollDisplayLeft(); delay(300); } } |
نحوه کار تابع marquee
ابتدا متن کامل با دستور lcd.print() در حافظه نمایشگر نوشته میشود. سپس برنامه بررسی میکند که طول رشته چقدر بیشتر از عرض LCD است و به همان تعداد صفحه را به سمت چپ حرکت میدهد:
|
1 2 3 4 5 6 7 |
for(int position = 0; position < strlen(text) - numCols; position++) { lcd.scrollDisplayLeft(); delay(300); } |
محدودیت حافظه داخلی LCD
تراشه LCD دارای حافظه داخلی برای نگهداری متن است. کتاب اشاره میکند که این حافظه محدود است و در بسیاری از نمایشگرهای چهارخطی حدود 32 بایت ظرفیت دارد. اگر رشتههای بسیار طولانی را مستقیماً در این حافظه قرار دهیم، ممکن است متن روی خودش Wrap شود و نتیجه مورد انتظار را نداشته باشیم. برای اسکرول متنهای طولانیتر باید متن را در حافظه Arduino نگه داریم و هر بار فقط بخشی از آن را روی LCD نمایش دهیم.
اسکرول دستی متنهای طولانی
تابع زیر روشی برای اسکرول دستی رشتههای طولانی ارائه میدهد. در این روش بهجای حرکتدادن حافظه داخلی 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 |
void marquee(char *text) { int length = strlen(text); if(length < numCols) { lcd.print(text); } else { int pos; for(pos = 0; pos < numCols; pos++) { lcd.print(text[pos]); } delay(1000); pos = 1; while(pos <= length - numCols) { lcd.setCursor(0, 0); for(int i=0; i < numCols; i++) { lcd.print(text[pos + i]); } delay(300); pos = pos + 1; } } } |
روش اسکرول دستی چه تفاوتی دارد؟
در ابتدا فقط بهاندازه عرض LCD از رشته روی صفحه چاپ میشود. برای یک LCD با 16 ستون، 16 کاراکتر اول نمایش داده میشوند. پس از یک ثانیه، برنامه موقعیت شروع را یک کاراکتر جلو میبرد و دوباره 16 کاراکتر بعدی را نمایش میدهد. این روند تا زمانی ادامه پیدا میکند که تمام متن از مقابل صفحه عبور کند.
مزیت این روش این است که طول پیام دیگر به حافظه داخلی محدود LCD وابسته نیست و میتوان رشتهای را اسکرول کرد که در حافظه Arduino جا میشود.
جمعبندی
در قسمت 61 آموزش آردوینو، کار با LCD متنی را یک مرحله جلوتر بردیم. ابتدا با lcd.setCursor() محل دقیق نمایش متن و اعداد را کنترل کردیم و با lcd.clear() محتوای صفحه را پاک کردیم. سپس با توابع lcd.blink() و lcd.noBlink() مکاننما را کنترل کردیم و دیدیم چگونه با lcd.display() و lcd.noDisplay() نمایش متن را بدون پاکشدن اطلاعات حافظه LCD روشن و خاموش کنیم.
در ادامه نیز با lcd.scrollDisplayLeft() و lcd.scrollDisplayRight() متن را روی صفحه حرکت دادیم و دو روش برای ساخت متن روان یا Marquee بررسی کردیم. همچنین در قسمت بعدی آموزش آردوینو به سراغ نمایش کاراکترها و نمادهای ویژه روی LCD خواهیم رفت.
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.