Thermal Receipt Printer (영수증 출력 열전사 프린터)

영수증 출력용 프린터라고도 하고 열전사 프린터라고도 합니다. 상점에서 흔히 사용하는, 특수 종이에 열로 명암을 만드는 작은 프린터인데 DIY 용으로도 각광받는 프린터입니다. 그리고 생각과는 달리 사용법도 쉽고 문자, 바코드, QR코드, 이미지 출력이 가능하며 라이브러리도 잘 갖춰져 있어 매우 유용합니다!!

Adafruit에서 DIY용으로 적합하게 수정된 프린터를 팔 뿐 아니라 Tutorial도 자세하게 제공하고 있습니다. library는 다양한 DIY 사이트에서 개발해서 공개하고 있는데 adafruit 라이브러리를 추천합니다.

1. Thermal Receipt Printer

특수 종이에 열을 가해 프린트 하는 방식인 Thermal Dot Printer 는 주로 영수증 출력용으로 사용되고 있습니다. 작고 가볍고 유지비용도 저렴해서 최근에는 아두이노와 같은 Micro-processor 와 함께 취미용으로도 많이 사용됩니다. 관련된 프로젝트 들이 해외 사이트에 많이 소개되어 있습니다.

2.25” wide thermal 용지를 사용하고 5~9V 1.5Amps 어댑터로 동작가능 하지만 내부에 히터가 있기 때문에 5V 2A 이상 가능한 어댑터 사용을 권장합니다. 어댑터 용량에 따라 프린터 품질과 속도가 좌우된다고 합니다. USB 전원으로는 동작이 안됩니다!!

프린터 헤드는 거의 마라톤 길이 만큼 출력이 가능하다고 합니다. 맘 놓고 양껏 뽑으셔도 좋습니다.

아래와 같은 기능을 지원합니다.

  • Printing with small, medium and large text
  • Bold, underline and inverted text
  • Variable line spacing
  • Left, center and right justification
  • Barcodes in the following standard formats: UPC A, UPC E, EAN13, EAN8, CODE39, I25, CODEBAR, CODE93, CODE128, CODE11 and MSI – with adjustable barcode height
  • Custom monochrome bitmap graphics (1bit bitmap)
  • SW적 처리를 통해 QR code 프린트 가능

2. 프린터 셋업, 동작 확인

프린터를 받으면 아래 구성품들이 있습니다. 프린터와 전원 케이블, Serial 통신 케이블, 테스트 출력 예제 종이, 프린터용 용지 롤. 보통 어댑터가 포함되지 않은 경우가 많으므로 어댑터 포함유무 확인하고 같이 구매하는 것이 좋습니다. 용지도 넉넉히 구매 하시고…

a1

뚜껑 옆 레버를 밀어 올려서 뚜껑을 열고 전용 용지를 아래와 같이 장착합니다. 용지가 두꺼워 안들어가면 용지를 적당히 잘라내시고, 방향을 아래 사진과 똑같이 맞춰줘야 정상 동작합니다.

a2

용지를 장착하고 아랫면을 봅니다.

a4

두 개의 케이블 소켓이 있는데 왼쪽이 전원, 오른쪽이 통신용 소켓입니다. 일단 전원이 5~9V 어댑터에 연결되도록 하면 됩니다.

프린터 윗면을 보면 왼쪽 위 LED 와 함께 버튼이 딱 하나 있습니다. Feed 버튼입니다. 버튼을 누르면 용지가 한 라인 간격으로 밀려 나오도록 되어 있습니다.

a3

이 버튼을 누른 상태에서 어댑터 전원을 연결하면 테스트 출력이 됩니다. 각종 폰트 리스트와 프린터 사양이 출력되는데 여기서 BAUDRATE 값을 확인해야 합니다. 이 부분은 아두이노 소스에서 사용되는 부분입니다. 보통 9600 또는 19200으로 설정되어 있습니다.

a5

3. 연결 방법

구슬이 서 말이라도 꿰어야죠. 아두이노에 연결해서 사용해보도록 하겠습니다.

주의!!! 아두이노에서 프린터로 데이터를 전송하기 위해서 5V TTL serial connection을 사용합니다. 이 부분은PC의 9핀 시리얼 포트인 10V RS232 serial 과는 호환되지 않습니다. PC에 직접 연결할 경우 프린터에 손상을 초래할 수 있습니다. (프린터 제원을 살펴보고 이 부분을 확인하세요.)

