Tinker Board : 한글 입력기 설치

OS/Tinker Board 2018.09.30 18:00 Posted by 파란크리스마스

출처

ip 확인

$ ip addr | grep inet
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
    inet 192.168.137.101/24 brd 192.168.137.255 scope global dynamic eth0
    inet 192.168.137.145/24 brd 192.168.137.255 scope global secondary eth0
    inet6 fe80::b848:f27d:8127:389/64 scope link

eMMC에 OS 설치

$ sudo dd if=20180622-tinker-board-linaro-stretch-alip-v2.0.7.img of=/dev/mmcblk1 bs=4MB status=progress conv=sync
3096000000 bytes (3.1 GB, 2.9 GiB) copied, 70.0279 s, 44.2 MB/s 
782+1 records in
783+0 records out
3132000000 bytes (3.1 GB, 2.9 GiB) copied, 71.9111 s, 43.6 MB/s

리눅스 정보 확인

$ grep . /etc/*-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

OS 업데이트

$ sudo apt-get update && sudo apt-get upgrade

Tinker Board 환경설정

$ sudo tinker-config

용량 확장

locale 변경

재부팅후 폴더 이름 변경 설정 팝업

한글폰트 설치 (나눔폰트 - nanum)

$ sudo apt install fonts-nanum fonts-nanum-coding fonts-nanum-extra

한글 입력기(nabi, imhangul) 설치

$ sudo apt-get install nabi imhangul-gtk2 imhangul-gtk3 im-config zenity

입력기 설정

$ im-config -n hangul

입력기 환경설정

$ im-config

한글입력예

환경설정

$ cat .xinputrc 
## im-config(8) generated on Thu, 11 Oct 2018 06:17:20 +0000
run_im hangul
## im-config signature: ef7d60ee7a0f5fd446ce389716f52467  -
 
export XIM=nabi
export XIM_ARGS=
export XIM_PROGRAM="nabi"
export XMODIFIERS="@im=nabi"
export GTK_IM_MODULE=xim
export QT_IM_MODULE=xim

내용 추가

export XIM=nabi
export XIM_ARGS=
export XIM_PROGRAM="nabi"
export XMODIFIERS="@im=nabi"
export GTK_IM_MODULE=xim

Tinker Board : CodeTyphone

OS/Tinker Board 2018.09.30 03:56 Posted by 파란크리스마스

출처

컴파일하는 동안 ‘out of memory’을 방지하기 위해 스왑 파일을 활성화

$ sudo apt-get install -y dphys-swapfile

dphys-swapfile 서비스 실행

$ sudo /etc/init.d/dphys-swapfile start
Starting dphys-swapfile (via systemctl): dphys-swapfile.service==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'dphys-swapfile.service'.
Authenticating as: linaro,,, (linaro)
==== AUTHENTICATION COMPLETE ===

"sudo" 루트 권한 부여

$ sudo vi /etc/sudoers

linaro ALL=(ALL) NOPASSWD: ALL

CodeTyphon 다운로드

$  wget http://www.pilotlogic.com/codetyphon/zips/CodeTyphonIns.zip

CodeTyphon 압축 해제

$ unzip CodeTyphonIns.zip

CodeTyphon 설치 스크립트 실행

$ cd CodeTyphonIns/
$ ./install.sh 
 
====================================================
             CodeTyphon Studio 
            Version 6.50 (GEN 6)
   Installation for: Linux-Solaris-FreeBSD-MacOS
====================================================
 
   0) Install CodeTyphon Studio
 
   9) Exit
 
>>> Select an action (press 0..9 key): 0

0번 선택 ( 0) Install System Libraries )

====================================================
  CodeTyphon Studio 6.50 Setup for Linux32
   Settings: Platform=gtk2  Multiarch Mode=0
====================================================
   
   0) Install System Libraries
   1) Run CodeTyphon Center (CTC)
   
     11) -- Platform (widget) Setup
     12) -- Multi-Architecture Setup
   
   3) Remove FreePascal
   4) Remove and Build FreePascal
   
   5) Remove Typhon IDE
   6) Remove and Build Typhon IDE
   
   7) Remove ALL
   8) Remove and Build ALL
   
   9) EXIT
   
>>> Select an action (press 0..9 key): 0

8번 선택 ( 8) Remove and Build ALL )

====================================================
  CodeTyphon Studio 6.50 Setup for Linux32
   Settings: Platform=gtk2  Multiarch Mode=0
====================================================
   
   0) Install System Libraries
   1) Run CodeTyphon Center (CTC)
   
     11) -- Platform (widget) Setup
     12) -- Multi-Architecture Setup
   
   3) Remove FreePascal
   4) Remove and Build FreePascal
   
   5) Remove Typhon IDE
   6) Remove and Build Typhon IDE
   
   7) Remove ALL
   8) Remove and Build ALL
   
   9) EXIT
   
>>> Select an action (press 0..9 key): 8

9번 선택 ( 9) EXIT )

====================================================
  CodeTyphon Studio 6.50 Setup for Linux32
   Settings: Platform=gtk2  Multiarch Mode=0
====================================================
   
   0) Install System Libraries
   1) Run CodeTyphon Center (CTC)
   
     11) -- Platform (widget) Setup
     12) -- Multi-Architecture Setup
   
   3) Remove FreePascal
   4) Remove and Build FreePascal
   
   5) Remove Typhon IDE
   6) Remove and Build Typhon IDE
   
   7) Remove ALL
   8) Remove and Build ALL
   
   9) EXIT
   
>>> Select an action (press 0..9 key): 9

실행

Tinker Board : RDP (원격 데스크톱) 설치

OS/Tinker Board 2018.09.17 01:12 Posted by 파란크리스마스

출처

xrdp 설치

$ sudo apt-get install xrdp
$ sudo apt-cache policy xrdp
xrdp:
  Installed: 0.9.1-9+deb9u3
  Candidate: 0.9.1-9+deb9u3
  Version table:
 *** 0.9.1-9+deb9u3 500
        500 http://http.debian.net/debian stretch/main armhf Packages
        100 /var/lib/dpkg/status

xorgxrdp 설치

$ sudo apt-get install xorgxrdp
$ sudo apt-cache policy xorgxrdp
xorgxrdp:
  Installed: 0.9.1-9+deb9u3
  Candidate: 0.9.1-9+deb9u3
  Version table:
 *** 0.9.1-9+deb9u3 500
        500 http://http.debian.net/debian stretch/main armhf Packages
        100 /var/lib/dpkg/status

IP 확인

$ ip addr | grep inet
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
    inet 192.168.137.142/24 brd 192.168.137.255 scope global dynamic eth0
    inet6 fe80::2edd:91a0:cbe0:6514/64 scope link

원격 데스크톱 연결

Tinker Board : Lazarus 설치

OS/Tinker Board 2018.09.16 12:26 Posted by 파란크리스마스

출처

OS 업그레이드

$ sudo apt-get update
$ sudo apt-get upgrade

기존 전치된 lazarus 삭제

$ sudo apt-get remove lazarus
$ sudo apt-get remove fpc
$ sudo apt-get autoremove
$ sudo shutdown -r now

Swap 파일 크기 늘리기

여유 공간 확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        15G  8.3G  5.5G  61% /
devtmpfs        943M     0  943M   0% /dev
tmpfs          1007M     0 1007M   0% /dev/shm
tmpfs          1007M  8.9M  998M   1% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs          1007M     0 1007M   0% /sys/fs/cgroup
/dev/mmcblk1p1   63M  7.5M   56M  12% /boot
tmpfs           202M  8.0K  202M   1% /run/user/1000

Swap 설정 파일 수정

$ sudo vi /etc/dphys-swapfile

Swap 사이즈 설정

CONF_SWAPSIZE=1000

Swap 설정 파일을 저장하고 스와핑을 다시 시작

$ sudo /etc/init.d/dphys-swapfile stop
Stopping dphys-swapfile (via systemctl): dphys-swapfile.service.
$ sudo /etc/init.d/dphys-swapfile start
Starting dphys-swapfile (via systemctl): dphys-swapfile.service.
$ ls -lh /var
total 1001M
drwxr-xr-x  2 root root   4.0K Sep 16 01:22 backups
drwxr-xr-x 11 root root   4.0K Jul 21 10:44 cache
drwxr-xr-x 49 root root   4.0K Jul 21 20:09 lib
drwxrwsr-x  2 root staff  4.0K Nov 19  2017 local
lrwxrwxrwx  1 root root      9 Jan 10  2018 lock -> /run/lock
drwxr-xr-x  7 root root   4.0K Sep 16 03:29 log
drwxrwsr-x  2 root mail   4.0K Jan 10  2018 mail
drwxr-xr-x  2 root root   4.0K Jan 10  2018 opt
lrwxrwxrwx  1 root root      4 Jan 10  2018 run -> /run
drwxr-xr-x  7 root root   4.0K Jul 21 10:43 spool
-rw-------  1 root root  1000M Sep 16 03:43 swap
drwxrwxrwt  6 root root   4.0K Sep 16 03:30 tmp

Seed/Bootstrap Pascal Compiler 설치

$ mkdir /usr/local/fpc
$ wget ftp://ftp.hu.freepascal.org/pub/fpc/dist/3.0.4/arm-linux/fpc-3.0.4.arm-linux-eabihf-raspberry.tar
$ tar xvf fpc-3.0.4.arm-linux-eabihf-raspberry.tar 
fpc-3.0.4.arm-linux/
fpc-3.0.4.arm-linux/doc-pdf.tar.gz
fpc-3.0.4.arm-linux/binary.arm-linux.tar
fpc-3.0.4.arm-linux/install.sh
fpc-3.0.4.arm-linux/demo.tar.gz
$ mv fpc-3.0.4.arm-linux /usr/local/fpc/
$ cd /usr/local/fpc/fpc-3.0.4.arm-linux/
$ sudo ./install.sh

설치과정

linaro@tinkerboard:/usr/local/fpc/fpc-3.0.4.arm-linux$ sudo ./install.sh 
This shell script will attempt to install the Free Pascal Compiler
version 3.0.4 with the items you select

Install prefix (/usr or /usr/local)  [/usr] : 
Installing compiler and RTL for arm-linux...

Install Textmode IDE (Y/n) ? 
Done.

Install documentation (Y/n) ? 
Installing documentation in /usr/share/doc/fpc-3.0.4 ...
Done.

Install demos (Y/n) ? 
Install demos in [/usr/share/doc/fpc-3.0.4/examples] : 
Installing demos in /usr/share/doc/fpc-3.0.4/examples ...
Done.

Running on linux
Write permission in /etc.
Writing sample configuration file to /etc/fpc.cfg
Writing sample configuration file to /usr/lib/fpc/3.0.4/ide/text/fp.cfg
Writing sample configuration file to /usr/lib/fpc/3.0.4/ide/text/fp.ini
Writing sample configuration file to /etc/fppkg.cfg
Writing sample configuration file to /etc/fppkg/default

End of installation.

Refer to the documentation for more information.

svn 클라이언트 설치

$ sudo apt-get install subversion

관련 라이브러리 설치

$ sudo apt-get install libgtk2.0-dev libcairo2-dev libpango1.0-dev libgdk-pixbuf2.0-dev libatk1.0-dev libghc-x11-dev libx11-dev

Free Pascal 설치

$ cd /usr/local/fpc
$ svn co http://svn.freepascal.org/svn/fpc/trunk source 
$ cd source
$ sudo make all OPT="-dFPC_ARMHF -CpARMV7A -OpARMV7A"
$ sudo make install OPT="-dFPC_ARMHF -CpARMV7A -OpARMV7A" PREFIX=/usr/local
$ sudo make install sourceinstall OPT="-dFPC_ARMHF -CpARMV7A -OpARMV7A" PREFIX=/usr/local

설치된 pascal 버전 확인

$ ls /usr/lib/fpc
3.0.4  lexyacc

fpc 최신 버전으로 심볼릭 링크 걸기

$ ls -al /usr/bin/ppcarm
lrwxrwxrwx 1 root root 25 Sep 16 11:23 /usr/bin/ppcarm -> /usr/lib/fpc/3.0.4/ppcarm

fpc 컴파일러 버전 확인

$ fpc -iW
3.0.4

Lazarus 설치

관련 라이브러리 설치

$ sudo apt-get install libx11-dev libgdk-pixbuf2.0-dev libcairo2-dev gir1.2-coglpango-1.0 libpangox-1.0-dev xorg-dev libgtk2.0-dev libpango1.0-dev

Lazarus 다운로드 및 컴파일

$ mkdir /usr/local/lazarus
$ cd /usr/local/lazarus
$ svn co http://svn.freepascal.org/svn/lazarus/trunk source
$ cd source
$ sudo make all OPT="-dFPC_ARMHF -CpARMV7A -OpARMV7A"
$ sudo make install OPT="-dFPC_ARMHF -CpARMV7A -OpARMV7A" PREFIX=/usr/local

gcc 라이브러리 경로 설정

컴파일하면 crtbegin.o 및 crtend.o를 찾을 수 없다는 경고가 출력됩니다. 경고가 표지 되지 않도록 설정

crtbegin.o 찾기

$ sudo find / -name crtbegin.o
/usr/lib/gcc/arm-linux-gnueabihf/6/crtbegin.o

fpc 환경 파일 (fpc.cfg) 수정

$ sudo vi /etc/fpc.cfg

내용 추가

# path to the gcclib
-Fl/usr/lib/gcc/arm-linux-gnueabihf/6

gdb 설치

$ sudo apt-get install gdb-multiarch

Lazarus 실행

fpc 경로 오류

fpc 경로 찾기

fpc 경로 설정

Lazarus 실행화면

Tinker Board : Smart-Mirror 설치

OS/Tinker Board 2018.09.16 10:20 Posted by 파란크리스마스

출처

Tinker Board : Smart-Mirror 설치

Raspberry PI에서 사용햇던 Smart-Mirror를 Tinker Board에 적용해보았습니다. Raspberry PI이 보다 실행 속도가 많이 빨라 졌습니다. 모니터는 Raspberry PI 7인치 모니터를 사용했고, 미러용 필름은 붙이지는 않았습니다. 마이크의 입력은 4극 스테레오 Y케이블을 사용해서 특별하게 마이크 설정없이 바로 사용이 가능했습니다.

음성 인식용으로 사용했던 마이크

4극 스테레오 (3.5) Y케이블

Tinker Board용 Audio 단자는 마이크 입력과 오디오 출력이 동시에 가능한 4핀 단자로 아래와 같은 4극 Y케이블을 이용하면 마이크 입력과 오디오 출력을 분리해서 사용 할 수 있습니다.

4극 스테레오 (3.5) Y케이블에 마이크 연결

Node.js 6.x 설치

$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Smart-Mirror 소스 다운로드

$ cd ~
$ git clone https://github.com/evancohen/smart-mirror.git

Smart-Mirror 관련 라이브러리 설치

$ sudo apt-get install sox libatlas-base-dev

Smart-Mirror 설치

$ cd ~/smart-mirror
$ npm install

Smart-Mirror 실행

$ npm start

개발자 콘솔로 Smart-Mirror 실행

$ npm start dev

관리 페이지 접속

관리 페이지 오른쪽 상단 톱니바퀴 아이콘을 선택하면 Smart-Mirror 설정 화면으로 이동이 가능합니다.

언어 설정 변경 (한국어 명령이 가능하도록 설정)

Language 항목의 설정을 ko-KR로 수정

자신만의 호출 키워드 생성

이 작업은 마이크를 사용하여 smart-mirror가 대기 모드에서 명령 모드로 변경 됩니다.

키워드 생성은 사이트(https://snowboy.kitt.ai/hotword/47)에서 하시면 되고 저는 팅커보드의 약자로 팅커벨로 했습니다.

Snowboy에서 생성한 Tinkerbell.pmdl 파일을 smart-mirror가 설치된 경로(/home/linaro/smart-mirror)에 복사합니다.

호출 키워드 등록

Google Cloud Speech Keyfile 등록

출처 : Cloud Speech Recognition · Smart Mirror Documentation

keyfile 생성

Google Cloud Speech Keyfile 등록

모니터 세로 모드로 변경

$ vi .xsessionrc

#!/bin/sh
xrandr --output DSI-1 --rotate left

Smart-Mirror 실행 영상

Tinker Board : pi4j

OS/Tinker Board 2018.09.08 13:04 Posted by 파란크리스마스

출처

Tinker Board S : pi4j

Tinker Board의 pwm 제어 하는 예제는 python을 제외하고는 c언어나 java 예제를 찾을 수 없어서 wiringPi 라이브러리를 직접 컴파일 해보았지만 모터의 떨림도 심하고, 발열도 심해서 아직은 불안한것 같습니다. python의 pwm관련 소스를 wiringPi에 추가하고 다시 pi4j 라이브러리에 적용했습니다. pi4j라이브러리와 pi4j를 이용한 Servo.java 예제도 첨부했습니다.동영상을 보시면 알겠지만, 떨림도, 발열도 발생하지 않았습니다.

pi4j-core-1.2-SNAPSHOT.jar

TinkerBoardPin.java

package com.pi4j.io.gpio;

import java.util.EnumSet;

public class TinkerBoardPin extends PinProvider {

    // GPIO0_C1
    public static final Pin GPIO0_C1 = createDigitalPin(7, "GPIO0_C1");          // addGpioPinInfo(16+1, "GPIO0_C1", 7, PinInfo.DIGITAL_IN_OUT);

    // GPIO5B (GP5B0-GP5B7)
    public static final Pin GPIO5_B0 = createDigitalPin(16, "GPIO5_B0");         // addGpioPinInfo(160, "GPIO5_B0", 10, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B1 = createDigitalPin(15, "GPIO5_B1");         // addGpioPinInfo(160+1, "GPIO5_B1", 8, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B2 = createDigitalPin(4, "GPIO5_B2");          // addGpioPinInfo(160+2, "GPIO5_B2", 16, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B3 = createDigitalPin(5, "GPIO5_B3");          // addGpioPinInfo(160+3, "GPIO5_B3", 18, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B4 = createDigitalPin(0, "GPIO5_B4");          // addGpioPinInfo(160+4, "GPIO5_B4", 11, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B5 = createDigitalPin(21, "GPIO5_B5");         // addGpioPinInfo(160+5, "GPIO5_B5", 29, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B6 = createDigitalPin(2, "GPIO5_B6");          // addGpioPinInfo(160+6, "GPIO5_B6", 13, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_B7 = createDigitalPin(3, "GPIO5_B7");          // addGpioPinInfo(160+7, "GPIO5_B7", 15, PinInfo.DIGITAL_IN_OUT);

    // GPIO5C (GP5C0-GP5C3)                                                       // GPIO5C (GP5C0-GP5C3)
    public static final Pin GPIO5_C0 = createDigitalPin(22, "GPIO5_C0");          // addGpioPinInfo(168, "GPIO5_C0", 31, PinInfo.DIGITAL_IN_OUT);
    //public static final Pin GPIO5_C1 = createDigitalPin(168+1, "GPIO5_C1");     // addGpioPinInfo(168+1, "GPIO5_C1", -1, PinInfo.DIGITAL_IN_OUT);
    //public static final Pin GPIO5_C2 = createDigitalPin(168+2, "GPIO5_C2");     // addGpioPinInfo(168+2, "GPIO5_C2", -1, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO5_C3 = createDigitalPin(6, "GPIO5_C3");           // addGpioPinInfo(168+3, "GPIO5_C3", 22, PinInfo.DIGITAL_IN_OUT);

    // GPIO6A (GP6A0-GP6A1)
    public static final Pin GPIO6_A0 = createDigitalPin(1, "GPIO6_A0");           // addGpioPinInfo(184, "GPIO6_A0", 12, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO6_A1 = createDigitalPin(24, "GPIO6_A1");          // addGpioPinInfo(184+1, "GPIO6_A1", 35, PinInfo.DIGITAL_IN_OUT);
    // GPIO6A (GP6A3-GP6A4)
    public static final Pin GPIO6_A3 = createDigitalPin(28, "GPIO6_A3");          // addGpioPinInfo(184+3, "GPIO6_A3", 38, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO6_A4 = createDigitalPin(29, "GPIO6_A4");          // addGpioPinInfo(184+4, "GPIO6_A4", 40, PinInfo.DIGITAL_IN_OUT);

    // GPIO7A (GP7A7)
    public static final Pin GPIO7_A7 = createDigitalPin(27, "GPIO7_A7");          // addGpioPinInfo(216+7, "GPIO7_A7", 36, PinInfo.DIGITAL_IN_OUT);

    // GPIO7B (GP7B0-GP7B2)
    public static final Pin GPIO7_B0 = createDigitalPin(25, "GPIO7_B0");          // addGpioPinInfo(224, "GPIO7_B0", 37, PinInfo.DIGITAL_IN_OUT);
    //public static final Pin GPIO7_B1 = createDigitalPin(224+1, "GPIO7_B1");     // addGpioPinInfo(224+1, "GPIO7_B1", -1, PinInfo.DIGITAL_IN_OUT);
    //public static final Pin GPIO7_B2 = createDigitalPin(224+2, "GPIO7_B2");     // addGpioPinInfo(224+2, "GPIO7_B2", -1, PinInfo.DIGITAL_IN_OUT);

    // GPIO7CL (GP7C1-GP7C2)
    public static final Pin GPIO7_C1 = createDigitalPin(30, "GPIO7_C1");          // addGpioPinInfo(232+1, "GPIO7_C1", 27, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO7_C2 = createDigitalPin(31, "GPIO7_C2");          // addGpioPinInfo(232+2, "GPIO7_C2", 28, PinInfo.DIGITAL_IN_OUT);
    // GPIO7CH (GP7C6-GP7C7)
    public static final Pin GPIO7_C6 = createDigitalAndPwmPin(23, "GPIO7_C6");    // addPwmPinInfo(232+6, "GPIO7_C6", 33, 0, PinInfo.DIGITAL_IN_OUT_PWM);
    public static final Pin GPIO7_C7 = createDigitalAndPwmPin(26, "GPIO7_C7");    // addPwmPinInfo(232+7, "GPIO7_C7", 32, 1, PinInfo.DIGITAL_IN_OUT_PWM);

    // GPIO8A (GP8A3-GP8A7)
    public static final Pin GPIO8_A3 = createDigitalPin(11, "GPIO8_A3");          // addGpioPinInfo(248+3, "GPIO8_A3", 26, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO8_A4 = createDigitalPin(8, "GPIO8_A4");           // addGpioPinInfo(248+4, "GPIO8_A4", 3, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO8_A5 = createDigitalPin(9, "GPIO8_A5");           // addGpioPinInfo(248+5, "GPIO8_A5", 5, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO8_A6 = createDigitalPin(14, "GPIO8_A6");          // addGpioPinInfo(248+6, "GPIO8_A6", 23, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO8_A7 = createDigitalPin(10, "GPIO8_A7");          // addGpioPinInfo(248+7, "GPIO8_A7", 24, PinInfo.DIGITAL_IN_OUT);

    // GPIO8B (GP8B0-GP8B1)
    public static final Pin GPIO8_B0 = createDigitalPin(13, "GPIO8_B0");          // addGpioPinInfo(256, "GPIO8_B0", 21, PinInfo.DIGITAL_IN_OUT);
    public static final Pin GPIO8_B1 = createDigitalPin(12, "GPIO8_B1");          // addGpioPinInfo(256+1, "GPIO8_B1", 19, PinInfo.DIGITAL_IN_OUT);

    protected static Pin createDigitalPin(int address, String name) {
        return createDigitalPin(TinkerBoardGpioProvider.NAME, address, name);
    }

    protected static Pin createDigitalPinNoEdge(int address, String name, EnumSet<PinPullResistance> resistance) {
        return createDigitalPin(TinkerBoardGpioProvider.NAME, address, name, resistance, EnumSet.noneOf(PinEdge.class));
    }

    protected static Pin createDigitalPinNoEdge(int address, String name) {
        return createDigitalPin(TinkerBoardGpioProvider.NAME, address, name, EnumSet.noneOf(PinEdge.class));
    }

    protected static Pin createDigitalAndPwmPin(int address, String name) {
        return createDigitalAndPwmPin(TinkerBoardGpioProvider.NAME, address, name);
    }

    protected static Pin createDigitalAndPwmPinNoEdge(int address, String name) {
        return createDigitalAndPwmPin(TinkerBoardGpioProvider.NAME, address, name, EnumSet.noneOf(PinEdge.class));
    }

    // *override* static method from subclass
    // (overriding a static method is not supported in Java
    //  so this method definition will hide the subclass static method)
    public static Pin getPinByName(String name) {
        return PinProvider.getPinByName(name);
    }

    // *override* static method from subclass
    // (overriding a static method is not supported in Java
    //  so this method definition will hide the subclass static method)
    public static Pin getPinByAddress(int address) {
        return PinProvider.getPinByAddress(address);
    }

    // *override* static method from subclass
    // (overriding a static method is not supported in Java
    //  so this method definition will hide the subclass static method)
    public static Pin[] allPins() { return PinProvider.allPins(); }

    // *override* static method from subclass
    // (overriding a static method is not supported in Java
    //  so this method definition will hide the subclass static method)
    public static Pin[] allPins(PinMode ... mode) { return PinProvider.allPins(mode); }
}

servo.c

#include <stdio.h>
#include "RKIO.h"
#include "wiringTB.h"
#include "constants.h"
#include "common.h"
#include "c_gpio.h"
#include "py_gpio.h"
#include "py_pwm.h"

int main ()
{
	printf("servo.main\n");
	
	int myservo = 239;
	
	//GPIO.setmode(GPIO.ASUS)
	py_setmode(ASUS);
	
	//GPIO.setup(myservo,GPIO.OUT)
	py_setup_channel(myservo, OUTPUT);
	
	//pwm = GPIO.PWM(myservo,50) # 50hz yani 20mslik periyod
	PWMObject pwm;
	PWM_init(&pwm, myservo, 50);
	printf("pwm.gpio = %d\n", pwm.gpio);
	
	//pwm.start(2.5) # 0 derece
	PWM_start(&pwm, 2.5);
	
	//pwm.ChangeDutyCycle(2.5) #0 derece
	PWM_ChangeDutyCycle(&pwm, 2.5);
	sleep( 1 );
  
	//pwm.ChangeDutyCycle(7.5) #90 derece
	PWM_ChangeDutyCycle(&pwm, 7.5);
	sleep( 1 );
	
	//pwm.ChangeDutyCycle(12.5) #180 derece
	PWM_ChangeDutyCycle(&pwm, 12.5);
	sleep( 1 );
	
	//pwm.ChangeDutyCycle(7.5)
	PWM_ChangeDutyCycle(&pwm, 7.5);
	sleep( 1 );
	
	//pwm.ChangeDutyCycle(2.5) #0 derece
	PWM_ChangeDutyCycle(&pwm, 2.5);
	sleep( 1 );
  
 	//pwm.ChangeDutyCycle(7.5)
	PWM_ChangeDutyCycle(&pwm, 7.5);
	sleep( 1 );
	
	PWM_dealloc(pwm);
}

컴파일

$ gcc -lm -lpwmBx servo.c -o servo

Servo.java

import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.TinkerBoardGpioProvider;
import com.pi4j.wiringpi.ASUSGpio;
import com.pi4j.wiringpi.PWMObject;

public class Servo {

	public static void main(String[] args) throws Exception {

		GpioFactory.setDefaultProvider(new TinkerBoardGpioProvider());

		int myservo = 239;

		//GPIO.setmode(GPIO.ASUS)
		ASUSGpio.pySetmode(ASUSGpio.ASUS);

		//GPIO.setup(myservo,GPIO.OUT)
		ASUSGpio.pySetupChannel(myservo, ASUSGpio.OUTPUT);

		//pwm = GPIO.PWM(myservo,50) # 50hz yani 20mslik periyod
		PWMObject pwm = ASUSGpio.pwmInit(myservo, 50);
		System.out.println("pwm.gpio = "+ pwm.gpio + "/" + pwm.freq + "/" + pwm.dutycycle);

		//pwm.start(2.5) # 0 derece
		ASUSGpio.pwmStart(pwm, 2.5f);
		Thread.sleep( 1000 );

		//pwm.ChangeDutyCycle(2.5) #0 derece
		ASUSGpio.pwmChangeDutyCycle(pwm, 2.5f);
		Thread.sleep( 1000 );

		//pwm.ChangeDutyCycle(7.5) #90 derece
		ASUSGpio.pwmChangeDutyCycle(pwm, 7.5f);
		Thread.sleep( 1000 );

		//pwm.ChangeDutyCycle(12.5) #180 derece
		ASUSGpio.pwmChangeDutyCycle(pwm, 12.5f);
		Thread.sleep( 1000 );

		//pwm.ChangeDutyCycle(7.5)
		ASUSGpio.pwmChangeDutyCycle(pwm, 7.5f);
		Thread.sleep( 1000 );

		//pwm.ChangeDutyCycle(2.5) #0 derece
		ASUSGpio.pwmChangeDutyCycle(pwm, 2.5f);
		Thread.sleep( 1000 );

		//pwm.ChangeDutyCycle(7.5)
		ASUSGpio.pwmChangeDutyCycle(pwm, 7.5f);
		Thread.sleep( 1000 );
		
		ASUSGpio.pwmDealloc(pwm);
	}
}

컴파일

$ javac -cp .:pi4j-core-1.2-SNAPSHOT.jar Servo.java

실행

$ java -cp .:pi4j-core-1.2-SNAPSHOT.jar Servo

실행 동영상

Tinker Board : C언어를 이용한 GPIO LED 제어

OS/Tinker Board 2018.09.03 00:55 Posted by 파란크리스마스

출처

led.c

#include <stdio.h>
#include <wiringpi.h>

// #define LED 0 matches with ASUS_GPIO 164! This can be checked with command 'sudo gpio readall'.
#define LED     8

int main (void)
{
         printf ("TB blink\n");

         wiringPiSetup ();
         pinMode (LED, OUTPUT);

         for (;;)
         {
                 printf ("led on\n");
                 digitalWrite (LED, HIGH);
                 delay (500);
                 printf ("led off\n");
                 digitalWrite (LED, LOW);
                 delay (500);
         }
         return 0;
}

컴파일

$ gcc -o led led.c -lwiringPi

실행

$ ./led

Tinker Board : PWM(서보모터) 제어

OS/Tinker Board 2018.09.02 16:13 Posted by 파란크리스마스

출처

Tinker Board S : PWM(서보모터) 제어

wiringPi라이브러리의 설치

$ git clone https://github.com/TinkerBoard/gpio_lib_c.git
$ cd gpio_lib_c/
$ chmod a+x build
$ sudo ./build
 
... 생략 ...
 
[Install Dynamic Lib]
 
GPIO Utility
[Compile] gpio.c
[Compile] readall.c
[Compile] pins.c
[Link]
[Install]
 
All Done.
 
NOTE: To compile programs with wiringPi, you need to add:
    -lwiringPi
  to your compile line(s) To use the Gertboard, MaxDetect, etc.
  code (the devLib), you need to also add:
    -lwiringPiDev
  to your compile line(s).

gpio readall

$ gpio readall
wiringPi: wiringPiSetup called
piGpioLayout: Hardware: Hardware        : Rockchip (Device Tree)
 
piGpioLayout: Revision string: Revision : 0000
piGpioLayout: last4Chars are: "0000"
piGpioLayoutOops: Returning revision: 2
piboardId: Revision string: Revision    : 0000
piBoardId: Old Way: revision is: 0000
piBoardId: 2: revision is: 0000
piboardId: Revision string: Revision    : 0000
piBoardId: Old Way: revision is: 0000
piBoardId: 2: revision is: 0000
 +-----+-----+---------+------+---+--Tinker--+---+------+---------+-----+-----+
 | CPU | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | CPU |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 | 252 |   8 |   SDA.1 |  I2C | 1 |  3 || 4  |   |      | 5v      |     |     |
 | 253 |   9 |   SCL.1 |  I2C | 1 |  5 || 6  |   |      | 0v      |     |     |
 |  17 |   7 | GPIO0C1 |   IN | 1 |  7 || 8  | 1 | SERL | TxD.1   | 15  | 161 |
 |     |     |      0v |      |   |  9 || 10 | 1 | SERL | RxD.1   | 16  | 160 |
 | 164 |   0 |  CTSN.4 | SERL | 1 | 11 || 12 | 0 | I2S  | I2S_CLK | 1   | 184 |
 | 166 |   2 |   TxD.4 | SERL | 1 | 13 || 14 |   |      | 0v      |     |     |
 | 167 |   3 |   RxD.4 | SERL | 1 | 15 || 16 | 1 | SERL | CTSN.1  | 4   | 162 |
 |     |     |    3.3v |      |   | 17 || 18 | 1 | SERL | RTSN.1  | 5   | 163 |
 | 257 |  12 |  MOSI.2 |  SPI | 0 | 19 || 20 |   |      | 0v      |     |     |
 | 256 |  13 |  MISO.2 |  SPI | 1 | 21 || 22 | 0 | IN   | GPIO5C3 | 6   | 171 |
 | 254 |  14 |  SCLK.2 |  SPI | 0 | 23 || 24 | 1 | SPI  | CE0.2   | 10  | 255 |
 |     |     |      0v |      |   | 25 || 26 | 1 | SPI  | CE1.2   | 11  | 251 |
 | 233 |  30 |   SDA.4 |  I2C | 1 | 27 || 28 | 1 | I2C  | SCL.4   | 31  | 234 |
 | 165 |  21 |  RTSN.4 | SERL | 1 | 29 || 30 |   |      | 0v      |     |     |
 | 168 |  22 | GPIO5C0 |   IN | 1 | 31 || 32 | 0 | OUT  | GPIO7C7 | 26  | 239 |
 | 238 |  23 |   PWM.2 |  PWM | 0 | 33 || 34 |   |      | 0v      |     |     |
 | 185 |  24 |  I2S_FS |  I2S | 0 | 35 || 36 | 1 | SERL | RxD.3   | 27  | 223 |
 | 224 |  25 |   TxD.3 | SERL | 1 | 37 || 38 | 1 | I2S  | I2S_SDI | 28  | 187 |
 |     |     |      0v |      |   | 39 || 40 | 0 | I2S  | I2S_SDO | 29  | 188 |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | CPU | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | CPU |
 +-----+-----+---------+------+---+--Tinker--+---+------+---------+-----+-----+

팅커 보드 용 Python GPIO 라이브러리 설치

$ wget http://github.com/TinkerBoard/gpio_lib_python/archive/sbc/tinkerboard/python.zip
$ sudo apt-get install python-dev
$ unzip python.zip
$ cd gpio_lib_python-sbc-tinkerboard-python/
$ sudo python setup.py install

py_gpio.c 소스 일부

PyMethodDef asuspi_gpio_methods[] = {
   {"setup", (PyCFunction)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up a GPIO channel or list of channels with a direction and (optional) pull/up down control\nchannel        - either board pin number ,RK number or ASUS number depending on which mode is set.\ndirection      - IN or OUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial]      - Initial value for an output channel"},
   {"cleanup", (PyCFunction)py_cleanup, METH_VARARGS | METH_KEYWORDS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection\n[channel] - individual channel or list/tuple of channels to clean up.  Default - clean every channel that has been used."},
   {"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel or list of channels\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set.\nvalue   - 0/1 or False/True or LOW/HIGH"},
   {"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel.  Returns HIGH=1=True or LOW=0=False\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set."},
   {"setmode", py_setmode, METH_VARARGS, "Set up numbering mode to use for channels.\nBOARD - Use ASUS Pi board numbers\nRK   - Use Broadcom GPIO 00..nn numbers"},
   {"getmode", py_getmode, METH_VARARGS, "Get numbering mode used for channel numbers.\nReturns BOARD, RK, ASUS or UNKNOWN"},
   {"add_event_detect", (PyCFunction)py_add_event_detect, METH_VARARGS | METH_KEYWORDS, "Enable edge detection events for a particular GPIO channel.\nchannel      - either board pin number ,RK number or ASUS number depending on which mode is set.\nedge         - RISING, FALLING or BOTH\n[callback]   - A callback function for the event (optional)\n[bouncetime] - Switch bounce timeout in ms for callback"},
   {"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set."},
   {"event_detected", py_event_detected, METH_VARARGS, "Returns True if an edge has occured on a given GPIO.  You need to enable edge detection using add_event_detect() first.\nchannel - either board pin number ,RK number and ASUS number depending on which mode is set."},
   {"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\nchannel      - either board pin number ,RK number or ASUS number depending on which mode is set.\ncallback     - a callback function"},
   {"wait_for_edge", (PyCFunction)py_wait_for_edge, METH_VARARGS | METH_KEYWORDS, "Wait for an edge.\nchannel      - either board pin number ,RK number or ASUS number depending on which mode is set.\nedge         - RISING, FALLING or BOTH\n[bouncetime] - time allowed between calls to allow for switchbounce"},
   {"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, PWM, SERIAL, I2C, SPI)\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set."},
   {"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
   {"pwmWrite", py_pwmWrite, METH_VARARGS, "Writes the duty cycle to the PWM register for the given GPIO"},
   {"pwmToneWrite", py_pwmToneWrite, METH_VARARGS, "Creates a square wave with given frequency for the given GPIO"},
   {"pwmSetFrequency", py_pwmSetFrequency, METH_VARARGS, "Set up the frequency of PWM clock source."},
   {"pwmSetPeriod", py_pwmSetPeriod, METH_VARARGS, "Writes the period to the PWM register for the given GPIO."},
   {"setGpioDrive", py_setGpioDrive, METH_VARARGS, "Set up the drive strength for the given GPIO."},
   {"getGpioDrive", py_getGpioDrive, METH_VARARGS, "Return the current drive strength."},
   {NULL, NULL, 0, NULL}
};

PWM(서보모터) 제어 파이썬 예제

import ASUS.GPIO as GPIO
import time

GPIO.setmode(GPIO.ASUS)
GPIO.setwarnings(False)

myservo = 239

GPIO.setup(myservo,GPIO.OUT)
pwm = GPIO.PWM(myservo,50) # 50hz yani 20mslik periyod
pwm.start(2.5) # 0 derece

try:
        while True:
                print "0 derece"
                pwm.ChangeDutyCycle(2.5) #0 derece
                time.sleep(1) # wait 1sec
                print "90 derece"
                pwm.ChangeDutyCycle(7.5) #90 derece
                time.sleep(1)
                print "180 derece"
                pwm.ChangeDutyCycle(12.5) #180 derece
                time.sleep(1)
                print "90 derece"
                pwm.ChangeDutyCycle(7.5)
                time.sleep(1)
except KeyboardInterrupt:
        print "Hoscakal canim"
        GPIO.cleanup()

PWM(서보모터) 제어 Java 예제

import com.pi4j.wiringpi.Gpio;

public class ServoTest3 {
	
	private static int PIN_NUMBER = 239;
	
	public static void main(String[] args) throws Exception {
		//
		//GpioFactory.setDefaultProvider(new TinkerBoardGpioProvider());
		
		Gpio.wiringPiSetupGpio();

		Gpio.pinMode(PIN_NUMBER, Gpio.PWM_OUTPUT);
		Gpio.pwmSetMode(Gpio.PWM_MODE_MS);
		// 445 : 200 ~ 1000
		Gpio.pwmSetClock(445); // Gpio.pwmSetClock(400);
		Gpio.pwmSetRange(1024);
		
		int[] arr = {205, 570, 1000};

		while (true) {
			for (int i=0; i≪arr.length; i++) {
				Gpio.pwmWrite(PIN_NUMBER, arr[i]);
				Thread.sleep(300);
			}
		}
	}
}

Tinker Board : Pi Camera 2.1 적용 Python 얼굴인식

OS/Tinker Board 2018.08.24 00:45 Posted by 파란크리스마스

출처

Pi카메라 2.1로 영상을 받을 경우 녹색빛으로 보이는데, 네이버카페에서 aciddust님이 올려주신 white_balance.py 소스를 가지고, 파이썬 예제의 얼굴인식 소스에서 카메라로 받은 이미지를 white_balance 작업 후 진행되도록 수정했습니다. 완벽하게 원하는 수준의 영상을 얻을 수는 없었지만, 이전 보다는 좋은 영상을 얻을 수 있었습니다.

다만 S/W로 보정하다보니 조금 느려진 기분이 들고, USB 카메라보다 화질은 아직 떨어 지고, 전용 카메라가 도착하며 다시 시도 해보겠습니다. 지금은 USB 카메라로 하는것이 좋은 결과를 얻을 수 있습니다.

소스 복사

$ mkdir facedetect
$ cd facedetect
$ cp /usr/local/share/OpenCV/samples/python/facedetect.py .
$ cp /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml .
$ cp /usr/local/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml .

facedetect.py 소스

white_balance 참조

# bluexmas
import white_balance as wb

카메라로 받은 이미지 정보를 white_balance 적용

        # bluexmas
        img = wb.retinex_adjust(img)
        img = wb.gray_world(img)
        img = wb.gimp(img,0.05)

facedetect.py 전체 소스

#!/usr/bin/env python

'''
face detection using haar cascades

USAGE:
    facedetect.py [--cascade ] [--nested-cascade ] []
'''

# Python 2/3 compatibility
from __future__ import print_function

import numpy as np
import cv2

# local modules
from video import create_capture
from common import clock, draw_str

# bluexmas
import white_balance as wb


def detect(img, cascade):
    rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30),
                                     flags=cv2.CASCADE_SCALE_IMAGE)
    if len(rects) == 0:
        return []
    rects[:,2:] += rects[:,:2]
    return rects

def draw_rects(img, rects, color):
    for x1, y1, x2, y2 in rects:
        cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)

if __name__ == '__main__':
    import sys, getopt
    print(__doc__)

    args, video_src = getopt.getopt(sys.argv[1:], '', ['cascade=', 'nested-cascade='])
    try:
        video_src = video_src[0]
    except:
        video_src = 0
    args = dict(args)
    cascade_fn = args.get('--cascade', "../../data/haarcascades/haarcascade_frontalface_alt.xml")
    nested_fn  = args.get('--nested-cascade', "../../data/haarcascades/haarcascade_eye.xml")

    cascade = cv2.CascadeClassifier(cascade_fn)
    nested = cv2.CascadeClassifier(nested_fn)

    cam = create_capture(video_src, fallback='synth:bg=../data/lena.jpg:noise=0.05')

    while True:
        ret, img = cam.read()
        
        # bluexmas
        img = wb.retinex_adjust(img)
        img = wb.gray_world(img)
        img = wb.gimp(img,0.05)
        
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        gray = cv2.equalizeHist(gray)

        t = clock()
        rects = detect(gray, cascade)
        vis = img.copy()
        draw_rects(vis, rects, (0, 255, 0))
        if not nested.empty():
            for x1, y1, x2, y2 in rects:
                roi = gray[y1:y2, x1:x2]
                vis_roi = vis[y1:y2, x1:x2]
                subrects = detect(roi.copy(), nested)
                draw_rects(vis_roi, subrects, (255, 0, 0))
        dt = clock() - t

        draw_str(vis, (20, 20), 'time: %.1f ms' % (dt*1000))
        
        cv2.imshow('facedetect', vis)

        if cv2.waitKey(5) == 27:
            break
    cv2.destroyAllWindows()

소스 파일

facedetect.tar

실행

$ python3 facedetect.py --cascade haarcascade_frontalface_alt.xml --nested-cascade haarcascade_eye_tree_eyeglasses.xml /dev/video0

실행 결과

Tinker Board : 자바를 이용한 GPIO LED 제어

OS/Tinker Board 2018.08.19 00:59 Posted by 파란크리스마스

출처

Tinker Board S : 자바를 이용한 GPIO LED 제어

저의 경우 자바로 GPIO 제어하는 것이 좋은 점은 서버 구성하기 편하기 때문인데, 라즈베리파이의 경우 pi4j가 잘 되어 있지만, 아직 팅커보드는 pi4j가 지원하지 않아, 다른 라이브러리를 찾아보니 diozero 라이브러리가 gifhub에 있었고, 몇가지 설치 방법이 pi4j 보다 어려움이 있어서 정리 해보았습니다. 

우선 Device I/O library 소스를 다운 받아서 설치하고, GPIO 번호 설정도 pi4j와 달라서 고생을 했는데, GPIO 표에서 GPIO.ASUS를 사용하니 잘 되었습니다.

Tinker Board : GPIO

이미지 출처 : GPIO - Tinker Board Wiki

jdk 설치

$ sudo apt-get install default-jdk

Device I/O library 설치

$ sudo apt-get install mercurial
$ hg clone http://hg.openjdk.java.net/dio/dev
$ cd dev/
$ export PI_TOOLS=/usr
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-armhf
$ export CROSS_TOOL=/usr/bin/
$ make
$ cd ..
$ sudo mv ~/dev /opt/dio
$ sudo chown -R root.root /opt/dio
$ sudo cp -r /opt/dio/build/deviceio/lib/* $JAVA_HOME/jre/lib

diozero 다운로드

Diozero JAR 라이브러리가 압축된 ZIP파일을 Google 드라이브에서 다운로드

diozero 압축해제

$ unzip diozero-distribution-0.11-SNAPSHOT-bin.zip
$ cd diozero-distribution-0.11-SNAPSHOT/

배선

LED+ : 3번핀 (GPIO.ASUS : 252)
LED- : 9번핀 (GND)

TestLEDMain.java

import org.pmw.tinylog.Logger;

import com.diozero.devices.LED;
import com.diozero.util.BoardInfo;
import com.diozero.util.DeviceFactoryHelper;
import com.diozero.util.RuntimeIOException;
import com.diozero.util.SleepUtil;
import com.diozero.util.SystemInfo;

public class TestLEDMain {

	public static void main(String[] args) throws Exception {
		String hardware = "Rockchip (Device Tree)";
		String revision = "0000";
		BoardInfo board_info = SystemInfo.lookupLocalBoardInfo(hardware, revision, null);
		System.out.println(hardware + "/" + revision + ": " + board_info);

		if (args.length < 1) {
			Logger.error("Usage: {} <gpio>", TestLEDMain.class.getName());
			System.exit(1);
		}
		test(board_info, Integer.parseInt(args[0]));
	}
	
	public static void test(BoardInfo board_info, int pin) {
		
		try (LED led = new LED(pin)) {
			Logger.info("On");
			led.on();
			SleepUtil.sleepSeconds(1);
			Logger.info("Off");
			led.off();
			SleepUtil.sleepSeconds(1);
			Logger.info("Toggle");
			led.toggle();
			SleepUtil.sleepSeconds(1);
			Logger.info("Toggle");
			led.toggle();
			SleepUtil.sleepSeconds(1);
			
			Logger.info("Blink 10 times");
			led.blink(0.5f, 0.5f, 10, false);
			
			Logger.info("Done");
		} catch (RuntimeIOException e) {
			Logger.error(e, "Error: {}", e);
		} finally {
			// Required if there are non-daemon threads that will prevent the
			// built-in clean-up routines from running
			DeviceFactoryHelper.getNativeDeviceFactory().close();
		}
	}
}

TestLEDMain 실행

실행시 LED+ 연결된 3번핀의 GPIO.ASUS 번호 252를 인자로 전달

TestLEDMain.java

$ sudo java -cp .:tinylog-1.3.5.jar:commons-math3-3.6.1.jar:dio.jar:pigpioj-java-2.2.jar TestLEDMain 252
Rockchip (Device Tree)/0000: BoardInfo [make=Asus, model=Tinker Board, memory=2048, libraryPath=tinkerboard, adcVRef=1.8]
03:40:41.377 [main] DEBUG com.diozero.util.DeviceFactoryHelper.init - Using native device factory class JdkDeviceIoDeviceFactory
03:40:41.443 [main] INFO TestLEDMain.test - On
03:40:41.482 [main] DEBUG com.diozero.util.LibraryLoader.loadLibrary - Loaded library 'diozero-system-utils' from classpath
03:40:42.485 [main] INFO TestLEDMain.test - Off
03:40:43.486 [main] INFO TestLEDMain.test - Toggle
03:40:44.488 [main] INFO TestLEDMain.test - Toggle
03:40:45.489 [main] INFO TestLEDMain.test - Blink 10 times
03:40:55.495 [main] INFO TestLEDMain.test - Done
03:40:55.495 [main] DEBUG com.diozero.api.DigitalOutputDevice.close - close()
03:40:55.496 [main] DEBUG com.diozero.internal.provider.AbstractDevice.close - close(), key=Native-GPIO-252
03:40:55.497 [main] DEBUG com.diozero.internal.provider.jdkdio11.JdkDeviceIoGpioOutputDevice.closeDevice - closeDevice()
03:40:55.498 [main] DEBUG com.diozero.internal.DeviceStates.closed - closed(Native-GPIO-252)
03:40:55.502 [main] DEBUG com.diozero.internal.provider.AbstractDeviceFactory.close - close()
03:40:55.503 [main] DEBUG com.diozero.internal.DeviceStates.closeAll - closeAll()
03:40:55.531 [DIO-Zero Shutdown Handler] DEBUG com.diozero.util.ShutdownHandlerThread.run - Shutdown handler running
03:40:55.532 [DIO-Zero Shutdown Handler] DEBUG com.diozero.internal.provider.AbstractDeviceFactory.close - close()
03:40:55.533 [DIO-Zero Shutdown Handler] DEBUG com.diozero.internal.DeviceStates.closeAll - closeAll()
03:40:55.533 [DIO-Zero Shutdown Handler] DEBUG com.diozero.util.ShutdownHandlerThread.run - Shutdown handler finished

실행결과

Tinker Board : mjpg-streamer (동영상 스트리밍)

OS/Tinker Board 2018.08.18 22:40 Posted by 파란크리스마스

출처

MJPG streamer 컴파일 관련 라이브러리 설치

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install cmake libjpeg-dev imagemagick libv4l-dev
$ sudo apt-get install subversion libjpeg62-turbo-dev imagemagick

MJPG streamer 소스 다운로드, 컴파일, 설치

$ svn co https://svn.code.sf.net/p/mjpg-streamer/code/
$ cd code/mjpg-streamer
$ make
$ sudo make install
install --mode=755 mjpg_streamer /usr/local/bin
install --mode=644 input_uvc.so output_file.so output_udp.so output_http.so input_testpicture.so input_file.so /usr/local/lib/
install --mode=755 -d /usr/local/www
install --mode=644 -D www/* /usr/local/www

MJPG Streamer 실행

$ cd ~/code/mjpg-streamer
$ ./mjpg_streamer -i "./input_uvc.so -y" -o "./output_http.so -w ./www"
MJPG Streamer Version: svn rev: 3:172
 i: Using V4L2 device.: /dev/video0
 i: Desired Resolution: 640 x 480
 i: Frames Per Second.: 5
 i: Format............: YUV
 i: JPEG Quality......: 80
Adding control for Pan (relative)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Tilt (relative)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Pan Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Tilt Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Pan/tilt Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Focus (absolute)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
mapping control for Pan (relative)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Tilt (relative)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Pan Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Tilt Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Pan/tilt Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Focus (absolute)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for LED1 Mode
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for LED1 Frequency
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Disable video processing
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Raw bits per pixel
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
 o: www-folder-path...: ./www/
 o: HTTP TCP port.....: 8080
 o: username:password.: disabled
 o: commands..........: enabled

확인

Tinker Board : Python + OpenCV

OS/Tinker Board 2018.08.18 22:23 Posted by 파란크리스마스

출처

기존에 설치된 OpenCV 제거

OpenCV 설치 여부 확인 - 설치가 안 된경우

$ pkg-config --modversion opencv
Package opencv was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv' found

OpenCV 설치 여부 확인 - 설치 되어 있는 경우

$  pkg-config --modversion opencv
2.4.9.1

설치되어 있는 OpenCV 삭제

$ sudo apt-get purge libopencv* python-opencv
$ sudo apt-get autoremove

OS 업그레이드

$ sudo apt-get update
$ sudo apt-get upgrade

개발 도구와 관련 패키지 설치

$ sudo apt-get install build-essential cmake pkg-config

이미지(JPEG, PNG, TIFF, 기타 등등...) 처리 관련 패키지 설치

$ sudo apt-get install libjpeg-dev libtiff5-dev

비디오 처리 관련 패키지 설치

$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
$ sudo apt-get install libxvidcore-dev libx264-dev

Video4Linux 패키지 설치

$ sudo apt-get install libv4l-dev v4l-utils

GTK 패키지 설치

$ sudo apt-get install libgtk2.0-dev

OpenCV 관련 패키지 설치

$ sudo apt-get install libatlas-base-dev gfortran libeigen3-dev

Python 설치

$ sudo apt-get install python2.7-dev python3-dev

NumPy 설치

출처 : 예제로 배우는 파이썬 프로그래밍 - numpy 사용하기

$ sudo apt-get install python-numpy python3-numpy

OpenCV 소스 다운로드 및 압축해제

$ cd ~
$ wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.2.0.zip
$ unzip opencv.zip

OpenCV Extra Modules 소스 다운로드 및 압축해제

$ wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.2.0.zip
$ unzip opencv_contrib.zip

cmake

$ cd ~/opencv-3.2.0/
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D WITH_TBB=OFF \
-D WITH_IPP=OFF \
-D WITH_1394=OFF \
-D BUILD_WITH_DEBUG_INFO=OFF \
-D BUILD_DOCS=OFF \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D BUILD_EXAMPLES=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D ENABLE_NEON=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.2.0/modules \
-D WITH_V4L=ON  \
-D WITH_LIBV4L=ON  \
-D WITH_FFMPEG=ON \
-D WITH_XINE=ON \
-D BUILD_NEW_PYTHON_SUPPORT=ON \
../
 
-- General configuration for OpenCV 3.2.0 =====================================
--   Version control:               unknown
-- 
--   Extra modules:
--     Location (extra):            /home/linaro/opencv_contrib-3.2.0/modules
--     Version control (extra):     unknown
-- 
--   Platform:
--     Timestamp:                   2018-08-17T16:45:11Z
--     Host:                        Linux 4.4.103+ armv7l
--     CMake:                       3.7.2
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               RELEASE
-- 
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ Compiler:                /usr/bin/c++  (ver 6.3.0)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -mfp16-format=ieee -mfpu=neon -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -mfp16-format=ieee -mfpu=neon -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /usr/bin/cc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -mfp16-format=ieee -mfpu=neon -ffunction-sections -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -fdiagnostics-show-option -pthread -fomit-frame-pointer -mfp16-format=ieee -mfpu=neon -ffunction-sections -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):
--     Linker flags (Debug):
--     ccache:                      NO
--     Precompiled headers:         YES
--     Extra dependencies:          /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/arm-linux-gnueabihf/libpng.so /usr/lib/arm-linux-gnueabihf/libz.so /usr/lib/arm-linux-gnueabihf/libtiff.so gtk-x11-2.0 gdk-x11-2.0 pangocairo-1.0 atk-1.0 cairo gdk_pixbuf-2.0 gio-2.0 pangoft2-1.0 pango-1.0 gobject-2.0 glib-2.0 fontconfig freetype gthread-2.0 v4l1 v4l2 avcodec avformat avutil swscale dl m pthread rt
--     3rdparty dependencies:       libwebp libjasper IlmImf libprotobuf tegra_hal
-- 
--   OpenCV modules:
--     To be built:                 core flann imgproc ml photo reg surface_matching video dnn freetype fuzzy imgcodecs shape videoio highgui objdetect plot superres xobjdetect xphoto bgsegm bioinspired dpm face features2d line_descriptor saliency text calib3d ccalib datasets rgbd stereo tracking videostab xfeatures2d ximgproc aruco optflow phase_unwrapping stitching structured_light python2 python3
--     Disabled:                    world contrib_world
--     Disabled by dependency:      -
--     Unavailable:                 cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java ts viz cnn_3dobj cvv hdf matlab sfm
-- 
--   GUI: 
--     QT:                          NO
--     GTK+ 2.x:                    YES (ver 2.24.31)
--     GThread :                    YES (ver 2.50.3)
--     GtkGlExt:                    NO
--     OpenGL support:              NO
--     VTK support:                 NO
-- 
--   Media I/O: 
--     ZLib:                        /usr/lib/arm-linux-gnueabihf/libz.so (ver 1.2.8)
--     JPEG:                        /usr/lib/arm-linux-gnueabihf/libjpeg.so (ver )
--     WEBP:                        build (ver 0.3.1)
--     PNG:                         /usr/lib/arm-linux-gnueabihf/libpng.so (ver 1.6.28)
--     TIFF:                        /usr/lib/arm-linux-gnueabihf/libtiff.so (ver 42 - 4.0.8)
--     JPEG 2000:                   build (ver 1.900.1)
--     OpenEXR:                     build (ver 1.7.1)
--     GDAL:                        NO
--     GDCM:                        NO
-- 
--   Video I/O:
--     DC1394 1.x:                  NO
--     DC1394 2.x:                  NO
--     FFMPEG:                      YES
--       avcodec:                   YES (ver 57.64.101)
--       avformat:                  YES (ver 57.56.101)
--       avutil:                    YES (ver 55.34.101)
--       swscale:                   YES (ver 4.2.100)
--       avresample:                NO
--     GStreamer:                   NO
--     OpenNI:                      NO
--     OpenNI PrimeSensor Modules:  NO
--     OpenNI2:                     NO
--     PvAPI:                       NO
--     GigEVisionSDK:               NO
--     Aravis SDK:                  NO
--     UniCap:                      NO
--     UniCap ucil:                 NO
--     V4L/V4L2:                    Using libv4l1 (ver 1.12.3) / libv4l2 (ver 1.12.3)
--     XIMEA:                       NO
--     Xine:                        NO
--     gPhoto2:                     NO
-- 
--   Parallel framework:            pthreads
-- 
--   Other third-party libraries:
--     Use IPP:                     NO
--     Use VA:                      NO
--     Use Intel VA-API/OpenCL:     NO
--     Use Lapack:                  NO
--     Use Eigen:                   NO
--     Use Cuda:                    NO
--     Use OpenCL:                  YES
--     Use OpenVX:                  NO
--     Use custom HAL:              YES (carotene (ver 0.0.1))
-- 
--   OpenCL:                        <Dynamic loading of OpenCL library>
--     Include path:                /home/linaro/opencv-3.2.0/3rdparty/include/opencl/1.2
--     Use AMDFFT:                  NO
--     Use AMDBLAS:                 NO
-- 
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.13)
--     Libraries:                   /usr/lib/arm-linux-gnueabihf/libpython2.7.so (ver 2.7.13)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.12.1)
--     packages path:               lib/python2.7/dist-packages
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.5.3)
--     Libraries:                   /usr/lib/arm-linux-gnueabihf/libpython3.5m.so (ver 3.5.3)
--     numpy:                       /usr/lib/python3/dist-packages/numpy/core/include (ver 1.12.1)
--     packages path:               lib/python3.5/dist-packages
-- 
--   Python (for build):            /usr/bin/python2.7
-- 
--   Java:
--     ant:                         NO
--     JNI:                         NO
--     Java wrappers:               NO
--     Java tests:                  NO
-- 
--   Matlab:                        Matlab not found or implicitly disabled
-- 
--   Tests and samples:
--     Tests:                       NO
--     Performance tests:           NO
--     C/C++ Examples:              NO
-- 
--   Install path:                  /usr/local
-- 
--   cvconfig.h is in:              /home/linaro/opencv-3.2.0/build
-- -----------------------------------------------------------------
-- 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/linaro/opencv-3.2.0/build

빌드 (4 개의 코어가 있으므로 OpenCV를 더 빠르게 컴파일 할 수 있도록 -j4 옵션추가)

$ cat /proc/cpuinfo | grep processor | wc -l
4
$ make -j4

OpenCV 설치

$ sudo make install

/etc/ld.so.conf.d/ 디렉토리에 /usr/local/lib를 포함하는 설정파일이 있는지 확인

$ cat /etc/ld.so.conf.d/*
## Multiarch support
/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabihf
## libc default configuration
/usr/local/lib

OpenCV 설치

$ sudo ldconfig

OpenCV 설치 확인 - 1

$ pkg-config --modversion opencv
3.2.0

OpenCV 설치 확인 - 2

$ pkg-config --libs --cflags opencv
-I/usr/local/include/opencv -I/usr/local/include -L/usr/local/lib -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dpm -lopencv_freetype -lopencv_fuzzy -lopencv_line_descriptor -lopencv_optflow -lopencv_reg -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_rgbd -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_face -lopencv_plot -lopencv_dnn -lopencv_xfeatures2d -lopencv_shape -lopencv_video -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_xobjdetect -lopencv_objdetect -lopencv_ml -lopencv_xphoto -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_photo -lopencv_imgproc -lopencv_core

용량 확보를 위해서 다운로드 받은 소스 파일 삭제

$ cd ~
$ rm -rf opencv-3.2.0 opencv_contrib-3.2.0

얼굴인식 예제 컴파일, 실행

$ cp /usr/local/share/OpenCV/samples/cpp/facedetect.cpp ./
$ g++ -o facedetect facedetect.cpp $(pkg-config --libs --cflags opencv) 
$ ./facedetect --cascade="/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade="/usr/local/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml " --scale=1.3

얼굴인식 예제 실행 결과

python3에서 OpenCV 버전확인

$ python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.2.0'

python3에서 얼굴인식 예제 실행

$ python3 /usr/local/share/OpenCV/samples/python/facedetect.py --cascade "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade "/usr/local/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml" /dev/video0