고급 예제

다양한 도구들을 가지고 마음껏 응용해보세요.

Nokia 5110-이미지 출력

2015-04-16 16:32:05

개요


출처 : 노키아 5110 LCD - sparkfun

 

이번에는 Nokia 5110 LCD에 이미지를 출력해 보겠습니다.

Nokia 5110 LCD는 84x48의 픽셀수를 가지고 있으며 그래픽 LCD이기 때문에 한글, 영문, 도형, 이미지 등 다양하게 사용이 가능한 LCD입니다.

사용핀수도 적고 필요 전압도 낮기 때문에 많이 사용되는 LCD중 하나 입니다.

PCD8544 CMOS LCD 콘트롤러가 내장되어 있으며 Serial bus를 사용해서 아두이노와 통신이 가능합니다.

 
 
픽셀수가 적기 때문에 배열수가 적지만 그만큼 출력되는 이미지 또한 제약이 많다는 점은 단점입니다.
이미지 출력을 위해 Image2GLCD라는 프로그램을 이용해 보겠습니다.
 
 

필요한 부품 목록

 
NO 부품명 수량 상세설명
1 오렌지 보드 1 아두이노
2 Nokia 5110 LCD 1 LCD
5 10KΩ 저항 4 저항
6 1KΩ 저항 1 저항
7 330Ω 저항 1 저항
8 브레드보드 1 브레드보드
9 점퍼케이블 15 점퍼케이블
 
부품명 오렌지 보드 Nokia 5110 LCD 10KΩ 저항 1KΩ 저항
파트
부품명 330Ω 저항 브레드보드 점퍼케이블
파트

 하드웨어 Making

 

 

소프트웨어 coding

 

이미지를 띄우기 위해서는 이미지의 픽셀을 배열로 바꿔줄 수 있는 프로그램이 필요합니다.

여기서는 Image2GLCD라는 프로그램을 이용하여 이미지를 배열로 바꿔보겠습니다.

아래 주소에서 내려받을 수 있으며 다양만 포맷의 이미지파일을 픽셀로 변환하여 그래픽LCD에 이미지를 띄울 수 있게 합니다.

http://www.avrportal.com/?page=image2glcd

 

Image2GLCD를 실행시키면 아래와 같은 화면이 뜹니다. 

Bit & Byte Alignment를 통해 이미지를 띄우는 정렬방식을 지정할 수 있고 이미지 픽셀또한 지정 가능합니다.

잠깐 MSB와 LSB에 대하여 설명하면

MSB : most significant bit의 약자로 최상위 비트를 의미합니다. 예를 들어 16진수 7386AB54가 있다면 가장 최상위 비트인 7이 MSB가 됩니다. 

LSB : least significant bit의 약자로 최하위 비트를 의미합니다. 예를 들어 16진수 7386AB54가 있다면 가장 최하위 비트인 4가 LSB가 됩니다.

 

Nokia 5110의 경우에는 아래 사진과 같이 LSB부터 MSB까지 위에서 아래로 픽셀을 뿌리며 이미지를 출력합니다.

그렇기 때문에 Bit & Byte Alignment을 LSB to MSB Top to Bottom으로 선택합니다.

 

Nokia 5110은 84x48이기 때문에 custom을 눌러 84x48로 맞춰줍니다.

 

아래의 이미지를 픽셀로 만들어서 띄워보겠습니다.

 

아래의 코드를 복사합니다.

위의 그림을 Image2GLCD에 넣고 save를 시키게 되면 Image2GLCD라는 확장자가 .c인 파일이 생기게 됩니다.(이 파일은 c파일이지만 메모장으로도 열기가 가능합니다.)

이 파일을 열게 되면 아래와 같이 배열 파일이 보입니다.

배열안의 내용을 복사해서 코드 배열에 붙여넣기 합니다.

 

이 코드를 실행시키면 Nokia 5110 LCD에서 출력하고자 하는 이미지가 보이게 됩니다.

 

/*Sparkfun참조*/

