개요

작은 터치스크린과 열전사 프린터를 내장한 즉석 사진기를 제작했다. 버튼이나 터치스크린을 눌러서 사진을 찍을 수 있고 찍은 사진을 바로 영수증 용지에 인쇄해주는 물건이다.

제작 과정

재료

  • 라즈베리 파이

  • 라즈베리 파이용 카메라 모듈

  • 2.4인치 LCD

  • 열전사 프린터

  • USB to Serial interface

  • 18650 배터리 2개

  • DC-DC 스텝 다운 컨버터

  • 버튼 스위치

라즈베리 파이 세팅

우선 라즈비안 불스아이 버전을 설치했다. 사실 버전별로 무슨 차이가 있는지 몰라서 그냥 설치한 거였는데, 최신 버전의 라즈비안은 기존 카메라 라이브러리가 새로운 걸로 대체되어서 파이썬의 picamera 를 사용할 수 없다는 이야기가 있었다. 다행히 raspi-config를 이용해서 레거시 카메라 인터페이스를 활성화 할 수 있었다. 나는 단순히 내가 만든 카메라 앱만 동작시키면 되기 때문에 무겁고 필요없는 gui 는 비활성화하고 파이썬과 각종 필요한 라이브러리를 설치했다.

LCD 준비

LCD 를 사긴 했지만 알리제품이 그렇듯이 설명이 부실해서 여기저기 뒤져서 세팅법을 찾아야 했다. 가장 도움이 된 페이지는 여기. 설치 후 기본 디스플레이를 lcd로 설정하고 프레임버퍼도 세팅하고 자잘한 작업을 해줬다.

카메라

카메라는 뭐 그냥 연결하면 된다. 잘 연결되었는지는 raspistill 같은 명령어로 테스트하면 끗

버튼

이것도 그냥 원하는 GPIO 핀과 GND에 연결하면 끝이다. 집에 굴러다니던 체리 적축 스위치를 하나 주워다 달았다.

열전사 프린터

이번 프로젝트에서 가장 문제가 되던 부분이 이 지점이었다. 대부분의 열전사 프린터는 사실 이미지 인쇄를 위한 물건이 아니다보니 고해상도의 이미지를 출력하려고 하면 개똥같은 결과물을 내놓기 일쑤다. 여러 개의 프린터를 주문해서 이리저리 테스트해봤지만 만족할만한 품질이 아니었는데, 유독 하나가 이미지를 잘 뽑아줘서 그걸 쓰려고 했지만 테스트 과정에서 부주의하게 배터리를 반대로 연결해서 회로가 타버리고 말았다..

다시 주문한 물건들도 죄다 이미지 품질이 나빠서 이대로 좌절해야 하나 싶었는데, 마지막으로 주문한 프린터의 판매자가 상당히 친절해서 프린터 세팅 프로그램을 전달 받아 프린터 펌웨어의 세팅을 변경해서 해결할 수 있었다.

열전사 프린터는 생각보다 순간 소모 전류가 높다(2A 정도). 원래 계획은 그냥 3.7v 리튬 폴리머 배터리랑 충전 회로를 포함해서 배터리를 내장형으로 하는 거였는데, 프린터가 5~9V 전압에 2A를 요구해버리니까 거기 맞는 DC-DC 컨버터를 찾아야 하는 문제가 있었다. 그래서 회로를 변경해서 충전을 포기하고 18650 두 개를 직렬 연결해서 전압과 전류를 맞춰주고 라즈베리파이에 들어가는 전원을 스텝다운 회로를 거쳐서 공급하게 했다.

열전사 프린터 업계에는 일종의 업계 표준이랄 수 있는 ESC/POS 라는 명령어셋이 있었다.

그런데 이것도 프린터마다 지원 범위 같은 게 조금씩 다르고 동작도 달라서 프린터 부품을 교체할때마다 삽질을 엄청나게 해야 했다. 마지막으로 샀던 프린터는 다행히 제조사측이 친절해서 매뉴얼을 얻을 수 있었는데 이게 많이 도움이 되었다.

저 명령어를 지원하도록 간단하게 시리얼 통신으로 인쇄하는 루틴을 직접 제작해서 테스트하면 끗

전원

위 프린터 부분에서도 썼지만 전압과 방전율때문에 리튬 폴리머 싱글셀을 포기하고 18650 배터리 두 개를 직렬로 연결해서 사용했다. 최대 4.2 x 2 = 8.4v 에서 평균적으로 3.7 x 2 = 7.4v 정도가 나오고, 방전율도 높기 때문에 프린터를 충분히 구동시킬 수 있었다. 방전율에 여유가 있기 때문에 거기에 추가로 스텝다운 컨버터를 달아 라즈베리 파이와 카메라 모듈, lcd 등을 동시에 구동해도 여유가 있었다.

다만 아쉬운 점이라면 직렬 연결을 하게 만들면서 충전 회로를 넣기가 애매해져서 포기한 점이다. 차후 개량판을 만든다면 이 부분을 보강해야 할 것 같다.

소프트웨어

앱 화면

GUI 환경을 없앴기 때문에 그래픽을 표현하기 위해서는 프레임버퍼를 직접 건드려야 했는데, pygame 을 사용하기로 했다. 사실 고작 이미지만 그리면 되는건데 굳이 쓰기엔 과하지 않나 하는 생각도 들었지만... 귀찮아서...