뒷면 통신용 소켓에 케이블을 끼운뒤 다시 아두이노에 아래와 같이 연결해주면 됩니다.

  •  프린터 ==> 아두이노
  • RX(노란색) ==> D3 (또는 D6)
  • TX(녹색) ==> D2 (또는 D5)
  • GND ==> GND

프린터의 3가닥 데이터 케이블(green, yellow, black : 제품마다 틀릴 수 있음)을 아두이노 D2, D3, GND 에 연결합니다. Adafruit 라이브러리를 사용할 경우 D5(- green), D6(- yellow), GND(- black) 를 사용하므로 편하신 대로 연결하세요. 아두이노에서 SoftwareSerial 을 통해 통신을 하기 때문에 아두이노 핀은 변경이 가능합니다. 자신의 설정에 맞게 소스코드 수정만 해주면 됩니다.

통신용 핀 연결과는 별도는 프린터의 전원은 어댑터를 통해 공급되어야 합니다.

4. 소스 코드 (스케치)

먼저 간단히 테스트를 해보죠. 아래 소스코드를 올려서 프린터가 출력되는지 확인해보세요. 아두이노의 D2, D3 핀에 프린터의 TX, RX 핀을 연결했을 때 기준입니다.

/*
 Example 38.1 - Sparkfun Thermal Printer Test (COM-10438)
 http://tronixstuff.com/tutorials > chapter 38
 Based on code by Nathan Seidle of Spark Fun Electronics 2011
 Modified by HardCopyWorld.com
*/
#include <SoftwareSerial.h>
SoftwareSerial Thermal(2, 3);
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15; 
char printBreakTime = 15;

void setup() {
  Serial.begin(57600); // for debug info to serial monitor
  Thermal.begin(19200); // to write to our new printer
  initPrinter();
}
void initPrinter() {
  //Modify the print speed and heat
  Thermal.write(27);
  Thermal.write(55);
  Thermal.write(7); //Default 64 dots = 8*('7'+1)
  Thermal.write(heatTime); //Default 80 or 800us
  Thermal.write(heatInterval); //Default 2 or 20us
  //Modify the print density and timeout
  Thermal.write(18);
  Thermal.write(35);
  int printSetting = (printDensity<<4) | printBreakTime;
  Thermal.write(printSetting); //Combination of printDensity and printBreakTime
  Serial.println();
  Serial.println("Printer ready"); 
}
void loop() {
  Thermal.println(" Visit http://hardcopyworld.com ");
  Thermal.write(10); //Sends the LF to the printer, advances the paper
  Thermal.print(" Millis = ");
  Thermal.println(millis()); 
  Thermal.write(10);
  Thermal.write(10); 
  do { } while (1>0);
}

loop() 함수 안에서 간단한 문자열을 출력하는 예제입니다. initPrinter() 함수로 프린터 초기화 해주고 Thermal.print(), Thermal.println() 함수로 문자열을 마음대로 출력할 수 있습니다.

조금 더 많은 예제는 아래 링크에서 확인 하실 수 있습니다. 이 방법을 이용하면 라이브러리 없이도 간단한 프린터 출력 작업이 가능합니다.

tronixstuff tutorial

위 링크의 예제는 간단한 문자열 출력에는 유용하지만 이미지, 바코드, QR코드, 다양한 문자셋을 사용하는데는 적합치 않습니다. 프린터의 기능을 십분 활용하기 위해서는 Adafruit 라이브러리를 사용하는 것이 좋습니다.

GitHub 에서 Adafruit Thermal Printer Library 를 다운로드 받습니다. 압축을 풀고 라이브러리를 아두이노 IDE 라이브러리 폴더에 복사해 넣어줍니다. 아두이노 IDE 1.0 이전 버전을 사용하는 경우는 NewSoftSerial 라이브러리를 사용해야 합니다. Download NewSoftSerial 링크에서 다운로드 받아서 라이브러리 설치를 해줍니다. 최신 IDE 를 사용하는 경우 NewSoftSerial 라이브러리 설치는 필요 없습니다.

라이브러리 설치가 끝나면 File→Sketchbook→Libraries→Adafruit_Thermal→A_printertest 예제를 불러옵니다.

먼저 아래와 같이 설정되어 있는 통신용 핀 번호를 확인해야 합니다. 만약 자신이 연결한 핀 번호와 다르다면 자신의 연결 상태에 맞게 수정해주면 됩니다.

#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

이 코드를 아두이노에 올려서 프린터 테스트를 해보면 아래와 같이 출력됩니다.

a6

만약 문제가 생긴다면…

  • 용지가 너무 빡빡하지 않게 바른 방향으로 들어가 있는지 확인
  • 프린터의 전원이 충분히 공급되는지 확인
  • 프린터의 녹색등이 점멸하는지(정상상태) 확인
  • 테스트 인쇄가 정상적으로 진행되는지 확인
  • 통신용 핀 TX, RX 번호가 맞는지 확인, GND 연결도 되었는지 확인
  • BAUDRATE 값이 바르게 설정되어 있는지 확인

BAUDRATE 값은 Adafruit 라이브러리 폴더에서 Adafruit_Thermal.cpp 파일에서 확인할 수 있습니다. 아래처럼 정의되어 있는데 자신의 BAUDRATE 값과 같은지 확인합니다.

#define BAUDRATE  19200

예제 소스에서도 SoftwareSerial 초기화 하는 부분을 확인해줍니다.

mySerial.begin(19200);  // Initialize SoftwareSerial

같은 방법으로 Adafruit에서 제공하는 다른 예제들도 출력해보세요. 예제의 코드를 확인하면 프린터 출력에 필요한 대부분의 방법을 익힐 수 있습니다.

5. 텍스트 출력하기

Adafruit 라이브러리의 예제 소스코드를 분석해보면 텍스트 출력과 이미지 출력에 대한 내용을 알 수 있을 것입니다. 간단하게 정리하면…

  • 반전된 문자:
    inverseOn() — 검은 배경에 흰 문자로 출력, inverseOff() 를 호출하면 원래 상태로 되돌림
  • 2배 높이로 늘이기:
    doubleHeightOn() — 호출시 글자가 2배 크기로 길어짐, doubleHeightOff() 호출하면 원래크기로 복귀
  • 우측, 중앙, 좌측 정렬:
    문자열을 정렬하는 방식. justify(‘R’)justify(‘C’), justify(‘L’) 로 변경. Left(좌측 정렬)이 기본.
  • Bold 문자:
    boldOn(), boldOff()
  • Underlined 문자:
    underlineOn(), underlineOff()
  • Large/Medium/Small 크기 설정:
    기본은 small 이며 medium은 높이가 두배, large는 높이-넓이 모두 2배가 됨. setSize(‘L’),setSize(‘M’) or setSize(‘S’)
  • 행 간격:
    setLineHeight(<numpix>) – numpix 값으로 픽셀값 지정. 최소 24 (간격 없음). 기본은 32.

6. 이미지 출력하기

프린터는 pixel 하나당 1bit의 정보만을 가집니다. 즉 특정 픽셀이 on 이면 black, off 이면 white로 출력합니다. 따라서 비트맵 이미지의 데이터도 1bit bitmap으로 저장되어 있어야 합니다. 원하는 이미지를 일일이 이렇게 변환하기는 프린터 사용하기보다 더 어려운 작업이므로 자동화 된 툴을 사용해야 합니다. 내용을 참조한 Adafruit.com 에서는  LCD Assistant 프로그램을 추천합니다만 (해외 사이트에서는 프린터, LCD 사용할 때 주로 이 프로그램을 사용합니다.) 실제 사용해보면 원하는대로 변환이 잘 되지 않고 코드에 넣었을 때 제대로 동작하지 않는 경우가 많았습니다. 국내 개발자 분이 개발한 ezCircuits – ezBMP 프로그램이 100배 더 쉽고 변환이 편리합니다. 강추 완소 필수 변환 프로그램입니다.

http://ezcircuits.net/zbxe/24758

여기에 비트맵 이미지를 넣고 변환하면 xxx.c 파일로 결과를 만들어줍니다. 아래와 같은 형식으로 나오는데

const unsigned char xxxxx[] = {
  0x00,0x03,0x1c,0xe0,0x1f,0xff
};

이걸 그대로 사용하면 에러가 발생하기 때문에 아래와 같이 변경해주어야 합니다.

const unsigned char xxx[] ==> const unsigned char PROGMEM xxx[]