#define PIN_SCE   11 //Pin 11 on LCD
#define PIN_RESET 12 //Pin 12 on LCD
#define PIN_DC    10 //Pin 10 on LCD
#define PIN_SDIN  9 //Pin 9 on LCD
#define PIN_SCLK  8 //Pin 8 on LCD

// The DC pin tells the LCD if we are sending a command or data
#define LCD_COMMAND 0 
#define LCD_DATA  1

// You may find a different size screen, but this one is 84 by 48 pixels
#define LCD_X     84
#define LCD_Y     48

// This is the SFE flame in bit form
char img [] = {
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFB, 
	0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 
	0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFF, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xEF, 0xEF, 0xDF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 
	0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x0F, 0x0F, 0x0F, 
	0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0F, 
	0x0F, 0x0F, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 
	0x01, 0x01, 0xC1, 0xC1, 0xC0, 0xC2, 0x00, 0x04, 0x08, 0x10, 0xE0, 0x20, 0xE0, 0x18, 0x08, 0x04, 
	0x02, 0x02, 0x01, 0x01, 0x01, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 
	0x00, 0x02, 0x04, 0x04, 0x08, 0x38, 0xC8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 
	0x01, 0x0B, 0x0F, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x10, 0x10, 0x00, 0x20, 0x20, 
	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x10, 0x10, 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 
	0x01, 0x06, 0x0C, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 
	0x00, 0x00, 0x20, 0x20, 0x00, 0x10, 0x10, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 
	0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x40, 0x40, 0x40, 
	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 
	0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0xF0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xF0, 
	0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 
	0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 
	0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 
};

void setup() {
	LCDInit(); // Init the LCD
}

void loop() {
	LCDClear();
	LCDBitmap(img);
	delay(1000);
}

void gotoXY(int x, int y) {
	LCDWrite(0, 0x80 | x);  // Column.
	LCDWrite(0, 0x40 | y);  // Row.  ?
}

// This takes a large array of bits and sends them to the LCD
void LCDBitmap(char my_array[]) {
	for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++) {
		LCDWrite(LCD_DATA, my_array[index]);
	}
}
	
// Clears the LCD by writing zeros to the entire screen
void LCDClear(void) {
	for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++) {
		LCDWrite(LCD_DATA, 0x00);	
	}
	
	// After we clear the display, return to the home position
	gotoXY(0, 0); 
}

// This sends the magical commands to the PCD8544
void LCDInit(void) {
	// Configure control pins
	pinMode(PIN_SCE, OUTPUT);
	pinMode(PIN_RESET, OUTPUT);
	pinMode(PIN_DC, OUTPUT);
	pinMode(PIN_SDIN, OUTPUT);
	pinMode(PIN_SCLK, OUTPUT);
	
	// Reset the LCD to a known state
	digitalWrite(PIN_RESET, LOW);
	digitalWrite(PIN_RESET, HIGH);
	
	// Tell LCD that extended commands follow
	LCDWrite(LCD_COMMAND, 0x21); 
	// Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
	LCDWrite(LCD_COMMAND, 0xB0); 
	// Set Temp coefficent
	LCDWrite(LCD_COMMAND, 0x04); 
	// LCD bias mode 1:48: Try 0x13 or 0x14
	LCDWrite(LCD_COMMAND, 0x14); 
	
	// We must send 0x20 before modifying the display control mode
	LCDWrite(LCD_COMMAND, 0x20); 
	// Set display control, normal mode. 0x0D for inverse
	LCDWrite(LCD_COMMAND, 0x0C); 
}

//There are two memory banks in the LCD, data/RAM and commands. This 
//function sets the DC pin high or low depending, and then sends
//the data byte
void LCDWrite(byte data_or_command, byte data) {
	//Tell the LCD that we are writing either to data or a command
	digitalWrite(PIN_DC, data_or_command); 
	
	//Send the data
	digitalWrite(PIN_SCE, LOW);
	shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
	digitalWrite(PIN_SCE, HIGH);
}

 

 

코드를 실행하면 아래와 같이 Nokia5110LCD에 띄워진 이미지를 볼 수 있습니다.

kocoafabeditor

항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!

nokia5110, 아두이노, 오렌지보드