카메라 이미지를 매 프레임 받아서 화면에 지속적으로 뿌려주고 모드에 따라 추가적인 이미지 (카운트 다운을 나타내는 숫자라던지)를 표시하도록 하는게 거의 전부라서 별다를 건 없었다. 다만 lcd 화면을 가리키는 프레임버퍼를 사용하도록 주의만 하면 된다.

입력

키보드

완성될 기기에는 키보드가 없지만 개발중의 편의를 위해서 우선 키보드 입력을 받도록 했다. pygame이 지원하는 입력 이벤트를 이용해서 입력받은 키를 매 프레임 보관하고 스페이스바가 입력되었을 경우 카운트다운을 시작하도록 했다.

터치스크린

터치스크린은 어차피 내부적으로 마우스로 인식되기 때문에 그냥 어디든 마우스가 클릭된 경우를 감지하면 된다. 마우스가 클릭되었을 경우 스페이스바가 눌린 것으로 취급되도록 했다.

버튼 사용

GPIO 핀에 버튼을 연결하고 해당 버튼이 눌렸는지를 확인하면 된다. RPi.GPIO 라이브러리를 썼고, 풀업 모드로 세팅해서 gpio.read 를 했을 때 False 가 나오면 버튼이 눌린 것으로 판단하면 된다. 마찬가지로 매 프레임 검사하다가 버튼이 눌린 경우 스페이스바가 눌린 것으로 취급하면 끗.

이미지 처리

프린터가 흑백 비트맵만 인쇄할 수 있기 때문에 이미지를 프린터가 출력할 수 있는 사이즈로 리사이징 한 뒤에 디더링으로 흑백으로 처리해서 bytes 로 만들었다. 디더링 알고리즘은 처음에는 플로이드-스테인버그 알고리즘을 사용했었다가 조금 더 인물 사진에 적합한 느낌인 앳킨슨 방식으로 변경했다.

비동기

이미지 처리나 사진 출력에 시간이 꽤 걸리는데 그 동안 화면이 멈춰있으면 안되기 때문에 이미지 처리 함수와 사진 출력 함수를 멀티프로세스로 분리했다. 각각의 함수와는 피클링이 가능한 bytes 형태로 데이터를 주고받도록 하고 각 부분이 처리되는 동안 화면에는 처리중이라는 것을 나타내는 애니메이션을 표시하도록 했다.

하드웨어

케이스 설계

처음에는 그나마 유일하게 쓸 줄 아는 스케치업을 통해서 케이스를 디자인해보려고 했지만 생각처럼 쉽지 않았다. 툴이 아니라 사람이 문제인건 알지만 그래도 왠지 툴을 탓하고 싶어서 개인용으로 무료로 사용할 수 있는 Fusion360을 써보기로 했다.

사실 제일 어려웠던 부분이 바로 이 부분이었다. 나는 하드웨어 설계에 대한 경험이 너무 없기 때문에 실제로 뽑아보면 조립이 불가능하다거나 공차가 너무 크다거나 제대로 고정이 되지 않는다거나... 하여튼 아주 힘들었는데 특히 가장 문제가 되었던 부분은 배터리 홀더인데, 배터리 뚜껑을 고정하는 방법은 아직도 제대로 되지 않아서 아쉬운 부분이다. 가능하면 추후에 개선해보려고 한다.

회로 구성

특별히 pcb 설계가 필요한 정도는 아니고 각 부품을 잘 연결하는 정도면 된다. 납땜이 필요한 부분은 버튼과 전원 스위치 정도였고 그 외의 부분은 모두 커넥터로 처리해서 납땜 없이 연결할 수 있도록 했다.

처음엔 라즈베리 파이와 프린터간의 통신은 GPIO를 통해 직접 해볼까 생각했었는데, LCD가 gpio 핀을 절반 이상 잡아먹고 있어서 그 방법은 포기하고 라즈베리파이의 usb 포트에 usb-to-serial 인터페이스를 연결하고 거기에 프린터를 연결하는 방식으로 처리했다.

배터리에서 나온 라인은 우선 전원 스위치를 거친 후 양쪽으로 나뉘어서 한 쪽은 직접 프린터로 연결되고 다른 한 쪽은 DC-DC 컨버터로 간다. DC-DC 컨버터에서 5v로 조정된 선은 lcd 에 노출된 5v / gnd 로 가고 lcd가 라즈베리와 공유하는 핀을 통해서 lcd/라즈베리 양쪽에 전원이 공급된다.

완성품

18650 배터리 두 개를 넣고 전원을 켜면 부팅 과정을 거친 후 바로 카메라 앱으로 진입한다. 이 상태에서 버튼을 누르거나 화면을 터치하면 5초간의 카운트다운을 거친 후 사진이 찍히고, 찍힌 사진은 디더링되어 프린터로 전송된다. 프린터 전송이 끝나면 다시 사진을 찍을 수 있는 모드로 돌아간다.

처음에는 그냥 간단하게 생각해서 시작했던 프로젝트인데 생각보다 과정이 복잡해서 재밌었다. 이걸 정말 제품화하려면 배터리를 충전할 수 있도록 충전 회로를 구성하고 배터리 커버를 개선하거나 아예 내장해버리는 게 필요하겠지만 당장은 어차피 사용자가 아내 뿐이기 때문에 굳이 그렇게까지 할 필요가 있을까 싶긴 하다. 아니면 아예 배터리를 빼고 smps를 달아서 전원을 유선으로 공급받게 해도 괜찮을 것 같다.