معرفی
این دومین مقاله از مجموعه سه قسمتی است که در پلتفرم سخت افزاری آردوینو می نویسم . این مقاله بر روی سیم کشی یک آردوینو به یک LCD کاراکتری و یک LCD گرافیکی تمرکز دارد و شامل دموهای ثابت و متحرک برای نشان دادن قابلیت های هر صفحه نمایش است.
ال سی دی های کاراکتری و گرافیکی
پس از اینکه در ابتدا پلتفرم آردوینو را کشف کردم، بلافاصله متوجه انواع مختلفی از قطعاتی شدم که میتوانند به آردوینو متصل شوند - همه چیز از LEDهای ارزان قیمت گرفته تا سپر اترنت با قیمت متوسط، تا محافظ مخزن ظالمانه و فوقالعاده (که به فروش میرسد). برای نزدیک به 200 دلار!) . هنگام خرید برای آردوینو، متوجه شدم که LCDها نسبتاً ارزان هستند، بنابراین یک LCD کاراکتری 16×2 10 دلاری و یک LCD گرافیکی 128×64 دلاری 18 دلاری خریدم .
ال سی دی های کاراکتری و ال سی دی های گرافیکی دستگاه های کاملا متفاوتی هستند و برای راه اندازی آنها به کتابخانه ها و API های متفاوتی نیاز دارند. خوشبختانه هر دو دستگاه توسط جامعه آردوینو پشتیبانی می شوند. برای کاراکتر LCD از کتابخانه LiquidCrystal و برای LCD گرافیکی خود از کتابخانه LCD گرافیکی KS0108 استفاده کردم .
ال سی دی کاراکتری
وصل کردن ال سی دی کاراکتر و برنامه نویسی خیلی راحت بود و مشکلی نداشتم. من به سادگی دستورالعمل ها و نمودار سیم کشی را در آموزش کاراکتر ال سی دی آردوینو دنبال کردم و همه چیز همانطور که انتظار می رفت کار کرد. پس از اجرای طرح نمونه LCD_example، برای استفاده از ال سی دی کاراکتر خود طرحی نوشتم به نام HelloCodeProject
:
Shrink را مخفی کنید
![](https://www.codeproject.com/images/arrow-up-16.png)
کد را کپی کنید
/*
HelloCodeProject.cpp, based off of LCD_example from
http://www.hacktronics.com/Tutorials/arduino-character-lcd-tutorial.html
*/
#include <LiquidCrystal.h>
const int BACK_LIGHT = 13; // Pin 13 will control the backlight
// Connections:
// RS (LCD pin 4) to Arduino pin 12
// RW (LCD pin 5) to Arduino pin 11
// Enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal g_lcd(12, 11, 10, 5, 4, 3, 2);
void setup()
{
pinMode(BACK_LIGHT, OUTPUT);
digitalWrite(BACK_LIGHT, HIGH); // Turn backlight on.
// Replace 'HIGH' with 'LOW' to turn it off.
g_lcd.clear(); // Start with a blank screen
g_lcd.setCursor(0, 0); // Set the cursor to the beginning
g_lcd.print("Hello,");
g_lcd.setCursor(0, 1); // Set the cursor to the next row
g_lcd.print("CodeProject");
}
void loop()
{
}
TickerTape
طرح دومی که نوشتم این بود TickerTape
که پیغام نوار تیک تیک در حال حرکت در صفحه نمایش را شبیه سازی می کند. از آنجایی که TickerTape
اولین طرحی بود که نوشتم که از یک الگوریتم استفاده می کرد (الگوریتم از یک بافر برای پیام استفاده می کند، int
برای پیگیری نقطه شروع پیام برای نمایش، و زمانی که پیام در انتهای آن قرار می گیرد در نظر می گیرد. از بافر)، تصمیم گرفتم ابتدا الگوریتم را در یک برنامه اصلی Win32 C/C++ کدنویسی کنم. از آنجایی که آردوینو فقط قابلیت اشکال زدایی محدودی دارد، من احساس کردم که کدگذاری الگوریتم ابتدا در محیطی که از اشکال زدایی سطح خط و نقاط شکست پشتیبانی می کند سریعتر از تلاش برای اشکال زدایی در آردوینو با استفاده از مجموعه ای از دستورات است Serial.println()
. بعد از اینکه تأیید کردم که الگوریتم کار می کند، TickerTape
طرح را کدنویسی کردم:
/*
TickerTape.cpp, based off of LCD_example from
http://www.hacktronics.com/Tutorials/arduino-character-lcd-tutorial.html
*/
#include <LiquidCrystal.h>
const int BACK_LIGHT = 13; // Pin 13 will control the backlight
const char* MESSAGE = "Example 2: Hello, CodeProject. ";
const int MESSAGE_LENGTH = 31;
const int DISPLAY_WIDTH = 16;
// Connections:
// RS (LCD pin 4) to Arduino pin 12
// RW (LCD pin 5) to Arduino pin 11
// Enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal g_lcd(12, 11, 10, 5, 4, 3, 2);
void setup()
{
pinMode(BACK_LIGHT, OUTPUT);
digitalWrite(BACK_LIGHT, HIGH); // Turn backlight on.
// Replace 'HIGH' with 'LOW' to turn it off.
g_lcd.clear(); // Start with a blank screen
Serial.begin(9600);
}
void loop()
{
static int s_nPosition = 0;
int i;
if(s_nPosition < (MESSAGE_LENGTH - DISPLAY_WIDTH))
{
for(i=0; i<DISPLAY_WIDTH; i++)
{
g_lcd.setCursor(i, 0);
g_lcd.print(MESSAGE[s_nPosition + i]);
}
}
else
{
int nChars = MESSAGE_LENGTH - s_nPosition;
for(i=0; i<nChars; i++)
{
g_lcd.setCursor(i, 0);
g_lcd.print(MESSAGE[s_nPosition + i]);
}
for(i=0; i<(DISPLAY_WIDTH - nChars); i++)
{
g_lcd.setCursor(nChars + i, 0);
g_lcd.print(MESSAGE[i]);
}
}
s_nPosition++;
if(s_nPosition >= MESSAGE_LENGTH)
{
s_nPosition = 0;
}
delay(500);
}
تلاش دوم من تصویر را با استفاده از رمزگذاری طول اجرا فشرده کرد. از آنجایی که بسیاری از پیکسل های تصویر تکرار می شوند، فکر کردم این ممکن است راهی کارآمد برای کاهش داده های مورد نیاز برای تصویر باشد. قالب هر خط این بود:
پنهان کردن کد کپی
[1,0,-42], run1, run2, ..., runN, -1
اولی int
یک نشانگر است. 1
نشان می دهد اولین اجرای خط سیاه است، 0
نشان می دهد اولین اجرای خط سفید است و -42
نشان می دهد که آرایه به پایان رسیده است. دومی int
طول اجرا را نشان می دهد و بین سیاه و سفید به عقب و جلو می رود تا زمانی که -1
پیدا شود، که نشان دهنده پایان ردیف است. به عنوان مثال، اگر وجود داشت:
پنهان کردن کد کپی
1, 64, 32, 32, -1
…64 پیکسل سیاه کشیده می شود، سپس 32 پیکسل سفید، سپس 32 پیکسل سیاه.
این کار بهتر عمل کرد زیرا اندازه طرح اکنون به اندازه کافی کوچک بود تا در آردوینو آپلود شود، اما آرایه برای پشته آردوینو خیلی بزرگ بود. وقتی کل آرایه را وارد کردم، آردوینو خراب شد و بارها و بارها خودش را دوباره راه اندازی کرد، و متوجه شدم که اگر فقط 1/4 از کل آرایه را وارد کنم، خوب کار می کند، بنابراین رویکرد RLE نیز کار نمی کند.
پس از انجام برخی تحقیقات، متوجه شدم که مقادیر زیادی داده باید با استفاده از کلمه کلیدی در حافظه فلش ذخیره شود PROGMEM
. با استفاده از PROGMEM
آرایه خام به صورت زیر اعلام می شود:
پنهان کردن کد کپی
static prog_uchar bits[] PROGMEM = {
سپس داده ها از حافظه فلش از طریق pgm_read_byte_near()
:
پنهان کردن کد کپی
char val = pgm_read_byte_near(bits + (i + (128 * j)));
… و سپس هر بار یک پیکسل از طریق GLCD.SetDot()
.
علاوه بر این که متوجه شدم باید داده ها را در حافظه فلش ذخیره کنم، همچنین متوجه شدم که نسخه بتا کتابخانه KS0108 یک تابع جدید نیز دارد DrawBitmap()
. نسخه دوم CodeProjectLogo
(فقط عبارت را نظر دهید #define USE_SET_DOT
) آرایه را به صورت زیر اعلام می کند: