2016년 12월 20일 화요일

RPi VNC 해상도 변경

라즈베리 파이에 기본으로 포함된 RealVNC를 통해 접속해보니 화면 해상도가 낮아서 불편했다. 헤드레스일 때 기본 해상도가 640×480인 모양이다. 검색을 통해 알아낸 방법은 약간 의외였다.

/boot/config.txt에서 hdmi_로 시작하는 항목 세 개를 다음과 같이 편집하는 것이다.

hdmi_force_hotplug=1
hdmi_group=2
hdmi_mode=16

각 항목의 의미에 대해서는 문서를 참조.

2016년 12월 6일 화요일

쇼핑 리스트

번역 중인 책에 나온 전자부품들을 구입하느라 며칠 동안 디바이스마트와 알리익스프레스에서 열심히 쇼핑을 했다.


주문내역


구입처 별로 비싼 물건부터. 가격은 변동될 수 있음.

디바이스마트



해외구매 상품 때문에 전체적인 배송이 늦어지는 것이 싫어서, 해외구매 목록의 전체 삭체 버튼을 눌렀다가 국내상품까지 모두 지워지는 바람에 울 뻔 했다. 다행히 맥북에 띄워둔 브라우저에 주문 내역이 남아있어서 다시 주문할 수 있었다.


알리익스프레스




중고나라


  • XBee 시리즈 2



아직 못다 산 것들





알리익스프레스 결제


디바이스마트는 네이버 페이로 결제 완료. 알리에서는 주문 후 결제를 마치지 못했다. 신용카드는 없애버린 지 오래이고, 체크 카드는 얼마 전에 교체발급하면서 실수로 해외결제가 안되는 카드를 받았기 때문이다. 이참에 달러화로 해외 결제 시 수수료를 물지 않는다는 '하나 글로벌페이' 체크카드를 만들어볼까 싶다(해외 결제 체크카드 수수료 및 수수료를 덜 낼 수 있는 카드들 참조).

여러 업체에서 주문했고, 배송 기간도 제각각이라 물건이 도착할 때마다 테스트해보면 될 듯. 이번 달까지 초벌 번역을 끝내고 1~2월은 테스트와 퇴고를 하며 보내야겠다.


라즈비안 SSH


라즈비안의 최신 버전에서는 SSH 서버가 디폴트로 disable된다는 소식(SSH - 위키독스 라즈베리 파이 문서 참조).

2016년 12월 3일 토요일

XBee

번역 중인 라즈베리 파이 책에 ZigBee 통신에 대한 소개가 있어 실습을 위해 구입해볼까하고 알아보다가, 너무나 다양한 제품에 질려버렸다. 물건을 파는 곳에서도 상세 정보를 올려두기는 했지만 뭐가 뭔지 알 수가 없다.

Sparkfun의 XBee Buying Guide를 참고해서, XBee에서 나온 모듈들을 정리해보았다. 보너스로 온라인 쇼핑몰(디바이스마트, 테솔, 가치창조기술, Digi-Key)의 가격비교.(새 창에서 보기).

* 부가세 포함 가격을 계산하여 기재

2016년 11월 28일 월요일

전지

자동차 배터리


자동차(그랜저 XG)의 시동을 걸기 위해 리모콘 버튼을 눌렀는데 아무 반응이 없길래, 처음엔 리모콘의 배터리가 방전되었을 것이라고 생각했다. 다른 리모콘에도 반응이 없어, 열쇠로 문을 열어보니 도난방지기가 작동하지 않고, 계기판에도 불이 들어오지 않았다. 리모콘이 아니라 자동차의 배터리가 방전된 것이었다.

손해보험사의 긴급출동 서비스를 불러서 시동을 걸고 보니, 실내등의 스위치가 ON에 가 있다.

그랜저 XG 용 GB80L 배터리


자동차 리모콘 배터리


차를 물려받을 때 리모콘을 두 개 받았다. 시동 기능이 있는 것과 없는 것. 몇 년이 지나서야, 두 리모콘에 들어가는 전지가 다르다는 것을 깨닫게 되었다.


  • OKA-NO10
    LOCK, UNLOCK, TRK(트렁크 개폐) 버튼이 있다. CR2032 한 개가 들어간다.
  • OKA-NO11
    세 개의 버튼 외에 ENG 버튼이 있어 원격 시동이 가능. CR2016이 두 개 들어간다.


CR2016과 CR2032는 전압이 3 V로 같고, 두께가 각각 1.6 mm와 3.2 mm로 차이가 있다. CR2016을 두 개 겹치면 CR2032와 두께가 같아지지만, 직렬이 되므로 전압은 6 V가 된다. 그렇다면 내 차의 리모콘(OKA-NO11)에 CR2016 두 개 대신에 CR2032 한 개를 넣어도 리모콘이 동작할 지 궁금해졌다. 실험해보았더니 동작하지 않는다.

현대차 용 OKA-NO10 리모콘과 CR2032 배터리

현대차 용 OKA-NO11 리모콘과 CR2016 배터리

배터리 체커


배터리 여러 개를 사용하는 장치가 전원 부족으로 인해 작동하지 않으면 배터리를 전부 교체하는 것이 보통이다. 그런데, 버려지는 여러 개의 배터리 중에 아직 수명이 많이 남은 것도 있지 않을까하는 생각이 들었다. 자동차 리모콘에 들어있던 CR2016 전지 두 개를 일전에 구입한 배터리 체커(BT-168)로 확인해보니 한 개는 정상, 한 개는 다 된 것으로 나왔기 때문이다.

리모콘 실험하러 주차장에 다녀오는 길에, 폐 배터리를 수거하는 주머니에서 건전지를 한 움큼 쥐어와서 확인해보았다. 그 중에 1/3은 GOOD으로 나왔다.

BT-168 배터리 체커

참고



2016년 11월 13일 일요일

TV 리모콘으로 OpenELEC 조작

IR(적외선) 센서를 라즈베리 파이에 연결하여 TV 리모콘으로 OpenELEC을 조작하도록 해보았다.

RPi와 IR 센서(늘솜 NS-GPIO-04)는 지인에게 얻은 것이고, 리모콘은 VHS/DVD 콤보를 중고로 구입할 때 딸려온 것인데 짝이 맞지 않아서인지 작동이 되지 않아 못쓰고 있었다.

IR 센서 연결


센서 모듈은 조립이 된 상태로 받은 것인데, 센서가 기판의 앞면에 붙어있어서 RPi 2에 꽂는데에 문제가 없다. IR 센서는 RPi의 GPIO18에 연결된다(데이터시트).


디바이스 트리 오버레이 추가


RPi에 IR 센서를 연결하였으면 config.txt 파일을 편집해야 한다. OpenELEC에서는 /flash 디렉터리에 있는데, 파일시스템이 읽기 전용으로 마운트되어 있기 때문에 편집하기 위해서는 쓰기가 가능하도록 마운트해야 한다. SSH로 접속하여 다음의 명령을 실행한다.

openelec:/flash # mount | grep flash
/dev/mmcblk0p6 on /flash type vfat (ro,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro)
openelec:/flash # mount -o remount,rw /flash
openelec:/flash # mount | grep flash
/dev/mmcblk0p6 on /flash type vfat (rw,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro)

config.txt에 한 줄을 추가하고 리부트한다.

openelec:/flash # tail -1 config.txt
dtoverlay=lirc-rpi


리모콘 테스트


modprobe를 실행하고,

openelec:~ # modprobe lirc_rpi

lircd 프로세스를 종료한 다음,

openelec:~ # killall lircd

다음의 명령을 실행하고 리모콘을 눌러본다.

openelec:~ # mode2 -d /dev/lirc0
space 16777215
pulse 4528
space 4428
pulse 598
...

리모콘의 버튼을 눌렀을 때 출력이 발생하는 것으로 보아, 리모콘이 작동한다는 것을 알 수 있다.


리모콘 기록


irrecord를 실행하여 리모콘의 버튼 하나하나에 이름을 붙인다.

openelec:~ # irrecord --device=/dev/lirc0 /storage/.config/lircd.conf


irrecord의 지시를 따라 키보드와 리모콘을 누르다보면 다음과 같은 파일이 만들어진다.  /etc/lirc/lircd.conf.rpi 파일과 http://lirc.sourceforge.net/remotes/lg/6710CDAL01G 를 참고했다.

openelec:~/.config # more lircd.conf

# Please make this file available to others
# by sending it to 
#
# this config file was automatically generated
# using lirc-0.9.1-git(default) on Sun Nov 13 02:57:53 2016
#
# contributed by
#
# brand:                       LG
# model no. of remote control: 6710CMAM03C
# devices being controlled by this remote:
#

begin remote

  name  LG_6710CMAM03C2
  bits           16
  flags SPACE_ENC|CONST_LENGTH|REPEAT_HEADER
  eps            30
  aeps          100

  header       4518  4441
  one           580  1653
  zero          580   535
  ptrail        579
  repeat        580  1652
  pre_data_bits   16
  pre_data       0x808
  gap          107643
  toggle_bit_mask 0x0

      begin codes
          KEY_POWER                0x7887
          KEY_MUTE                 0xF807
          KEY_VOLUMEUP             0xE817
          KEY_VOLUMEDOWN           0x6897
          KEY_SLEEP                0x43BC
          KEY_1                    0x827D
          KEY_2                    0x42BD
          KEY_3                    0xC23D
          KEY_4                    0x22DD
          KEY_5                    0xA25D
          KEY_6                    0x629D
          KEY_7                    0xE21D
          KEY_8                    0x12ED
          KEY_9                    0x926D
          KEY_0                    0xD22D
          KEY_UP                   0x20DF
          KEY_DOWN                 0x728D
          KEY_LEFT                 0x609F
          KEY_RIGHT                0xE01F
          KEY_ENTER                0xA05F
          KEY_MENU                 0xB24D
          KEY_STOP                 0x708F
          KEY_CHANNELUP            0xC837
          KEY_CHANNELDOWN          0x48B7
          KEY_RECORD               0xA857
          KEY_STOP                 0x708F
          KEY_FASTFORWARD          0x8877
          KEY_REWIND               0x08F7
          KEY_PLAY                 0xB04F
          KEY_BACK                 0x30CF
      end codes

end remote

리부트하면 OpenELEC에서 리모콘을 사용할 수 있다. 키보드나 스마트폰 앱으로 조작하는 것보다 훨씬 편하다.



참고



2016년 11월 7일 월요일

데비안 8.6 설치

HP tx1000 노트북에 Debian 8.6을 설치했다. 기존에 사용하던 Lubuntu 14.04 LTS에 불만은 없었지만, 번역 중인 라즈베리 파이 책에 소개된 데비안 크로스 툴체인을 테스트하기 위해 Debian을 처음으로 설치해본 것이다.

준비


설치 이미지 다운로드


https://www.debian.org/distrib/에서 small installation image(64-bit PC netinst iso)를 다운로드.

USB 메모리에 복사


다운로드한 이미지를 USB 메모리에 복사.

$ sudo cp debian-8.6.0-amd64-netinst.iso /dev/sda


Debian 설치


리부트 후 CMOS에서 <ESC> 키를 누르고 5. Boot Menu에서 USB Hard Drive 선택.


랜 선을 꽂은 상태로 설치를 했다. 파티션 분할을 자동으로 해줘서 편리했다.


무선랜 활성화


펌웨어 설치


tx1000 노트북의 WiFi 장치인 BCM4311을 사용하기 위해 펌웨어 설치.

$ su -
# apt install firmware-b43-installer


wpa_supplicant

wpa_passphrase 명령에 SSID와 암호를 인자로 주면 wpa_supplicant.conf 파일에 넣을 내용이 출력된다.

# wpa_passphrase myssid my_very_secret_passphrase > /etc/wpa_supplicant/wpa_supplicant.conf

/etc/network/interfaces


/etc/network/interfaces에 다음의 내용을 추가.

auto wlan0
iface wlan0 inet dhcp
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf


한국어 설정


지역 및 언어


언어는 한국어, 형식은 대한민국 선택.

한글 입력 설정


fcitx-hangul 설치.

apt install fcitx-hangul

입력기 설정(im-config) 실행하여 fcitx 선택.


참고




2016년 11월 5일 토요일

랜 선으로 두 대의 RPi 연결

랜 선 하나만으로 두 대의 라즈베리 파이를 연결할 수 있는지 실험해보았다. 결과는 성공이다.



랜 케이블로 연결된 두 대의 라즈베리 파이의 호스트명은 각각 rpi1과 rpi3이다. rpi1에는 HDMI와 키보드, 마우스를 연결하고 micro USB 전원을 연결했다. rpi3은 헤드레스로, USB-TTL 케이블을 통해 노트북의 USB 포트에서 전원을 공급받으며, 노트북에서 콘솔을 띄웠다.

rpi3에서 ifconfig로 IP 주소를 확인한 후,
pi@rpi3:~$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr b8:27:eb:74:7d:c9
          inet addr:169.254.218.16  Bcast:169.254.255.255  Mask:255.255.0.0
          inet6 addr: fe80::bbe0:b9f7:d1f3:1222/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:88 errors:0 dropped:0 overruns:0 frame:0
          TX packets:133 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:21761 (21.2 KiB)  TX bytes:34334 (33.5 KiB)

rpi1에서 rpi3으로 ping 테스트를 해보니 잘 된다.
pi@rpi1 ~ $ ping -c 3 169.254.218.16
PING 169.254.218.16 (169.254.218.16) 56(84) bytes of data.
64 bytes from 169.254.218.16: icmp_req=1 ttl=64 time=0.578 ms
64 bytes from 169.254.218.16: icmp_req=2 ttl=64 time=0.483 ms
64 bytes from 169.254.218.16: icmp_req=3 ttl=64 time=0.544 ms

--- 169.254.218.16 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.483/0.535/0.578/0.039 ms

SSH 접속도 잘 된다.
pi@rpi1:~$ ssh pi@169.254.218.16
The authenticity of host '169.254.218.16 (169.254.218.16)' can't be established.
ECDSA key fingerprint is 78:7a:83:49:ae:18:91:45:91:37:03:ca:fa:d3:14:f5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '169.254.218.16' (ECDSA) to the list of known hosts.
pi@169.254.218.16's password:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Nov  5 13:10:27 2016 from rpi1.local
pi@rpi3:~$

IP 주소를 입력하는 대신 호스트명을 사용하기 위해, rpi1에 있는 /etc/hosts 파일의 끝에 rpi3의 IP 주소를 추가했다.
pi@rpi1 ~ $ tail -1 /etc/hosts
169.254.218.16  rpi3

그리고, SSH 접속을 할 때마다 패스워드를 입력하지 않기 위해 다음과 같이 키를 생성 및 복사했다.
$ ssh-keygen
$ ssh-copy-id pi@rpi3
$ ssh-add

지금까지 한 일은 아래의 영상과 같은 것을 만들어 보기 위한 준비 과정이었다. 소스 코드는 여기에 있다.

2016년 10월 31일 월요일

RPi에서 음성 인식하기

라즈베리 파이에서 USB 마이크와 PocketSphinx라는 소프트웨어를 이용하여 음성인식을 시험해보았다. 이 글에서는 마이크를 사용하여 소리를 녹음해보고, 음성인식에 필요한 소프트웨어를 설치한 다음, 음성을 인식하는지 테스트해보고, 그것을 이용해서 다른 명령을 실행시키는 과정을 다룬다.

USB 마이크


구입과 설치


USB 마이크의 구입과 설치에 대해서는 Raspberry Pi에서 소리 입력 및 녹음하기를 참조. 아래와 같은 명령으로 소리를 녹음하고 재생할 수 있으면, 다음으로 진행할 수 있다(이 글에서는 소리의 녹음을 위해 ALSA 프레임워크를 사용한다).

$ arecord -D plughw:1,0 -d 5 test.wav
$ aplay test.wav


USB 마이크를 기본 녹음 장치로 설정


USB 마이크를 기본 녹음 장치로 만들어두는 것이 편리할 것이다.

$ more ~/.asoundrc
pcm.!default {
    type asym
    playback.pcm {
        type plug
        slave.pcm "hw:0,0"
    }
    capture.pcm {
        type plug
        slave.pcm "hw:1,0"
    } 
}


홈 디렉터리에 위와 같이 .asoundrc를 작성한다. 이제 arecord를 실행할 때 -D 옵션을 생략해도 된다.

$ arecord -d 5 test.wav


음성인식


의존 패키지 설치


PocketSphinx를 설치하기에 앞서, 필요한 패키지들을 먼저 설치한다.

sudo apt install libasound2-dev autoconf libtool bison swig python-dev python-pyaudio
sudo pip install gevent grequests


SphinxBase와 PocketSphinx 설치


SphinxBase를 설치한다.

git clone git://github.com/cmusphinx/sphinxbase.git
cd sphinxbase
./autogen.sh
make
sudo make install
cd ..

PocketSphinx를 설치한다.

git clone git://github.com/cmusphinx/pocketsphinx.git
cd pocketsphinx
./autogen.sh
make
sudo make install
cd ..

ldconfig를 실행.

sudo ldconfig


사전 만들기


말뭉치(corpus)를 텍스트 파일로 작성한다. 아래의 말뭉치는 구글 캘린더를 조작하는 명령과 관련된 것이다.

$ more corpus.txt 
day
week
month
4
agenda
refresh
next
previous
today

언어 모델과 사전을 만들 차례이다. 위에서 만든 말뭉치 파일을 http://www.speech.cs.cmu.edu/tools/lmtool-new.html 페이지의 Upload a sentence corpus file:에서 선택한 다음, "COMPILE KNOWLEDGE BASE" 버튼을 누르면 잠시 후에 다운로드 페이지로 이동한다. .lm과 .dic 파일을 다운로드하거나, .tgz로 압축된 파일을 다운로드하여 압축을 푼다. 파일들을 적당한 위치로 옮기고, 필요하다면 이름도 바꾼다.

음성인식 테스트


다음과 같이 pocketsphinx_continuous 명령을 실행하여 음성을 인식하는지 테스트해본다. -lm과 -dict 옵션에는 .lm 파일과 .dic 파일을 각각 지정한다. USB 마이크가 디폴트 녹음 장치로 설정되지 않았다면, -adcdev plughw:1,0 옵션을 추가하여 실행한다.

$ pocketsphinx_continuous -hmm /usr/local/share/pocketsphinx/model/en-us/en-us -lm cal.lm -dict cal.dic -samprate 16000/8000/48000 -inmic yes
INFO: pocketsphinx.c(152): Parsed model-specific feature parameters from /usr/local/share/pocketsphinx/model/en-us/en-us/feat.params
Current configuration:
[NAME]   [DEFLT]  [VALUE]
-agc   none  none
-agcthresh  2.0  2.000000e+00
-allphone    
-allphone_ci  no  no
-alpha   0.97  9.700000e-01

...

INFO: ps_lattice.c(1441): Joint P(O,S) = -144424 P(S|O) = -24085
INFO: ngram_search.c(872): bestpath 0.00 CPU 0.000 xRT
INFO: ngram_search.c(875): bestpath 0.00 wall 0.001 xRT
NEXT
INFO: continuous.c(275): Ready....
^C

위에서는 음성을 NEXT라고 인식한 것을 볼 수 있다.

음성인식 결과를 이용하여 다른 명령 실행하기

pocketsphinx_continuous를 사용하여 구글 캘린더(이전 글 참조)를 조작하는 셸 스크립트를 다음과 같이 작성해보았다.

#!/bin/sh

cd /home/pi/calendar

pocketsphinx_continuous -hmm /usr/local/share/pocketsphinx/model/en-us/en-us \
    -lm cal.lm -dict cal.dic -samprate 16000/8000/48000 -inmic yes | \
    xargs -L1 sh -c 'echo "$*" | head -c1 | tr A-Z a-z | \
    xargs xdotool search -onlyvisible -class "chromium" windowactivate type' -

위에서 pocketsphinx_continuous는 마이크로 입력된 음성을 분석해서 그에 해당하는 단어를 출력하는 것을 반복한다. 그러면, 출력이 있을 때마다 파이프와 xargs를 통해 head, tr, xdotool이 실행된다. 'NEXT'를 인식하였다면, 첫 글자 'N'을 취해서, 소문자인 'n'으로 변환하고, Chromium 창에서 'n'을 타이핑하는 것이다. 구글 캘린더는 키보드 입력으로 'n'이 들어오면 다음(next)으로 이동한다.
자동 실행을 위해 다음과 같은 systemd unit 파일을 ~/.config/systemd/user/pocketsphinx.service에 작성했다.

[Unit]
Description=PocketSphinx
After=graphical.target

[Service]
ExecStart=/home/pi/calendar/start-pocketsphinx.sh
Environment=DISPLAY=:0
Restart=no

[Install]
WantedBy=default.target

참고





2016년 10월 20일 목요일

RPi 벽걸이 캘린더

라즈베리 파이와 구글 캘린더를 이용하여 벽걸이 캘린더를 만드는 프로젝트가 있다. 요즘 수요일마다 참석하는 스터디 모임에서 일차적인 목표로 삼은 과제이다.

얼마 전에 구입한 RPi 3 Model B를 이용하여 이를 구현해보았다. Raspbian의 새로운 데스크톱 환경인 PIXEL에 기본으로 포함되는 Chromium 웹 브라우저를 사용했다.

Chromium에서 구글 캘린더를 열면 모바일 페이지가 뜨는 버그가 있는데, URL을 https://calendar.google.com/calendar/render로 변경함으로써 데스크톱용 캘린더 페이지를 열 수 있다(스터디에서는 버그를 피하기 위해 Chromium 대신 iceweasel(Firefox ESR) 브라우저를 설치하는 방법을 택했다. 따라서 아래의 내용을 참고하되 iceweasel에 맞도록 수정이 필요하다). Chromium에서 키보드의 F11 키를 누르면 전체 화면으로 바뀐다. 캘린더 보기는 "월"을 선택한다.

명령행에서 다음의 명령을 실행하면, Chromium을 전체화면으로 실행시키면서 구글 캘린더를 "월" 보기로 보여준다.
chromium-browser --kiosk "https://calendar.google.com/calendar/render#main_7|month"

이제, RPi를 켤 때마다 캘린더가 뜨도록 할 차례이다. 스터디에서는 ~/.config/lxsession/LXDE/autostart 파일을 이용하려고 했지만, 원격 접속의 문제인지 아니면 PIXEL로 바뀐 것 때문인지는 몰라도 예상대로 잘 되지 않는 것 같았다. 집에 와서 검색을 통해 다음과 같은 방법을 찾았다.
  1. 위의 명령을 실행하는 start-kiosk.sh 파일을 pi 사용자의 홈(~) 디렉터리에 만든다.
  2. 다음과 같은 설정으로 ~/.config/systemd/user/kiosk.service 파일을 만든다.
    [Unit]
    Description=Kiosk
    After=graphical.target
    
    [Service]
    ExecStart=/bin/bash /home/pi/start-kiosk.sh
    Environment=DISPLAY=:0
    Restart=always
    
    [Install]
    WantedBy=default.target
  3. 다음의 명령을 실행한다.
    systemctl --user enable kiosk
    systemctl --user start kiosk
  4. sudo reboot 명령으로 테스트해본다. Chromium이 제대로 종료되지 않은 것에 대한 팝업이 뜨는데, 이것을 숨기려면 start-kiosk.sh 파일의 chromium-brower 명령에 옵션을 추가한다.
    chromium-browser --kiosk --disable-session-crashed-bubble --disable-infobars "https://calendar.google.com/calendar/render#main_7|month"
  5. 화면이 꺼지거나 화면보호기가 뜨지 않도록 하려면 start-kiosk.sh에서 Chromium 실행 전에 다음과 같은 명령을 실행하도록 해준다.
    xset -dpms; xset s off

참고





2016년 10월 18일 화요일

Raspberry Pi 잡설

Raspberry Pi 관련 몇 가지 소소한 발견.

RPi에 외장 HDD 연결

  • RPi 1 Model B에서는 USB 포트의 출력이 약해서 외장형 HDD 사용에 문제가 있고, 가능하다 하더라도 포트가 2개 밖에 없기 때문에 다른 USB 장치를 꽂을 여유가 없다. 외장 HDD를 사용하기 위해서는 별도의 전원을 가진 USB 허브가 필요하다.
  • RPi 3 Model B에 외장형 HDD를 직접 물려보았더니 잘 동작한다. 핫 플러깅을 했는데도 문제가 없었다. 전원은 2.5 A 어댑터로부터 RPi의 마이크로 USB에 공급.
  • RPi 1 Model B+에서도 가능할지 모른다.

OpenELEC


  • RPi에서 쓰던, OpenELEC을 설치한 마이크로 SD 카드를 그대로 RPi 3에 넣고 전원을 넣어보니 부팅이 되는 듯 메시지가 올라가다가 멈춘다. 업데이트를 해줘야 쓸 수 있다.
  • OpenELEC에서 TV를 볼 수 있다! 댓글의 채널 목록을 받아서 테스트해보니, 현재 안 나오는 채널도 많지만, 아직 나오는 채널도 많다.
    www.todayhumor.co.kr/board/view.php?table=jisik&no=201727
  • KODI 재시작 명령
    systemctl restart kodi

디스플레이

영상을 감상할 때 종횡비 4:3의 브라운관 TV에 연결하면 위아래가 남고, WFHD(21:9) 모니터에서는 좌우가 남는다. 영상을 감상하는 데에는 역시 16:9 모니터가 최적일 것 같다. 그런 용도가 아니라 하더라도, RPi를 사용할 때 이런저런 신경을 쓰지 않고 편하게 사용할 수 있는 디스플레이 장치는 HDMI 단자가 있고 스피커가 내장된, 종횡비 16:9의 모니터라는 결론.



2016년 10월 16일 일요일

짝퉁 블로그

구글 검색으로 자료를 찾다가, 내 블로그(sk8erchoi-tech.blogspot.com)가 다른 사이트에 거의 똑같이 복제된 것을 발견했다. 차이점이 있다면, 당연히 사이트의 URL 주소가 다르고, 모든 링크의 주소가 해당 사이트의 주소로 바뀌어 있다는 것이다. 그리고, 광고가 삭제되어 있다.

짝퉁 사이트 주소:

  • 에이치티티피://f44.654k.net/0/?url=L21vYy50b3BzZ29sYi5oY2V0LWlvaGNyZThrcy8vQTMlcHR0aA==
  • 에이치티티피://9k.9941.yi.org/0/?url=L21vYy50b3BzZ29sYi5oY2V0LWlvaGNyZThrcy8vQTMlcHR0aA==


내가 쓴 모든 글과 사진이 내가 알지 못하는 누군가에 의해 고스란히 수집되어 게시되고 있다는 사실이 섬뜩하다. 만약 내가 블로그를 그만두면, 이곳이 사실상 내 이름을 건 블로그가 된다. 물론 내 컨텐츠가 여러 검색 엔진이나 인터넷 아카이브(web.archive.org)에도 수집되기는 하지만, 그것과는 다른 문제다.

짝퉁의 존재로 인해 어떤 피해를 입었느냐고 하면 딱히 말할 것은 없다. 만약 어떤 피해를 입는다고 해도 하소연할 곳도 없다.

* 글을 다 써서 올리자마자, 짝퉁 사이트에도 똑같이 보인다. 일정 주기로 크롤링하는 것이 아니라, 요청시마다 가져가는 듯.


2016년 10월 14일 금요일

USB-TTL 케이블로 RPi에 연결

이번에 구입한 라즈베리파이 스타터 키트에는 USB to TTL 케이블이 포함되어 있다. 이것을 이용하면 네트워크가 되지 않는 상황에서도 직렬 연결을 통해 라즈베리 파이(RPi)와 통신할 수 있어 든든하다(명령행에서 WiFi를 설정할 수 있다).

디바이스마트에서 구입한 것과 동일한 것으로 보이는 제품이 Adafruit에도 있어서 좀 더 자세한 정보를 알 수 있었다. USB 쪽 몸체가 검정색으로 된 것은 PL2303HX 칩셋을 쓴 구형 제품이고, 2014년 이후 제품은 파란색 몸체에 PL2303TA 칩셋이 들어있다고 한다. Windows 8과 10까지 지원하는 최신 드라이버에 대한 링크도 있다.

검정, 흰색, 녹색 선을 각각 6, 8, 10번 핀에 꽂는다. 빨간 선을 2번 핀에 꽂으면 전원 공급도 가능한데, 그때에는 마이크로 USB에는 전원을 연결하지 말아야 한다.


그리고, RPi의 /boot/config.txt에 UART를 사용하겠다는 설정이 있어야 하고, raspi-config에는 직렬 연결을 통해 로그인할 수 있도록 설정되어 있어야 한다(여기에서 삽질을 했다).

/boot/config.txt
...
enable_uart=1






참고


2016년 10월 13일 목요일

RJ with PIXEL 설치 및 한글 설정

라즈베리 파이 3 모델 B를 구입했다(디바이스마트의 스타터 키트).

노트북에 Raspbian Jessie with PIXEL(2016-09-23) 이미지를 내려받아Win32DiskImager로 마이크로 SD 카드에 기록한 다음, 마이크로 SD 카드를 RPi에 꽂고, 모니터와 키보드・마우스도 연결하고서 RPi의 전원을 넣으니 금세 부팅이 되어 GUI 데스크탑으로 들어온다.

Raspberry Pi Configuration에서 몇 가지 설정을 하고, 리부트. 한 가지 주의할 점은, Localisation 탭에서 WiFi Country를 KR로 변경하면 안 된다.

라즈비안을 업그레이드하고,

$ sudo apt update
$ sudo apt upgrade


펌웨어를  업데이트하고,

$ sudo rpi-update


한글이 제대로 표시되도록 글꼴을 설치하고,

$ sudo apt install ttf-unfonts-core


한글 입력을 위해 fcitx-hangul도 설치했다.

$ sudo apt install fcitx-hangul

리부트.

$ sudo reboot


RPi에 직접 연결한 키보드를 사용할 때 영국식 키보드 배열이 되어서 기호 입력에 문제가 있었다(@와 #이 아닌 따옴표와 파운드 기호가 입력됨). Fcitx 설정에서 Input Method에 "키보드 - 영어(미국)"을 추가하고, Hangul 입력기의 Keyboard layout을 "한국어 - 한국어(101/104키 호환)"으로 설정하여 해결했다.

참고



2016년 10월 12일 수요일

RPi에 WN725N 드라이버 설치

라즈베리 파이 모델 B에서 패키지 업그레이드와 펌웨어 업데이트를 했다.

pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get upgrade
pi@raspberrypi ~ $ sudo rpi-update
pi@raspberrypi ~ $ sudo reboot
pi@raspberrypi ~ $ uname -a
Linux raspberrypi 4.4.23+ #913 Tue Oct 4 13:56:56 BST 2016 armv6l GNU/Linux
pi@raspberrypi ~ $ sudo vcgencmd version
Oct 11 2016 12:23:39
Copyright (c) 2012 Broadcom
version c242c9606727d307232bde9c153938ab0b05c12d (clean) (release)

무선 랜 동글(WN725N)이 동작하지 않는다. ifconfig -a 명령을 실행해보니, 지금까지 사용하던 wlan0이 보이지 않는다.

아래의 방법으로 드라이버를 재설치하여 해결했다. 라즈베리 파이가 인터넷에 연결된 상태에서 가능한 방법이라, Wi-Fi를 통해 인터넷에 접속된 노트북에 랜 선으로 연결하여 작업했다.

pi@raspberrypi ~ $ wget https://dl.dropboxusercontent.com/u/80256631/install-wifi.tar.gz
--2016-10-12 20:36:22--  https://dl.dropboxusercontent.com/u/80256631/install-wifi.tar.gz
Resolving dl.dropboxusercontent.com (dl.dropboxusercontent.com)... 108.160.172.5
Connecting to dl.dropboxusercontent.com (dl.dropboxusercontent.com)|108.160.172.5|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3674 (3.6K) [application/octet-stream]
Saving to: `install-wifi.tar.gz.1'

100%[=====================================================>] 3,674       --.-K/s   in 0s

2016-10-12 20:36:35 (7.95 MB/s) - `install-wifi.tar.gz.1' saved [3674/3674]

pi@raspberrypi ~ $ tar xzf install-wifi.tar.gz
pi@raspberrypi ~ $ ./install-wifi

Your current kernel revision = 4.4.23+
Your current kernel build    = #913

Checking for a wifi module to determine the driver to install.

Your wifi module is Bus 001 Device 004: ID 0bda:8179 Realtek Semiconductor Corp.

And it uses the 8188eu driver.

Checking for a new 8188eu wifi driver module for your current kernel.
There is a driver module available for this kernel revision.
Downloading the 8188eu driver.
Installing the 8188eu driver.

참고

2016년 10월 10일 월요일

남의 댓글을 캡처하는 것에 대해

이 글을 왜 쓰게 되었는지부터 얘기해야겠지만, 그랬다가는 자가당착에 빠지게 되므로 어쩔 수 없이 불친절할 수 밖에 없다.

남이 쓴 게시물, 댓글, 채팅 메시지를 이미지로 캡처해서 제3자에게 공유하는 것은 잘못된 행동이다.

  • 글쓴이가 의도하지 않은 독자에게, 원래의 맥락에서 벗어난 상태로 읽힌다.
  • 특정 시점의 스냅샷이 돌아다니므로, 그 이후에 수정이나 삭제를 해도 반영되지 않는다.
  • 신상이 노출되어 피해를 입을 수 있다.

그러나 이런 얘기를 해봤자 쇠 귀에 경 읽기일테니, 스스로 피해를 입지 않도록 입(키보드)조심하는 것이 상책.

2016년 10월 7일 금요일

윈도우10 로그인 화면 배경 삭제

Windows 10의 스토어에서 페이스북 앱을 설치해서 쓰다가 불편해서 지워버렸다. 그런데, 프로필 동기화를 통해서 설정되었던 로그인 화면은 원상복구가 되지 않았다. 한동안 내버려두었다가 뒤늦게 조치했다. 그 방법을 소개하기 전에, 이 글에서는 다음의 세 화면을 구분한다는 점을 밝힌다.
  • 잠금 화면(lock screen): <Ctrl> + <Alt> + <Del>을 누르고, "잠금"을 선택하면 나오는 화면
  • 로그온 화면(start screen): 사용자 로그인을 하기 위해 패스워드를 입력하는 화면
  • 로그인 전 화면: 컴퓨터를 켜서 Windows가 기동되면 처음 나오는 화면

페이스북 앱


페이스북 앱에서 프로필 동기화를 해제하는 방법이 있다길래 따라해보려 했지만, 다시 설치한 페이스북 앱에서는 프로필 동기화 관련 설정을 할 방법을 찾을 수 없었다.

로그온 화면 배경 이미지 삭제


처음에는 잠금 화면과 로그온 화면의 차이를 모르고, 잠금 화면의 배경 이미지를 삭제하는 글을 찾아서 삽질을 좀 했다.

  1. 윈도우 키 + <R>을 누르고 gpedit.msc 실행
  2. 컴퓨터 구성 - 관리 템플릿 - 제어판 - 개인 설정 클릭하여 나오는 항목들을 이것저것 만져봄

그러던 중에 로그온 화면의 이미지는 제거할 수 있었다. 아마도 특정 시작 화면 배경 적용 옵션에서 배경 ID를 변경했을 때 반영된 것 같다. 그렇지만, 로그인 전 화면에는 보기 싫은 배경이 여전히 남아있었다 .


로그인 전 화면의 배경 이미지 삭제


로그인 전 화면의 배경 이미지는 다음과 같은 방법으로 삭제할 수 있었다.

  1. 파일 탐색기의 폴더 옵션에서 숨김 파일, 폴더 및 드라이브 표시 설정
  2. C:\ProgramData\Microsoft\Windows로 이동
  3. SystemData 폴더를 오른쪽 클릭하고 속성 창의 보안 탭에서 고급 버튼 클릭. 소유자를 변경하고, 하위 컨테이너와 개체의 소유자 바꾸기 선택한 다음 확인 버튼 클릭
  4. SystemData\S...\ReadOnly 폴더의 LockScreen_... 폴더를 바탕화면으로 끄집어냄
  5. 윈도우 키를 누르고 프로필 이미지를 클릭한 뒤 로그아웃 클릭
  6. 잘 되는 것을 확인했으면 바탕화면으로 가져온 LockScreen_... 폴더를 오른쪽 클릭하고 속성 창의 보안 탭에서 사용권한을 부여한 후에 폴더를 삭제


참고




프로필 사진

페이스북 프로필 사진은 몇 달에 한번씩 바꾸는 편이지만, 구글이라든지, 그외의 다른 서비스에서는 별로 손을 대지 않는 편이다. 최근에 몇 군데의 사이트에서 프로필 사진을 바꾸면서 느낀 점.


  • 사이트마다 바꾸는 것이 귀찮다. 프로필 사진을 다르게 할 수 있다는 점이 한편으로는 좋은 점이지만. 모두 gravatar를 지원하면 좋으련만.
  • 구글 플러스에서 사진을 바꾸면 구글의 모든 서비스에 적용되는 걸로 알고 있는데, 그게 뭔가 이상하다. 유튜브에선 바뀌어 있는데 지메일에선 예전 사진이 그대로 남아있는 식이다. 캐시가 남아서 그럴 수도 있겠지만, 어쨌거나 이번에는 상당히 불편한 상황을 겪었다. 구글은 대단한 기술을 척척 만들어내는 반면에 허술한 구석도 많은 것 같다. 서비스가 워낙 방대해서 그럴 수도 있겠지만.

2016년 10월 2일 일요일

svchost.exe의 CPU 점유 해결

Windows Vista 시절에 구입한 HP Compaq 6715b는 거무튀튀하고 큼직한 노트북이다. 아기자기한 맛이 없고 성능도 떨어지지만, 넓은 화면과 키보드가 있어 문서 작성용으로는 제격인 외형을 갖췄다. 작년말에 Windows Vista를 재설치하여 사용 중인데, CPU가 늘 100%로 차 있고 전반적으로 매우 느려서, 사용하는 데에 아주 많은 인내심을 필요로 했다. 그렇지만, 단지 하드웨어의 사양이 낮아서 그런 것이 아니라, 뭔가 이상이 있었다.

여러 개의 svchost.exe 프로세스 중 한 개가 대부분(80% 가량)의 CPU를 점유한다는 것까지는 파악했지만, svchost의 정체가 무엇인지, 어떻게 해야 CPU 점유를 낮출 수 있는지 갈피를 잡지 못하고 있었다.

오늘에야 위키피디아의 도움을 받아 문제를 해결했다. 여러 개의 시스템 서비스를 위해 각각의 프로세스를 띄우는 대신, 한 개의 프로세스에 모아서 실행시키는 것이 바로 svchost.exe다. 특정 svchost.exe 프로세스가 어떤 서비스들을 돌리고 있는지 알고 싶으면, Windows 작업 관리자의 프로세스 목록에서 오른쪽 클릭하여 팝업 메뉴에서 '서비스로 이동'을 선택하면 된다. 내 경우에는 Windows Update 서비스가 문제를 일으키고 있다는 것을, 서비스를 하나씩 중지시켜보는 방법으로 알아냈다.

Windows Update 서비스를 중지하자마자 CPU 점유율이 확 떨어졌다

결정적인 도움을 준 문서를 읽게 된 계기는 sysinternals의 Process Explorer 도구에서 작은 편의 기능으로 제공한 키워드 검색이었다. 이전의 문제해결 시도에서는 왜 위키피디아를 찾지 못했을까? 그것은 내가 "svchost.exe CPU full"과 비슷한 문구로 구글링을 계속했기 때문이다. 당장의 불을 끄는 방법에만 관심이 있었을 뿐, 불에 대한 이해나 불을 다루는 방법에는 관심을 두지 않았기 때문일 것이다.

2016년 9월 25일 일요일

윈도우10에서 은행 앱 지우기

나의 메인 PC라 할 수 있는 ThinkPad 노트북(X230)의 운영 체제를 Windows 7에서 10으로 업그레이드한 지 일년 남짓 되었다. 여태 큰 불편 없이 사용하고 있었는데, 요즘 들어 파일 탐색기가 부쩍 느려지고, 메뉴가 잘 작동하지 않더니, 부팅이나 시스템 종료가 실패하는 일도 잦아졌다. Windows Defender로 검사한 결과 악성코드는 나타나지 않았다. 나는 어지간해서는 운영체제를 재설치하지 않고, 내부 스토리지도 거의 교체하지 않는다. 그래서, 일단은 금융/보험/관공서에서 제공한 각종 프로그램들을 제거해보기로 했다.

이제는 익숙해졌지만, Windows 10을 처음 접했을 때 어색했던 것이, 데스크탑 운영체제에 '앱'이라는 용어를 도입한 것이었다. 제어판의 <앱 및 기능>에서 '앱'들을 지우기 시작했는데, 지워도 지워도 끝이 없다. 'safe'라든지, security의 앞 세 글자인 'sec'를 검색하면 모두 보안 프로그램이다. 이삼십 개는 지운 것 같다. 그러고 나니, 큰 기대를 하지 않았던 것에 비해 Windows의 안정성이 눈에 띄게 높아졌다.

그런데, <앱 및 기능>에서 잘 지워지지 않는 것들이 몇 개 있다. 몇 번 씨름하고서 내버려두었다가, 마이크로소프트 커뮤니티에서 다른 방법을 찾았다. <앱 및 기능> 창의 맨 아래로 가서 <프로그램 및 기능>을 클릭하면 <프로그램 제거 또는 변경> 창이 뜬다. 또는, 키보드의 Windows 키와 x 키를 함께 누르면 화면의 왼쪽 아래에 목록이 나타나는데, 그 중 <프로그램 및 기능>을 선택해도 된다. <앱 및 기능>에서 제거에 실패했던 프로그램들도 여기에서는 문제 없이 제거되었다. 남아 있던 것들을 마저 지워버렸다.

  • 다음 게임 스타터
  • MarkAny Inc.의 증명서 발급 시스템과 e-PageSafer
  • 금융결제원 - 스마트폰 인증서 이동 프로그램
  • INFovine - 휴대폰인증서(보관)서비스
  • SoftCamp Secure KeyStroke 4.0
  • INISafe SFilter 7.2 (SFilter v1.0)
  • CrossCertWeb v2.0
  • eISP
  • SoftForum의 AnySign4PC
  • interezen의 IPinside LWS Agent

앞으로 은행, 보험, 관공서 사이트 이용만을 위한 별도의 물리적인 PC를 사용하려고 한다. Windows 7 Starter(32 비트)가 설치된 넷북(Lenovo ideapad S10-2)이다.

디레퍼런스

번역 중인 RPi 책에 C/C++을 소개하는 부분이 있다. 포인터에 대한 내용을 번역하다보니, 'dereference'라는 단어가 나왔다. 이 단어를 한국어로 뭐라고 해야할 지 딱히 생각이 나지 않아, 일단 원문의 단어를 포함한 한글 문장으로 옮겼다. 나중에 네이버 사전을 찾으니 '역참조'라고 나온다. Ctrl + H를 해서 'dereference'를 '역참조'라고 바꿨다. 역참조라...

아무래도 마음에 들지 않는다. 구글에서 '역참조'를 검색하니, 'dereference'와 'back reference'가 있다. 그렇다면 더욱 마음에 들지 않는다.

다시 구글에서 'dereference'를 검색. Wiktionary.org의 뜻풀이가 간단명료하다. '포인터가 가리키는 것에 접근하다'라는 뜻의 동사다.

그렇다면 대체 접미사 'de-'는 무슨 뜻이길래 '역'으로 번역되었는가? Wiktionary에서는 라틴어에서 온, 'of, from'의 뜻이라고 한다. 그러니까, 'from reference', '참조로부터 얻는다'는 말이다. '역'이라는 글자는 대체 어디에서 왔을까? 저 옛날, 일본 기술 서적을 한글로 옮기던 때에서부터 시작된 것일까? 어쨌든 다시 Ctrl + H, '역참조', '디레퍼런스'. 출판사에서 받은 번역 지침에 '영어 표현은 가급적 한글 표현으로 대체한다'는 항목이 있어, 나중에 어떻게 바뀔지는 모르겠다.

'역참조'를 검색하다가 걸린 'back reference'에 대한 글도 읽어보았다.

2016년 9월 24일 토요일

Vim

RPi 책 번역 원고를 워드로 작성하고 있기는 하지만, 최근 들어서는 Vim에서 한번 작성해서 워드에 붙여넣는 식으로 하게 되었다. 업무상 유닉스에서 터미널을 통해 vi를 종종 사용했기 때문에 vi에 익숙하고 좋아하지만, 터미널을 볼 일이 없을 때에는 별로 사용하지 않는 편이었다.

Vim을 다시 설치해서 사용하게 된 계기가 된 것은 번역 용어집(glossaries)이다. OmegaT에서는 텍스트 파일로 만들어지지만, 이번 작업에서는 굳이 그럴 필요가 없어, 정렬을 위해 엑셀을 써보기도 했다. 그런데, 오피스 구독이 종료되어 맥북에서는 엑셀 파일을 편집할 수 없게 된 것이다. 그래서 다시 텍스트 파일을 쓰게 되었는데, 일반적인 텍스트 편집기(notepad++) 등에서는 정렬이 아무래도 성가신 일이었다. vi/Vim에서는 /^ras와 같이 용어를 빨리 찾을 수 있고, :2,$sort i 명령을 한번 내리면 순식간에 정렬이 끝난다(첫 행은 빼고, 대소문자 구분 없이 정렬). 이제 엑셀보다도 훨씬 빠르고 편하다.

그러다가, 초벌 번역 작업에까지 그 쓰임을 넓힌 것이다. vim.org 사이트에서 Vim을 다운로드하여 윈도우에 설치하고, 맥북에도 MacVim을 설치했다. 맥에서는 원래 터미널에서 vim을 쓸 수 있지만, MacVim이 운영체제와 잘 통합되어 있어 좀 더 편하게 느껴진다.

Vim의 composability에 대한 글을 읽고 나니, 이제서야 그 사상을 이해할 수 있을 것 같다.

자질구레한 불편사항이 있지만, 당분간은 MacVim과 함께 많은 시간을 보내게 될 것 같다.


2016년 9월 11일 일요일

iPhone SE 구입

iPhone 5가 재시작되는 현상은 나아지다 심해지기를 반복하면서 점점 더 상태가 나빠져서, 급기야는 무한 사과 모드(이런 말이 있는지 처음 알았다)에 빠졌다. 서비스 센터에서 권유한 방법인 재설정은 효과가 없었다. 선택을 해야했다.

  1. 리퍼: 수십만원을 들여서 수리하기엔 너무 구형이 되었다.
  2. 사설 수리: 돈 아끼려다 나중에 또 돈이 들어갈 것만 같다.
  3. 값싼 폰으로 기변: 딱히 갖고 싶은 것이 없다.
  4. 현재 판매 중인 iPhone으로 기변
  5. 한국에 iPhone 7이 나올 때까지 버티다가 기변: '혁신은 없었다'까지는 아니더라도 그리 매력적이지 않고, 비싸다.
결국 4번을 선택. 모델은 iPhone SE. 그 이름을 언젠가 흘려들은 적이 있는 것 같지만, 역시 이번에 알게 되었다. 이 모델을 선택한 이유:
  • 상대적으로 낮아진 성능을 제외하면 iPhone 5에 큰 불만이 없었다.
  • Topeak의 iPhone 5용 Ridecase를 계속 사용하고 싶었다(요즘 자전거를 잘 안 타기는 하지만).
  • iPhone6~7의 둥근스름한 모서리가 썩 마음에 들지 않는다.
  • iPhone 중에서는 가격이 저렴한 편이다.
iPhone 5를 들고가서 보상판매가 가능한지 물어보니, 정상작동해야만 가능하다고 한다. 다행히 직원이 상태를 확인하는 동안에는 작동이 되었다. 나중에 보상 센터에서 확인할 때 작동이 안되면, 보상받은 차액을 추가로 내야할 수도 있다고 한다.
직원이 USIM을 옮기는 작업을 도와주었는데, 무슨 이유에서인지 '서비스 안 됨' 상태이다. 일단 집에 와서 아이튠즈로 복원부터 해두었다. 내일 통신사에 방문하려고 한다.


덧붙임


  • '서비스 안 됨'이 뜬 이유는 "지원금에 상응하는 요금할인"을 받고 있었기 때문이다. 통신사에 방문하여 해결했다.
  • 구입한 지 며칠 지나지 않아 iOS 10으로 업그레이드되었다. 때맞춰 잘 바꿨다는 생각이 든다.

2016년 9월 3일 토요일

Office

지난 3월에 오피스365의 구독을 취소한 이후로, 재구독하지 않고 있다.

오피스를 전혀 쓰지 않는 것은 아니고, 지난 달에 번역 일을 시작했기 때문에 요즘은 매일 워드를 쓴다.

어떻게 그것이 가능한가(오피스 공짜로 쓰는 법?!):

1. 주 작업은 윈도10 노트북으로 한다. 구독 취소하기 전에 설치해둔 것으로 여전히 작업이 가능하다. Activation하라고 권유하지만 강제하지는 않는다.
2. 맥북에 설치된 것은, 이제 보기만 가능하고 문서 작성이 안되는 상태이다. 언젠가부터(구독 중일 때) 업데이트 설치가 잘 안되기도하고, 맥용오피스는 원래부터 어딘가 불편했던 터라, 맥에서는 워드를 안 쓰기로 결정. 외부에 들고나갈 때는 기본 텍스트 편집기로 작업했다가 집에 가서 윈도10 노트북에서 워드로 옮기는 작업을 한다.
3. 몇 달 전에 3만원 주고 산 넷북이 있는데, OS가 윈도 7 스타터이다. 윈도 7 스타터에는 오피스가 포함되어 있다! 가끔 기분 전환(스탠딩->의자)할 때 이걸로 작업한다. 얼마 전에 15인치 모니터를 주워다 붙였다.
4. 폰에서 워드 따위 쓸 일 없다!
5. 본가에 있는 비스타 노트북은 60일 짜리 오피스(2007이던가..)가 깔려있다. 이건 activation 체크를 무력화하는 방법이 있을 것 같아서 구글링해보니 쉽게 할 수 있었다.

그리 떳떳한 얘기는 아니다..

PS: 이 모든 것은 드롭박스가 있기에 편리하게 이루어진다. 매년 99달러 씩 내고 쓴다.

iPhone5 Crash

어제부터 아이폰5가 여러 번 crash되길래 서비스센터에 다녀왔다.

직원의 말: 앱이 서로 충돌할 수 있다. 백업 후에 재설정을 해보라. 증상이 반복되면 리퍼.

재설정 후 복원하면 소프트웨어의 충돌이 사라질까? 하드웨어를 교체하면 소프트웨어의 문제가 사라질까?

어쨌거나 다녀온 보람은 있다. 첫째, inspection 보고서 화면의 충돌한 앱 목록에서 카카오톡을 확인. 둘째, 서비스센터로 가려고 버스를 탄 이후에 한번도 crash되지 않음.

2016년 8월 11일 목요일

책상 재배치

책상 배치를 바꿨다. 지난 달 말에 스케이트 연습을 하다가 허리를 삐끗한 이후로 의자에 앉는 것이 힘들어서이다(서 있기도 힘들다). 누워 있거나 천천히 걷기, 자전거 타기가 가장 편안하지만, 이달 들어 책 번역을 시작했기 때문에 책상에서 시간을 보낼 수 밖에 없다.
전에 한번 스탠딩 데스크를 시도했다가 물렸는데, 가장 큰 이유는 오랫동안 서있는 것이 힘들어서였다. 그래서 이번에는 자세를 자주 바꿀 수 있도록 했다. 주 작업인 원고 집필은 서서 하고, 예제 실행은 앉아서 서브 노트북을 사용하는 것이다.



2016년 8월 2일 화요일

GitHub의 변경내역 비교하기

2015년 10월부터 라즈베리 파이 재단의 공식 문서를 번역하여 wikidocs.net에 게재하고 있다. 문서는 꾸준히 갱신되기 때문에, GitHub의 저장소에서 커밋 로그를 2-3일마다 확인하여 번역본에도 적용하고 있다(수정 사항이 많거나 바쁠 때에는 원문만 먼저 적용해두고 차차 번역해 나가는 식으로 작업한다). 수정 사항이 많지 않을 때에는 크게 문제가 되지 않지만, 은근히 시간을 많이 뺐는 작업이다. 게다가, 요즘 들어 여러 가지 일로 바빠서 신경을 쓰지 못하다보니, 보름 정도 변경 사항이 쌓여버렸다.

"15일 동안의 변경 사항을 쉽게 확인할 수 없을까?"하는 궁금증이 생겨 잠시 검색해보니, 아주 좋은 방법이 있다.

저장소에 대한 https 경로의 끝에 /compare를 붙이는 것이다.

https://github.com/raspberrypi/documentation/compare

그러면 Compare changes라는 화면이 보인다. 친절하게도, 하루 전의 master와 비교할 수 있는 예제도 링크해놓았다.

https://github.com/raspberrypi/documentation/compare/master@%7B1day%7D...master

1day를 15day로 바꾸면, 보름 동안의 변경사항을 확인.

https://github.com/raspberrypi/documentation/compare/master@%7B15day%7D...master

커밋은 48회 이루어졌지만, 실제 변경된 파일은 19개 밖에 되지 않으므로 쫓아가기가 한결 수월해졌다.


2016년 7월 5일 화요일

Lenovo ideapad S10-2 구입

얼마 전에 중고 넷북을 하나 샀다. 모델은 Lenovo S10-2. 키보드와 세 개의 USB 포트 중 두 개가 고장이라, 시세보다 조금 싼 가격인 3만원을 주었다.

특별히 용도가 있어서라기보다는, 기존에 가지고 있던 S10-3과 호환이 되지 않을까하는 생각에서 구입한 것인데, 기대와 달리 호환 가능한 부품이 전혀 없다.

어디에 쓸까 생각하다가 직장(스포츠센터)에서 쓰던, Lubuntu 깔린 tx1000을 대체하기로 했다. 너무 느리기도 하고, 결정적으로 리브레오피스와 한글 입력기가 매끄럽게 작동하지 않아서 불편하던 참이다. 그리 높은 사양의 컴퓨터는 필요하지 않고, 그저 웹브라우저와 엑셀, 드롭박스만 잘 되면 그만이다. 집에서 쓰는 컴퓨터를 가져다놓기에는 좀 불안하기도 하고, 이 정도가 적당하다.

Windows 7의 에디션 중에서 가장 기능이 적은 starter 에디션이 설치되어 있다. 비영리 사용자용이기는 하지만, MS 오피스도 포함되어 있다.

한동안 USB 키보드를 빌려서 쓰다가, ebay에서 구입한 부품으로 수리했다. RAM은 HP 6715b에 꽂았던 것과 바꿔서, 1 GB에서 2 GB로 업그레이드. 이것저것 깔지 않으니 쾌적하다. Windows 10으로 업그레이드하라는 알림이 뜨지만, 이 사양으로는 감당할 수 없으므로 손대지 않을 생각이다.

2016년 4월 17일 일요일

AV 시스템 셋업


피겨 스케이트 비디오를 여러 개 구한 것을 계기로, 거실 겸 침실에 AV 시스템을 꾸몄다.

왼쪽 아래부터 시계 방향으로 - 지난 달에 만오천원 주고 산 삼성 20인치 TV. 얼마 뒤에 3만원에 구입하고 LG 서비스센터에서 수리한 VHS/DVD 콤보. OpenELEC을 설치한 라즈베리 파이 모델 B. 아이패드 1세대와 키보드 독. JBL 블루투스 스피커(키보드 독의 이어폰 단자에 유선 연결).



2016년 3월 28일 월요일

Ubuntu upowerd 아이폰 버그

Lubuntu 14.04 LTS가 설치된 HP tx1000 노트북이 며칠 전부터 "시스템 프로그램 오류를 발견했습니다"는 팝업 메시지를 보인다.

/var/crash 디렉터리에 있는 로그를 확인하여 검색해보니, 아이폰을 USB 포트에 연결할 때 나타나는 문제.


Workaround: 전기 콘센트에 충전기를 꽂아서 아이폰을 충전하자.


2016년 3월 21일 월요일

오피스 365 구독 취소

MS 오피스 365 구독의 자동 갱신을 취소했다. 다음 달 중순부터는 PC들에 설치한 오피스 제품을 사용할 수 없게 된다. 업무상 필요한 오피스 제품을 회사에서 구입해주지 않아서 개인 경비로 처리하기 위해 구독을 시작했던 것인데, 퇴사한 후에도 꼬박꼬박 사용료를 내고 있었다. 가계부를 보니, 퇴사 후 지금까지 낸 사용료가 18만원 남짓이다. 개인적인 용도로는 구글 문서와 구글 스프레드 시트를 사용하고 있고, 당분간 책을 쓰거나 슬라이드를 만들 일도 없으니 성능 좋은 오피스 제품이 필요하지도 않다.

2016년 3월 11일 금요일

이세돌과 알파고, 다윗과 골리앗

이세돌과 알파고의 대국 결과, 바둑에 있어서 컴퓨터가 인간을 넘어섰다는 것이 확실해졌다. 이 시점에, 스티븐 호킹 박사가 '로봇보다도 자본주의를 두려워해야한다'고 말했다고 한다.

자본주의를 두려워하라.. 그러고보니, 한두 해 전에 지인과 술자리에서 나누었던 이야기가 떠오른다.

컴퓨터 하드웨어의 가격이 점점 떨어지면서 그 성능은 일취월장하는 것에 덩달아, 클라우드 서비스 등의 발전과 여러 가지 과금 체계로 인해 소프트웨어도 큰 경제적 부담 없이 사용할 수 있는 때가 되었다.

그렇기는 하지만, 개인이 구매할 수 있는 컴퓨터 시스템과 대기업이 자본을 투입하여 장비를 도입하고 전문가를 고용하여 구축하여 운영하는 시스템의 연산능력에는 언제나 매우 큰 차이가 있을 수 밖에 없다. 다윗(개인과 중소기업)과 골리앗(거대기업, 정부)의 싸움에서 다윗은 대부분 지게 되어있다. 법적인 다툼이 되었건, 금융 상품을 통한 투자가 되었건, 각종 지표를 활용한 경영 전략 수립이 되었건.

IT 업종의 종사자는 늘 누군가에게 고용되거나, 제품 및 서비스를 개발하고 판매하여 생계를 이어간다. 그리고, 그들이 구축한 컴퓨터 시스템은 다윗이나 골리앗, 혹은 양쪽 모두가 이용한다. 내 경우에는 대기업이 아니면 구입할 엄두를 내지 못하는 값비싼 제품을 담당해왔으므로, 주로 골리앗을 위해 일했다고 볼 수 있다.

최근에 각광받는 빅데이터와 딥 러닝에 대해 생각해보면, 기술 발전에 따른 혜택을 많은 사람들이 누리게 되겠지만, 그 혜택이 다윗과 골리앗에게 공평하게 돌아가게 될 지는 의문이다. 나는 기술의 발전이 점점 더 골리앗에게 힘을 실어주는 방향으로 작용하지 않을까하는 조바심이 든다.

어릴 때 본 어떤 영화에서, 야생마는 재갈을 물린 사람과 싸우려하기보다는 재갈과 싸우려하는 습성이 있다고 했던 것 같다. 우리가 싸워야하는 대상은 로봇이 아니라, 그것을 만드는 기술자들이 아니라, 자본주의와 국가가 될 것이다.

2016년 2월 25일 목요일

웹 브라우저에서 Raspberry Pi 조작하기

스터디의 이번 과제는, 웹브라우저에서 Raspberry Pi의 주소로 접근하여 텍스트필드에 문자열을 입력하면, 그 문자열을 PiFaceCAD에 출력하는 것이었다. 서버는 node.js를 사용하여 구현하기로 했다.

node.js의 웹프레임워크인 express 모듈을 사용했고, PiFaceCAD를 다루는 Python 코드를 호출하기 위해 child_process 모듈을 사용했다.

server.js

var express = require('express');
var app = express();

app.use(express.static('public'));

app.get('/', function (req, res) {
   res.sendFile( __dirname + "/" + "form.html" );
})

app.get('/lcd_write', function (req, res) {
   text = "\"" + req.query.text + "\""
   var exec = require('child_process').exec;
   function puts(error, stdout, stderr) { console.log(stdout) }
   cmd = "python3 -c \"import sys, pifacecad; pifacecad.PiFaceCAD().lcd.write(sys.argv[1])\""
   exec(cmd + " " + text, puts);
   console.log(text);
   res.end(text);
})

var server = app.listen(8000, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("Example app listening at http://%s:%s", host, port)

})

form.html

<html>
<body>
<form action="/lcd_write" method="GET">
Input text here: <input type="text" name="text">  <br>
<input type="submit" value="Submit">
</form>
</body>
</html>


2016년 2월 22일 월요일

Raspberry Pi에 node.js 설치

Raspberry Pi(Raspbian Wheezy)에 node.js를 설치해서 테스트해보았다. 강좌(http://pyrasis.com/nodejs/nodejs-HOWTO)를 따라서 콘솔 메시지로 Hello World까지는 출력을 했지만, express 모듈을 설치하고 사용하는 것이 그리 순탄치 않다.

npm ERR! Error: failed to fetch from registry: express

위와 같은 메시지가 나타나며 패키지 설치에 실패한다든지, 세그멘테이션 오류가 발생한다든지 하는 문제가 생긴다.

다음의 명령으로 패키지를 제거한 뒤에,

sudo apt-get purge nodejs npm

다음의 명령으로 4.2.4 버전을 다시 설치했다.

wget http://nodejs.org/dist/v4.2.4/node-v4.2.4-linux-armv6l.tar.gz
cd /usr/local
sudo tar xzvf ~/node-v4.2.4-linux-armv6l.tar.gz --strip=1


참고

2016년 2월 20일 토요일

Edx.org 수강을 위한 최소 사양

Edx.org의 Body101x 강좌를 듣기 시작했다.

지난 번에 수리를 했던, 사무실에 둔 IBM A22e 2655 노트북은 펜티엄3 CPU에 현재 256MB 램을 갖고 있는데, 동영상 스트리밍으로 강좌를 보기에는 어려움이 있었다.

Lubuntu 14.04를 설치한 HP tx1000을 집에서 시험해보니, 파이어폭스 브라우저에서 동영상 강좌를 보고 문제를 푸는 데에 지장이 없다. AMD (Turion 64 X2 Mobile Technology) CPU에 RAM은 512MB만 남겨둔 상태. 다음에 사무실에 들릴 때 이걸로 바꿔야겠다.


tx1000



아이나비 네비게이션 SD 카드 문제 해결

5년째 사용하고 있는 차량용 네비게이션이 얼마 전부터 자꾸 먹통이 되어서 용산에 있는 팅크웨어 서비스센터에 방문했다(곧 다른 곳으로 이전한다고).
수리기사는 네비게이션 문제가 아니라 SD 카드 문제로 진단했다. 그러고보니, 라즈베리 파이에 쓰려고 구입했던 삼성 8GB 마이크로 SD 카드를 네비게이션에 쓰고, 원래 네비게이션에 쓰던 4GB 마이크로 SD 카드는 파이에 사용하고 있었다.

집에 와서, OpenELEC을 설치해서 쓰던 4GB SD 카드를 SD Formatter 프로그램으로 파티션 조정 및 포맷("FORMAT SIZE ADJUSTMENT" 옵션을 "ON"으로 설정하고 실행)한 뒤에, 아이나비 업데이트 프로그램으로 지도 데이터를 다시 넣었다.
오늘 카드를 바꿔끼고 두어 시간 운전을 해보니 아무 문제가 없다. :)

2016년 2월 16일 화요일

Blogger에 코드 구문 강조 적용

이 블로그(http://sk8erchoi-tech.blogspot.com/)에 쓰는 글에는 프로그램 소스 코드라든지, 명령행에서 입력하는 내용이 종종 포함된다. 본문과 코드가 뒤섞이다보면 읽기가 불편하고, 글을 쓰는 입장에서도 어떻게 처리해야할 지 난감하다. 그래서 검색을 좀 해보니 구문 강조(syntax highlighting)를 해주는 JavaScript 패키지가 몇 가지 있다.

이번에 적용한 것은 highlight.js이다. 다음과 같이 블로거에 적용했다.

1. 블로거의 템플릿 메뉴에서 HTML 편집 버튼 클릭. </head> 윗줄에 다음의 코드를 삽입.
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script>

 2. 게시물의 코드 부분을 다음과 같이 pre와 code 태그를 사용하여 감싸기.
<pre><code class="python">print("hello")</code></pre>

3. 스타일(테마)을 변경하고 싶으면, 데모 페이지에서 원하는 스타일의 이름을 알아둔 다음, 스타일 디렉터리에서 해당되는 파일명을 확인하고, 1.의 템플릿 HTML을 수정. 예를 들어, Tomorrow Night 스타일을 적용하려면 default.min.css를 tomorrow-night.min.css로 변경한다.

2016년 2월 15일 월요일

Lenovo X230 Windows 10 Wi-Fi 문제 해결

Lenovo X230 노트북에 Windows 10을 설치하여 사용하다보니, Wi-Fi 네트워크에 연결이 되어도 "제한됨"으로 표시되고 인터넷이 잘 되지 않는 문제가 있다. 그때마다 연결을 끊었다가 다시 붙이기를 몇 번 씩 해서 사용해왔는데, 아무래도 불편하다.
Intel 사이트에서 Intel® Centrino® Advanced-N 6205, Dual Band 용 소프트웨어 및 드라이버(Wireless_18.21.0_e164.exe)를 다운로드하여 설치하고, 결과를 지켜보는 중.
https://downloadcenter.intel.com/download/25511/Intel-PROSet-Wireless-Software-for-Windows-8-1-

2016년 2월 14일 일요일

Raspberry Pi MP3 Player

Raspberry Pi와 PiFaceCAD를 사용하여 MP3 플레이어를 만들어보았다. 이것도 역시 스터디 숙제. 음악 파일의 재생을 위해 pygame.mixerpygame.mixer.music을 사용했다.



소스 코드:

#!/usr/bin/python3

from pygame import mixer
import time

class Player:
    def __init__(self):
        self.isOn = True
        self.isPlaying = False
        self.isPaused = False

        show("MP3 Player")
        mixer.init()
        self.musicVolume = round(mixer.music.get_volume(), 1)
        import glob
        self.musicFiles = tuple(sorted(glob.glob("*.mp3")))
        self.musicNum = 0
        filename = self.musicFiles[self.musicNum]
        show(filename + "\nReady")

    def listen(self, sw_id, func, always=False):
        if cad.switches[sw_id].value == 1 and (always or self.isOn):
            while cad.switches[sw_id].value == 1: pass
            print('self.%s()' % func)
            exec('self.%s()' % func)

    def playPause(self):
        if self.isPlaying:
            self.pause()
        else:
            if self.isPaused:
                self.resume()
            else:
                self.play()

    def play(self):
        filename = self.musicFiles[self.musicNum]
        mixer.music.load(filename)
        self.musicTitle = filename
        show(self.musicTitle + "\nPlaying")
        mixer.music.play()
        self.isPlaying = True

    def pause(self):
        self.isPlaying = False
        mixer.music.pause()
        show(self.musicTitle + "\nPaused")
        self.isPaused = True

    def resume(self):
        self.isPlaying = True
        show(self.musicTitle + "\nPlaying")
        mixer.music.unpause()
        self.isPaused = False

    def prev(self):
        self.musicNum = (self.musicNum - 1) % len(self.musicFiles)
        self.play()

    def next(self):
        self.musicNum = (self.musicNum + 1) % len(self.musicFiles)
        self.play()

    def randomPlay(self):
        import random
        self.musicNum = random.choice(range(len(self.musicFiles)))
        self.play()

    def volumeUp(self):
        self.setVolume("up")

    def volumeDown(self):
        self.setVolume("down")

    def setVolume(self, action):
        min, max, delta = 0.0, 1.0, 0.1
        vol = mixer.music.get_volume()
        vol = round(vol, 1)

        if action is "up" and vol < max:
            vol = round(vol + delta, 1)
            mixer.music.set_volume(vol)
            show(self.musicTitle + "\nvol: " + str(vol))
            self.musicVolume = vol
        elif action is "down" and vol > min:
            vol = round(vol - delta, 1)
            mixer.music.set_volume(vol)
            show(self.musicTitle + "\nvol: " + str(vol))
            self.musicVolume = vol
        elif action is "mute":
            if vol == min:
                vol = self.musicVolume
                mixer.music.set_volume(vol)
                show(self.musicTitle + "\nvol: " + str(vol))
            else:
                vol = min
                mixer.music.set_volume(vol)
                show(self.musicTitle + "\nMuted")
        else:
            pass

    def mute(self):
        self.setVolume("mute")

    def onOff(self):
        if self.isOn:
            if self.isPlaying:
                mixer.music.stop()
            show('Bye...')
            time.sleep(2)
            cad.lcd.backlight_off()
            time.sleep(1)
            cad.lcd.clear()
            self.isOn = False
        else:
            self.__init__()

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()
cad.lcd.cursor_off()
cad.lcd.blink_off()

def show(text):
    cad.lcd.clear()
    cad.lcd.write(text)

p = Player()

while True:
    p.listen(0, 'playPause')
    p.listen(1, 'prev')
    p.listen(2, 'next')
    p.listen(3, 'randomPlay')
    p.listen(4, 'onOff', True)
    p.listen(5, 'mute')
    p.listen(6, 'volumeDown')
    p.listen(7, 'volumeUp')

2016년 2월 10일 수요일

line.co.kr

line.co.kr 도메인을 둘러싼 송사에 관한 소식이 들리기에 간단히 생각을 써둔다.

라인 코퍼레이션이 법적으로 잘못한 것은 없다. 그렇다면 도덕적으로는 잘못했나? 내 생각엔 그렇지 않다. 협상이 잘 안되니 조정을 거쳤을 것이다. 오히려 도메인 이름을 선점한 것을 가지고 한몫 잡아보려한 사람이 뜻대로 일이 풀리지 않으니 송사와 언론 플레이를 시도했지만, 사리에 어둡고 과정이 치밀하지 못했기 때문에 제 풀에 넘어진 것이다.

도메인을 내놓게 된 그 사람은 이제 일본 회사가 한국의 개인을 등쳐먹는 듯한 구도를 억지로 만들어가려고 하고, 이에 몇몇 사람들은 케케묵은 일본에 대한 앙금을 토해내고, 또 어떤 이들은 악덕 기업과 헬조선을 건져올린다. 신물 난다.

한국인은 늘 감정을 앞세우다가 이성을 잃고 손해를 보는 듯하다. 그 와중에 이성적인 판단을 했던 이들까지 지탄을 받는다.

한 줄 요약: 그냥 라인이 십만 달러 지르고 생색 냈으면(그 일을 마케팅 소재로 삼았으면) 차라리 좋았을 것을...

PiFaceCAD

올해 초부터 우분투 한국 사용자모임에서 시작한 Raspberry Pi 스터디에 매주 나가고 있다. Pi에서 node.js를 구동하여 웹을 통해 이런저런 장치를 제어하는 것을 목표로 하는데, 작업의 편의를 위해 PiFaceCAD(PiFace Control and Display)라는 제품을 구입해서 사용하기로 했다. 들고다니다가 망가뜨리지 않을까 걱정이 되어, Raspberry Pi에 PiFaceCAD를 꽂은 채로 넣을 수 있는 케이스도 함께 샀다.

PiFaceCAD에 친숙해지기 위해 Python으로 스코어보드를 만들어보는 숙제가 있었다. LCD에 두 팀의 점수를 보여주는 기능을 하며, 각 팀의 점수를 올리기 위한 스위치 한 개 씩과, 점수를 리셋하는 용도의 스위치 한 개를 사용한다.


위의 영상과 같이 동작하며, 내가 짠 코드는 다음과 같다. (먼저 셋업이 필요하다)

#!/usr/bin/python3

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()

def show():
    cad.lcd.clear()
    cad.lcd.write('A team:' + str(score[0]) + '\n'
                  + 'B team:' + str(score[1]))

score = [0, 0]
show()

while True:
    if cad.switches[0].value == 1:
        score[0] = score[0] + 1
        while cad.switches[0].value == 1: pass
        show()
    elif cad.switches[1].value == 1:
        score[1] = score[1] + 1
        while cad.switches[1].value == 1: pass
        show()
    elif cad.switches[4].value == 1:
        score = [0, 0]
        while cad.switches[4].value == 1: pass
        show()

스위치를 한 번 누르는 동안 여러 점이 올라가는 것을 막기 위해, 손을 뗄 때까지 pass시키는 작은 while 문을 넣었다. 다른 사람들은 time.sleep()을 사용해서 처리했다. 이때, 일반적으로 0.25 초 정도의 sleep이 적당하다고 한다.

작성해놓고 보니 while 블록에서 중복으로 나타나는 것들을 정리하고 싶어져서 아래와 같이 바꾸었다.

#!/usr/bin/python3

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()

def show():
    cad.lcd.clear()
    cad.lcd.write('A team:' + str(score[0]) + '\n'
                  + 'B team:' + str(score[1]))

def listen(i, func):
    global score
    if cad.switches[i].value == 1:
        if func == 'add': score[i] = score[i] + 1
        elif func == 'reset': score = [0, 0]
        while cad.switches[i].value == 1: pass
        show()

score = [0, 0]
show()

while True:
    listen(0, 'add')
    listen(1, 'add')
    listen(4, 'reset')

다음의 코드는, 위쪽에 붙은 로커 스위치를 테스트해보기 위해 수정한 버전이다.

#!/usr/bin/python3

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()

def show():
    cad.lcd.clear()
    cad.lcd.write('A team:' + str(score[0]) + '\n'
                  + 'B team:' + str(score[1]))

def listen(i, func, team=None):
    global score
    if cad.switches[i].value == 1:
        if func == 'add': score[team] = score[team] + 1
        elif func == 'reset': score = [0, 0]
        while cad.switches[i].value == 1: pass
        show()

score = [0, 0]
show()

while True:
    listen(5, 'reset')
    listen(6, 'add', 0)
    listen(7, 'add', 1)

2016년 2월 3일 수요일

PyAudio

앞의 글에서는 Raspberry Pi에 USB 마이크를 연결하고 arecord와 aplay 명령을 사용하여 소리의 녹음과 재생을 해보았는데, 이번에는 같은 일을 Python에서 시도해 보았다. 사용한 라이브러리는 PyAudio라는 것으로, PortAudio의 Python 바인딩이다.


PyAudio 설치


다음의 명령으로 라이브러리를 설치한다.

$ sudo apt-get install python-pyaudio


Wav 파일 재생


PyAudio 홈페이지에 소개된, wav 파일을 재생하는 예제를 실행해보았다.
http://people.csail.mit.edu/hubert/pyaudio/#play-wave-example

경고 메시지가 많이 뜨긴 하지만 일단 무시했다. 소리가 많이 끊어져 들렸는데, CHUNK 값을 2048로 조정하니 조금 좋아졌지만 여전히 끊기는 듯한 느낌이 든다.


Wav 파일 녹음


이번에는 소리를 wav 파일로 녹음하는 예제를 실행해보았다.
http://people.csail.mit.edu/hubert/pyaudio/#record-example

IOError 메시지가 떴는데, 역시 CHUNK 값을 조정하여 해결했다. 이번에는 4096으로 설정. 그리고, 모노 마이크를 사용하기 때문에 CHANNELS = 1로 설정했다.

2016년 2월 1일 월요일

Raspberry Pi에서 소리 입력 및 녹음하기

Raspberry Pi는 소리를 출력할 수 있지만, 아날로그 마이크를 연결해서 소리를 녹음할 수 없다. 그래서 ① 마이크가 내장된 USB 카메라를 사용하거나,  ② USB 사운드카드에 마이크를 연결한다. 내가 선택한 것은 ③ USB 동글 형태의, 사운드카드와 마이크 일체형(?)으로, "USB Microphone" 비슷한 이름이 붙은 물건이다. eBay에서 1.65 달러에 구입했다.

http://www.ebay.com/itm/231668535198?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

USB 마이크


구성 및 테스트

  1. USB 마이크를 Pi에 꽂은 후, Pi에 전원을 넣는다.

  2. USB 오디오 녹음장치를 찾아본다.

    $ arecord -l
    **** List of CAPTURE Hardware Devices ****
    card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
      Subdevices: 1/1
      Subdevice #0: subdevice #0

    위에서는 card 번호가 1, device 번호가 0이다.

  3. 녹음해본다. 앞에서 알아낸 번호를 -D hw: 인자에 써준다.

    $ arecord -D hw:1,0 -f S16_LE -d 5 -r 44100 test.wav
    Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono

    만약 장치(-D 옵션)를 올바로 지정하지 않으면 다음과 같은 오류가 발생한다.

    arecord: main:682: audio open error: No such file or directory

    비트율(-r 옵션)을 생략하거나 부적당한 값을 지정하면 경고가 발생할 수 있다. 'got = '에 표시된 값으로 바꿔서 다시 녹음해본다.

    Warning: rate is not accurate (requested = 8000Hz, got = 44100Hz)
                    please, try the plug plugin

  4. 녹음된 파일을 재생해본다.

    $ aplay test.wav
    Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono

  5. 음량을 조절하려면 alsamixer를 실행한다. 처음 보이는 화면은 재생 음량이고, 탭을 한 번 누르면 녹음 음량이 보인다. 이때, <F6> 키를 누르고 사운드카드를 선택한 다음, 위아래 화살표 키로 음량을 조절한다. 스페이스 바를 눌러 "CAPTURE"라는 빨간 글씨가 보이도록 해야한다. <esc> 키로 종료한다.
    설정 값을 저장해두하려면 sudo alsactl store를 실행한다.

alsamixer

Raspberry Pi에서 MP3 오디오 재생하는 방법은 공식 문서(번역)를 참조.

참고

2016년 1월 17일 일요일

키보드 오작동

사용 중인 Microsoft Sculpt Ergonomic Desktop L5V-00001 키보드에서 한 가지 문제를 발견했다. '<' 기호의 입력이 잘 되지 않는 것이다. 원래 있던 문제를 2년 동안 모르고 지낸 것인지, 최근 들어 발생한 것인지 잘 모르겠다.

Shift 키가 작동하지 않는 것도 아니요, ',' 키도 잘 작동한다. 드라이버도 최신이고, 노트북의 키보드를 사용할 때에는 문제 없이 입력된다.

여러 번 시도하면서 알아낸 work-around는 이렇다. Shift 키를 누른 채로, ',' 키를 누르고, Shift 키에서 먼저 손을 떼고(이때 '<'가 입력됨), ',' 키에서도 손을 뗀다.

* 몇 주 지나고 보니 이 문제가 사라졌다. 배터리 수명이 다 되어서 그랬던 것일까.

2016년 1월 11일 월요일

Thinkpad 2655 수리

부팅이 되지 않지만 외관과 화면이 깨끗해 보이는 Thinkpad 2655 A22e 노트북이 중고나라에 올라온 것을 발견했다. 기존에 갖고 있던 같은 모델의 노트북을 수리할 요량으로, 판매자에게 쪽지를 보내어 구입했다.

많은 부품을 교체했다.
  • LCD 어셈블리: 화면의 얼룩이 심하고 시큼한 냄새가 나서 사용하기 불편했는데, 바꾸고 나니 새것 같다. A22e에도 13.1과 14.1 인치 모델이 있어서 혹시 안 맞을까 걱정했는데 다행히 잘 맞았다.
  • RAM: 64MB 짜리 2개에서 128MB 2개로 교체하니 사용하기가 훨씬 낫다.
  • CD롬 드라이브: 가만히 둬도 트레이가 열리곤 했는데, 바꾸고 나니 괜찮아졌다. 재미있는 점은, 이번에 구입한 노트북은 일본에서 생산된 일본 판매용 제품인데 ODD가 한국산이 들어가 있고, 내가 갖고 있던 노트북은 LG IBM에서 만든 한국 판매용 제품인데 ODD는 일제였다.
  • 키보드: 빨콩을 쓴 뒤 몇 초 동안 커서가 스르르 움직이는 현상이 있었는데, 키보드를 통째로 바꿔서 해결. 바꾼 것이 일본어 자판이라 왠지 재미있다.
  • 힌지 커버: 분해하다보니 힌지 커버가 여러 조각으로 쪼개지며 떨어져나갔다. 그래서 이것도 교체. 가운데 LCD 선 덮는 부분과 오른쪽 볼트 쪽이 깨지긴 했지만, 크게 눈에 띄지 않는다.
  • 키보드 베젤: 가장 눈에 띄는 엄지 손가락 사이의 정중앙 앞쪽에 금이 가 있었는데, 교체하고 나니 새것 같다. 한 가지 어려웠던 점은, 두 제품의 시스템 보드가 약간 다르고, 그에 따라 LED 빛을 이어주는 투명한 플라스틱의 크기가 달랐다. 베젤의 플라스틱을 살짝 지져서 마치 리벳처럼 접합되어 있었기에, 칼로 대가리를 살짝 따내어 분리할 수 있었다.


LCD 작동여부 테스트 중에 한 컷

2016년 1월 5일 화요일

모니터 없이 VNC를 통해 Raspberry Pi에 연결하기

Raspberry Pi에 VNC 서버를 띄우면, 네트워크의 다른 컴퓨터에서 Pi의 화면을 보면서 조작할 수 있다. 즉, Pi를 헤드레스(Pi에 키보드, 마우스와 모니터를 연결하지 않음)로 사용하더라도 VNC를 통해 대부분의 작업을 할 수 있다.


iOS 용 VNC 클라이언트


앱 스토어에도 VNC 클라이언트가 있기에, 놀고 있는 구형 iPad에게 Pi의 터미널로서의 새로운 역할을 부여하는 것도 좋겠다는 생각이 들었다. 그러나, VNC 앱을 설치하려고 하니 iOS 7.0 이상에서 설치가 가능하다며 진행이 되지 않았다. iPad 1세대는 iOS 5.1.1에서 더 이상 업데이트되지 않기 때문이다. 그러나, 다행히 PC의 iTunes에서 앱을 설치할 수 있었다.


Pi에 연결하기


VNC Viewer에서 Pi에 접속하기 위해서는 처음에 앱의 + 버튼을 눌러서 IP 주소를 넣어주면 된다. 그런데, Pi에 고정 IP를 부여하기 곤란한 상황에서는, Pi의 IP 주소가 바뀔 때마다 VNC Viewer에서도 바꿔주어야 한다. 특히 헤드레스로 구동할 때에는 문제가 된다. iOS와 Mac에서는 이 문제를 Avahi와 Bonjour를 이용하여 우아하게 해결할 수 있다.

Windows를 사용하며 여분의 LAN 포트가 있는 노트북이라면, LAN 케이블로 직접 연결하는 방법이 있다. 유/무선 LAN에 접근할 수 없을 때 유용하다. arp 명령으로 주소를 알아내고 VNC Viewer의 접속 정보를 편집하는 귀찮은 과정이 필요하지만, 어쨌든 접속은 할 수 있다.

Raspberry Pi 모델 A/A+, zero 등 LAN 포트가 없는 모델이라면 USB 랜카드라든지, 직렬 케이블 등을 사용해서 어떻게든 삽질을 해볼 수는 있겠다.