Search

'Tinker Board S'에 해당되는 글 3건

  1. 2018.09.16 Tinker Board : Smart-Mirror 설치 (1)
  2. 2018.09.08 Tinker Board : pi4j
  3. 2018.08.18 Tinker Board : 개봉기, OS 설치

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 : 개봉기, OS 설치

OS/Tinker Board 2018.08.18 17:06 Posted by 파란크리스마스

출처

개봉기

스펙

ModelTinker BoardTinker Board S
Release DateApril 2017January 2018
SoCRockchip RK3288
ArchitectureARMv7-A(32-bit)
CPUQuad core 1.8 GHz ARM Cortex-A17 (up to 2.6GHZ turbo clock speed) (32-bit)
GPU600 MHz Mali-T760 MP4 GPU
RAM2GB dual channel LPDDR3
Storageremovable MicroSD slot ( supporting SD 3.0 )16GB eMMC + removable MicroSD slot ( supporting SD 3.0 )
Video outputfull size HDMI 1.4, MIPI-DSI (compatible with the Raspberry Pi 7" display and others)full size HDMI 1.4 (CEC support added), MIPI-DSI(compatible with the Raspberry Pi 7" display and others)
Video inputMIPI-CSI camera
AudioRTL ALC4040 HD CODEC, Play: 24bit/192kHz, Record: 24bit/96kHz

3.5 mm audio jack ( supporting line out and microphone in )

RTL ALC4040 HD CODEC, Play: 24bit/192kHz, Record: 24bit/96kHz

3.5 mm audio jack ( supporting line out and microphone in, Plug-in Detection and Auto-Switch )

Other IO40-pin header with:
  • up to 28 x GPIO pins
  • up to 2 x SPI bus
  • up to 2 x I2C bus
  • up to 4 x UART
  • up to 2 x PWM
  • up to 1 x PCM/I2S
  • 2 x 5V power pins
  • 2 x 3.3V power pins
  • 8 x ground pins

1 x 2-pin contact pin :

  • 1 x PWM
  • 1 x S/PDIF
40-pin header with:
  • up to 28 x GPIO pins
  • up to 2 x SPI bus
  • up to 2 x I2C bus
  • up to 4 x UART
  • up to 2 x PWM
  • up to 1 x PCM/I2S (Enhanced I2S pin with Slave mode)
  • 2 x 5V power pins
  • 2 x 3.3V power pins
  • 8 x ground pins

1 x 2-pin contact pin :

  • 1 x PWM
  • 1 x S/PDIF

1 x 2-pin Power-on Header

USB4 x USB 2.0 ports
NetworkingGigabit LAN ( not shared with USB bus )
WirelessBluetooth V4.0 + EDR, 802.11 b/g/n Wi-Fi, with IPEX antenna header
PowerMicro-USB; due to Micro-USB power delivery limitations, powering over GPIO is suggested [2][3]
Form Factor3.37 inch x 2.125 inch ( 8.55 cm x 5.4 cm )
Weight55g
Operating SystemsTinkerOS is a Debian Linux derivative & Android 6

OS 이미지 SD메모리에 복사

SD 메모리로 부팅

제가 구입한 Tinker Board S의 경우 eMMC에 안드로이드 OS가 설치되어 있어 리눅스 OS 이미지가 복사된 SD 메모리를 삽입하고, 부팅해도 안드로이드로 부팅이 되는데, 아래 이미지 처럼 Maskrom mode로 설정후 부팅하면 SD메모리에 설치된 OS로 부팅이 됩니다.

라즈베리파이 7인치 모니터 적용 (MIPI-DSI)