추가된 PROGMEM 지시자는 코드에 선언된 변수를 메모리의 프로그램 영역으로 올려주는 역할을 합니다. 뭔 소리냐면… 

아두이노 보드는 프로그램(Flash) 영역 32KB, 실행시 코드에 포함된 변수 할당을 위해 사용하는 RAM 영역 2KB, 디스크 드라이브 처럼 읽고 쓰기가 가능한 EEPROM 1KB 를 가지고 있습니다. 컴파일하고 업로드하는 과정을 아두이노 IDE에서 수행하면 코드 영역(32KB)에 바이너리가 올라가고, 실제 프로그램이 실행될 때 변수를 저장하는 영역은 2KB에 불과합니다. 2KB를 프로그램에 포함된 라이브러리와 같이 써야하기 때문에 이미지 처럼 큰 데이터를 일반 변수로 선언하고 사용하면 램이 심각하게 부족해집니다. 그래서 이미지를 프로그램 영역에 포함시키고 Read-only 로 사용하는 겁니다. 이해가 안되시면 그냥 그러려니 하시고 위 처럼 변환하면 됩니다.

이제 이 이미지를 코드에 심어줍니다. 작업중인 파일 상단에 넣어줘도 되고, 이미지 변수들만 모아서 헤더 파일로 만들어준 다음 작업중인 파일에서 include 해줘도 됩니다. 이렇게 선언된 이미지를 사용할 때는 아래와 같이 합니다.

printBitmap(width, height, image)

a6

팁 하나 더… 이미지를 배열로 만들어서 인덱스 값으로 접근하고 싶으면 아래와 같이 사용하세요.

선언 : PROGMEM const unsigned char* bitmap_array[] = { ICON_BITMAP_0, ICON_BITMAP_1, ………. }

호출 : display.drawBitmap(x, y, (const unsigned char*)pgm_read_word(&(bitmap_array[icon_num])));

7. 바코드, QR 코드 출력하기

프린터는 11 개의 1D(1차원, 직선형) 바코드를 지원합니다 – UPC A, UPC E, EAN13, EAN8, CODE39, I25, CODEBAR, CODE93, CODE128, CODE11MSI. 본인의 프로젝트에 맞는 바코드는 다음 사이트에서 확인하고 선택하세요.

http://en.wikipedia.org/wiki/Barcodes#Linear_barcodes

1D 바코드 출력은 아래 함수를 사용하세요.

printBarcode("barcodedata", BARCODETYPE)

BARCODETYPE 으로 사용 가능한 값은 UPC_A, UPC_E, EAN13, EAN8, CODE39, I25, CODEBAR, CODE93, CODE128, CODE11MSI 입니다.

QR 코드와 같은 2D 바코드를 지원하기 위해서는 먼저 자신의 QR 코드를 생성해서 이미지 파일로 변환하고, 6장에서 설명한 이미지 출력 방법으로 출력하면 됩니다. 또는 아두이노에서 QR코드 생성 라이브러리를 이용해 문자열을 QR코드로 변환해서 사용할 수도 있습니다. (메모리 많이 잡아먹으므로 주의!!) 자세한 방법은 아래 링크를 참고하세요.

https://github.com/sparkfun/Thermal_Printer/tree/master/QRprint

8. 프린터 해킹!!

프린터의 속도를 높이는 방법이 있습니다.

heatTime = 120; //80 is default from page 23 of datasheet.
heatInterval = 50; //2 is default from page 23 of datasheet.

간단히 위 두 개의 파라미터를 Adafruit 라이브러리에서 찾아 변경해주면 됩니다. 1~255 까지의 값으로 변경이 가능한데 값이 작을수록 속도가 빨라집니다. 대신 프린트 품질(농도)이 떨어지게 됩니다. 프린트 품질이 중요하지 않다면 이 값을 작게 바꿔서 실험해보세요.

하드웨어적인 처리를 통해 프린터 속도를 향상시킬수도 있습니다. 다만 과정이 좀 더 복잡하고 하드웨어적인 손상을 부를 수 있으므로 부셔먹어도 좋다는 각오가 되어 있을 때 도전해보세요. 이 방법을 사용하면 빠른 속도로 이미지 출력이 가능합니다.

https://learn.adafruit.com/mini-thermal-receipt-printer/hacking

components_chrysler

참고자료 :

You may also like...