NanoPi NEO2-LTS NAS

OS/NanoPi 2018.08.30 23:22 Posted by 파란크리스마스

출처

Debian8 Jessie for NanoPi NEO2 설치

nanopi-neo2_debian-nas-jessie_4.14.0_20171208.img.zip 파일 이미지 복원

NAS에 접속

브라우져에서 FriendlyELEC 호스트 이름으로 접속

사용자이름 : admin
암호 : openmediavault

HDD Format

[저장소 - 파일시스템] 왼쪽 메뉴에서 선택하고, Format 할 파일 시스템을 목록에서 선택한 다음, [삭제] 버튼 선택

삭제 확인 메시지 [예] 버튼 선택

[생성] 버튼 선택해서 삭제한 파일 시스템을 추가

[장치] 에서 HDD를 선택하고, 파일 시스템은 [EXT4]로 선택하고, [예] 버튼 선택

추가된 파일 시스템 확인

Swift4 tip

Programming/Swift 2018.08.27 10:14 Posted by 파란크리스마스

출처

Dictionary to JSON

출처 : Convert Dictionary to JSON in Swift - Stack Overflow

        let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
        let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String
        print(jsonString)

화면전환, 파라미터 전달

출처 : Swift 화면 전환 기법: 뷰 컨트롤러, 내비게이션 컨트롤러, 세그웨이 : 네이버 블로그

    func native_video_recording(_ data : NSDictionary) { 
        let vcRecord = self.storyboard!.instantiateViewController(withIdentifier: "vcRecord") as! RecordController // 1
        vcRecord.setParamData(data) // 파라미터 전달
        vcRecord.modalTransitionStyle = UIModalTransitionStyle.crossDissolve // 2
        self.present(vcRecord, animated: true) // 3
    }

카메라 리소스 구하기

출처 : GitHub - parthibanios/custom-Video-Recording-Swift-3.0: Record video using AVCapture AVFoundation framework

    //MARK:- Setup Camera
    func setupSession() -> Bool {
        
        //captureSession.sessionPreset = AVCaptureSessionPresetHigh
        //1080
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        
        // Setup Camera
        let camera = AVCaptureDevice.default(for: .video)
        do {
            let input = try AVCaptureDeviceInput(device: camera!)
            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
                activeInput = input
            }
        } catch {
            print("Error setting device video input: \(error)")
            return false
        }
        
        // Setup Microphone
        let microphone = AVCaptureDevice.default(for: .audio)
        do {
            let micInput = try AVCaptureDeviceInput(device: microphone!)
            if captureSession.canAddInput(micInput) {
                captureSession.addInput(micInput)//addInput(micInput)
            }
        } catch {
            print("Error setting device audio input: \(error)")
            return false
        }
        movieOutput.maxRecordedDuration = CMTimeMake(9, 1)
        
        // Movie output
        if captureSession.canAddOutput(movieOutput) {
            captureSession.addOutput(movieOutput)
        }
        
        return true
    }

도큐먼트 디렉토리 구하기 - UIFileSharingEnabled 설정의 Root 경로

출처 : Swift로 파일 다루기 :

Eth Developer's Lab

    //EDIT 1: I FORGOT THIS AT FIRST
    func getMp4PathURL() -> URL? {
        /*
        let directory = NSTemporaryDirectory() as NSString
        
        if directory != "" {
            let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
            return URL(fileURLWithPath: path)
        }
        return nil
        */
        
        // 도큐먼트 디렉토리 구하기 - UIFileSharingEnabled의 Root 경로
        guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil }
        let fileName = NSUUID().uuidString + ".mp4"
        let fileURL = documentsDirectory.appendingPathComponent(fileName)
        
        /*
        print(imageURL)
        do {
            let imageData = try Data(contentsOf: imageURL)
            return UIImage(data: imageData)
        } catch let err as NSError {
            print("이미지 로딩 에러 : \(err)")
        }
        */
        
        return fileURL
    }

Swift4 : Alamofire 프로젝트에 추가하기

출처 : [iOS / Swift4] Alamofire 사용하기 | ry4nkim

Podfile 파일 편집

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'project' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  project 'project.xcodeproj'

  # Pods for project
  pod 'Firebase/Core'
  pod 'Firebase/Messaging'
  pod 'Alamofire', '~> 4.7'

end

pod install

$ pod install
Analyzing dependencies
Downloading dependencies
Installing Alamofire (4.7.3)
Installing Firebase 5.4.0
Installing FirebaseAnalytics (5.0.1)
Using FirebaseCore (5.0.5)
Using FirebaseInstanceID (3.1.1)
Using FirebaseMessaging (3.0.3)
Using GoogleToolboxForMac (2.1.4)
Using Protobuf (3.6.0)
Installing nanopb (0.3.8)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 9 total pods installed.
 
[!] Automatically assigning platform `ios` with version `9.3` on target `project` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.

Alamofire 파일 업로드, 결과 JSON 파싱

출력 : swift3 - upload image to server using Alamofire - Stack Overflow, ios - How to parse JSON response from Alamofire API in Swift? - Stack Overflow

        Alamofire.upload(multipartFormData: { (multipartFormData) in
            /*
            for (key, value) in parameters {
                multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
            }
            */
            multipartFormData.append("\(jsonString)".data(using: String.Encoding.utf8)!, withName: "json_str")
            
            /*
            if let data = imageData{
                multipartFormData.append(data, withName: "image", fileName: "image.png", mimeType: "image/png")
            }
            */
            multipartFormData.append(mp4FileUrl, withName: "test.mp4")
            
        }, usingThreshold: UInt64.init(), to: self.upload_url, method: .post, headers: headers) { (result) in
            switch result{
            case .success(let upload, _, _):
                upload.responseJSON { response in
                    print("Succesfully uploaded")
                    if let err = response.error {
                        print(err)
                        onCompletion?(nil, err)
                        return
                    }
                    if let result = response.result.value {
                        let JSON = result as! NSDictionary
                        print(JSON)
                        onCompletion?(JSON, nil)
                    }
                }
            case .failure(let error):
                print("Error in upload: \(error.localizedDescription)")
                onCompletion?(nil, error)
            }
        }

Timer, String format

출처 : ios - Swift - Update/Refresh Label that Displays Time - Stack Overflow

    let movieOutput = AVCaptureMovieFileOutput()
    var durationTimer: Timer?

    //MARK:- Setup Camera
    func setupSession() -> Bool {
        
        //captureSession.sessionPreset = AVCaptureSessionPresetHigh
        //1080
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        
        // Setup Camera
        // 생략
        // Setup Microphone
        // 생략
 
        // 녹화 시간 제한
        movieOutput.maxRecordedDuration = CMTimeMake(300, 1)
        
        return true
    }

    @IBAction func startRecording() {

        if movieOutput.isRecording == false {
        
// ... 생략 ...
            
            self.seconds = 0
            self.durationTimer = Timer(timeInterval: 1.0, target: self, selector: #selector(self.refreshDurationLabel), userInfo: nil, repeats: true)
            RunLoop.current.add(self.durationTimer!, forMode: RunLoopMode.commonModes)
            self.durationTimer?.fire()
        } else {
            self.durationTimer?.invalidate()
            self.durationTimer = nil
            self.seconds = 0
            //self.durationTxt.text = secondsToFormatTimeFull(second: 0)
            stopRecording()
        }
    }

    func secondsToFormatTimeFull(second: Int)->String {
        let sec : Int = second % 60
        let min : Int = second / 60
        return String(format : "%02d:%02d", min, sec)
    }

    @objc func refreshDurationLabel() {
        self.durationTxt.text = secondsToFormatTimeFull(second: self.seconds)
        seconds = seconds + 1
    }

연락처 조회, 선택, WebView 자바스크립트 호출(evaluateJavaScript)

출처 : ContactsUISample/ViewController.swift at master · koogawa/ContactsUISample · GitHub
[SWIFT] 주소록에 저장된 데이터 불러오기 - Things take time - 티스토리

import Contacts
import ContactsUI

class WebViewBase : UIViewController, CNContactPickerDelegate {

    func native_show_contacts() {
        let pickerViewController = CNContactPickerViewController()
        pickerViewController.delegate = self
        
        // Display only a person's phone, email, and postal address
        let displayedItems = [CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey]
        pickerViewController.displayedPropertyKeys = displayedItems
        
        // Show the picker
        self.present(pickerViewController, animated: true, completion: nil)
    }

    // MARK: CNContactPickerDelegate methods
    // Called when a property of the contact has been selected by the user.
    func contactPicker(picker: CNContactPickerViewController, didSelectContactProperty contactProperty: CNContactProperty) {
        //
    }
    
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        // You can fetch selected name and number in the following way
        
        // user name
        let userName:String = contact.givenName
        
        let name = contact.familyName + contact.givenName
        //print(name)
        
        var primaryPhoneNumberStr:String = ""
        
        if (!contact.phoneNumbers.isEmpty) {
            // user phone number
            let userPhoneNumbers:[CNLabeledValue<cnphonenumber>] = contact.phoneNumbers
            let firstPhoneNumber:CNPhoneNumber = userPhoneNumbers[0].value
            
            
            // user phone number string
            primaryPhoneNumberStr = firstPhoneNumber.stringValue
        }
        
        //print("phonenum = \(primaryPhoneNumberStr)")
        
        webView.evaluateJavaScript("setContract('\(name)', '\(primaryPhoneNumberStr)')")
    }
    
    // Called when the user taps Cancel.
    func contactPickerDidCancel(picker: CNContactPickerViewController) {
        //
    }
}

jni

Programming/Java 2018.08.25 23:07 Posted by 파란크리스마스

출처

py_pwm.h

typedef struct
{
    //PyObject_HEAD
    unsigned int gpio;
    float freq;
    float dutycycle;
} PWMObject;

int PWM_init(PWMObject *self, int channel, float frequency);
void PWM_start(PWMObject *self, float dutycycle);
int PWM_ChangeDutyCycle(PWMObject *self, float dutycycle);

PWMObject.java

package com.pi4j.wiringpi;

public class PWMObject {

	public int gpio;
	public float freq;
	public float dutycycle;

	public PWMObject() {

	}

	public int getGpio() {
		return gpio;
	}

	public void setGpio(int gpio) {
		this.gpio = gpio;
	}

	public float getFreq() {
		return freq;
	}

	public void setFreq(float freq) {
		this.freq = freq;
	}

	public float getDutycycle() {
		return dutycycle;
	}

	public void setDutycycle(float dutycycle) {
		this.dutycycle = dutycycle;
	}

}

com_pi4j_wiringpi_ASUSGpio.h

#include <jni.h>
/* Header for class com_pi4j_wiringpi_ASUSGpio */

#ifndef _Included_com_pi4j_wiringpi_ASUSGpio
#define _Included_com_pi4j_wiringpi_ASUSGpio
#ifdef __cplusplus
extern "C" {
#endif

#undef com_pi4j_wiringpi_ASUSGpio_ASUS
#define com_pi4j_wiringpi_ASUSGpio_ASUS 13L
#undef com_pi4j_wiringpi_ASUSGpio_OUTPUT
#define com_pi4j_wiringpi_ASUSGpio_OUTPUT 1L

JNIEXPORT jint JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pySetmode
  (JNIEnv *, jclass, jint);

JNIEXPORT jint JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pySetupChannel
  (JNIEnv *, jclass, jint, jint);

JNIEXPORT jobject JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pwmInit
  (JNIEnv *, jclass, jint, jfloat);

JNIEXPORT void JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pwmStart
  (JNIEnv *, jclass, jobject, jfloat);

JNIEXPORT jint JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pwmChangeDutyCycle
  (JNIEnv *, jclass, jobject, jfloat);

#ifdef __cplusplus
}
#endif
#endif

com_pi4j_wiringpi_ASUSGpio.c

#include <stdio.h>
#include <jni.h>
#include <wiringPi.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>
#include "com_pi4j_wiringpi_ASUSGpio.h"

void setPwmObject(JNIEnv *env, jclass targetClass, jobject newObject, PWMObject pwm) {
	
	jfieldID fid;
	
	// JniObject 객체의 intField 필드값 설정
	fid = (*env)->GetFieldID(env, targetClass, "gpio", "I");
	(*env)->SetIntField(env, newObject, fid, pwm.gpio);
	
	// JniObject 객체의 intField 필드값 설정
	fid = (*env)->GetFieldID(env, targetClass, "freq", "F");
	(*env)->SetFloatField(env, newObject, fid, pwm.freq);
	
	// JniObject 객체의 intField 필드값 설정
	fid = (*env)->GetFieldID(env, targetClass, "dutycycle", "F");
	(*env)->SetFloatField(env, newObject, fid, pwm.dutycycle);
}

void getPwmObject(JNIEnv *env, jclass targetClass, jobject newObject, PWMObject *pwm) {
	
	jfieldID fid;
	
	// JniObject 객체의 intField 필드값 설정
	fid = (*env)->GetFieldID(env, targetClass, "gpio", "I");
	pwm->gpio = (*env)->GetIntField(env, newObject, fid);
	
	// JniObject 객체의 intField 필드값 설정
	fid = (*env)->GetFieldID(env, targetClass, "freq", "F");
	pwm->freq = (*env)->GetFloatField(env, newObject, fid);
	
	// JniObject 객체의 intField 필드값 설정
	fid = (*env)->GetFieldID(env, targetClass, "dutycycle", "F");
	pwm->dutycycle = (*env)->GetFloatField(env, newObject, fid);
}

JNIEXPORT jint JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pySetmode
(JNIEnv *env, jclass obj, jint new_mode)
{
	return py_setmode(new_mode);
}

JNIEXPORT jint JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pySetupChannel
(JNIEnv *env, jclass obj, jint channel, jint direction)
{
	return py_setup_channel(channel, direction);
}

JNIEXPORT jobject JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pwmInit
(JNIEnv *env, jclass obj, jint channel, jfloat frequency)
{
	//pwm = GPIO.PWM(myservo,50) # 50hz yani 20mslik periyod
	PWMObject pwm;
	PWM_init(&pwm, channel, frequency);
	//printf("pwm.gpio = %d\n", pwm.gpio);
	
	//
	jclass targetClass = (*env)->FindClass(env, "com/pi4j/wiringpi/PWMObject");
	
	// 생성자 찾기
	jmethodID mid = (*env)->GetMethodID(env, targetClass, "<init>", "()V");

	// 객체 생성(객체 레퍼런스 반환)
	jobject newObject = (*env)->NewObject(env, targetClass, mid, "()V");
	
	setPwmObject(env, targetClass, newObject, pwm);
	
	return newObject;
}

JNIEXPORT void JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pwmStart
(JNIEnv *env, jclass obj, jobject thiz, jfloat dutycycle)
{
	PWMObject pwm;
	
	//
	jclass targetClass = (*env)->FindClass(env, "com/pi4j/wiringpi/PWMObject");
	getPwmObject(env, targetClass, thiz, &pwm);
	
	PWM_start(&pwm, dutycycle);
	setPwmObject(env, targetClass, thiz, pwm);
}

JNIEXPORT jint JNICALL Java_com_pi4j_wiringpi_ASUSGpio_pwmChangeDutyCycle
(JNIEnv *env, jclass obj, jobject thiz, jfloat dutycycle)
{
	PWMObject pwm;
	
	//
	jclass targetClass = (*env)->FindClass(env, "com/pi4j/wiringpi/PWMObject");
	getPwmObject(env, targetClass, thiz, &pwm);
	
	int result = PWM_ChangeDutyCycle(&pwm, dutycycle);
	setPwmObject(env, targetClass, thiz, pwm);
	
	return result;
}

ASUSGpio.java

package com.pi4j.wiringpi;

import com.pi4j.util.NativeLibraryLoader;

public class ASUSGpio {

  // private constructor
  private ASUSGpio()  {
    // forbid object construction
  }

  public static final int ASUS = 13;

  public static final int OUTPUT = 1;

  static {
    // Load the platform library
    NativeLibraryLoader.load("libpi4j.so");
  }

  public static native int pySetmode(int new_mode);

  public static native int pySetupChannel(int channel, int direction);

  public static native PWMObject pwmInit(int channel, float frequency);

  public static native void pwmStart(PWMObject self, float dutycycle);

  public static native int pwmChangeDutyCycle(PWMObject self, float dutycycle);
}

빌드

$ export SimulatedPlatform="TinkerBoard GPIO Provider"
$ mvn clean install

-----------------

hml-equation-parser 패키지를 설치

$ sudo apt-get install pandoc
$ sudo pip3 install typing
$ sudo pip3 install hml_equation_parser

jpserve 패키지를 설치

$ sudo pip install jpserve

jython 설치

$ java -jar jython-installer-2.7.0.jar

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

실행 결과

Linux에 Maven 설치하기

OS/Linux 2018.08.19 11:51 Posted by 파란크리스마스

출처

설치 : 다운로드, 압축해제, 디렉토리이동

$ wget http://mirror.apache-kr.org/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
$ tar xvf apache-maven-3.5.4-bin.tar.gz
$ sudo mv apache-maven-3.5.4 /opt/
$ sudo ln -s /opt/apache-maven-3.5.4/ /opt/maven

환경설정 : /etc/profile 내용 추가

$ sudo vi /etc/profile

내용추가

export M2_HOME=/opt/maven
export PATH=$PATH:$M2_HOME/bin

profile 실행

$ source /etc/profile

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

Tinker Board : MIPI-CSI Camera 문제점 정리

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

출처

MIPI-CSI Camera

Tinker Board에서 카메라를 사용하기 위해서 라즈베리파이에서 사용했던 카메라를 MIPI-CSI 연결해서 테스트 해보았지만, 좋은 결과를 얻지 못했습니다. 제가 가지고 있는 카메라 모듈의 문제가 있을 수 있으니 참고 만 하세요.

Raspberry Pi Camera Module V1.3 - 5 Megapixel

첫 번째 테스트 해본 카메라는 Raspberry Pi Zero - Version 1.3인데, camstill.sh 명령으로 카메라 캡쳐 이미지를 얻을 때 인식률이 제일 떨어 집니다. 1초에 나올 때도 있고, 5초정도 걸릴 때도 있고, 실패할 때도 많이 발생합니다.

OV5647 Sensor Fisheye Wide-angle Camera Module for Raspberry Pi

이 카메라 역쉬 인식률이 많이 떨어 집니다. 이전 [Raspberry Pi Camera Module V1.3 - 5 Megapixel]보다 인식률은 조금 좋아 졌지만, 렌즈도 광각 렌즈라서 OpenCV에 사용하기 힘들었습니다.

Raspberry Pi Camera Module V2 - 8 Megapixel

카메라의 인식률은 정말 좋습니다. 문제는 캡쳐된 이미지가 너무 어두운게 문제입니다. 관련 내용도 여기에서 확인 해볼 수 있습니다. (Tinker Board Forum - Raspi camera v2 (IMX219) preview is dark green)

카메라 관련 드라이버 메시지 ( dmesg )

$ dmesg | grep cam
[    6.200955] of_get_named_gpiod_flags: parsed 'rockchip,pd-gpio' property of node '/i2c@ff660000/camera-module@36[0]' - status (0)
[    6.200982] of_get_named_gpiod_flags: can't parse 'rockchip,pwr-gpio' property of node '/i2c@ff660000/camera-module@36[0]'
[    6.201003] of_get_named_gpiod_flags: can't parse 'rockchip,flash-gpio' property of node '/i2c@ff660000/camera-module@36[0]'
[    6.201023] of_get_named_gpiod_flags: can't parse 'rockchip,torch-gpio' property of node '/i2c@ff660000/camera-module@36[0]'
[    6.201043] of_get_named_gpiod_flags: can't parse 'rockchip,rst-gpio' property of node '/i2c@ff660000/camera-module@36[0]'
[    6.226655] ov7750.ov_camera_module_write_config(182) ERR: no active sensor configuration
[    6.227024] ov7750.ov_camera_module_write_config(233) ERR: failed with error -14
[    6.227613] ov7750.pltfrm_camera_module_read_reg(996) ERR: i2c read from offset 0x0000300a failed with error -6
[    6.228227] ov7750.pltfrm_camera_module_read_reg(996) ERR: i2c read from offset 0x0000300b failed with error -6
[    6.228662] ov7750.ov7750_check_camera_id(571) ERR: register read failed, camera module powered off?
[    6.229053] ov7750.ov7750_check_camera_id(589) ERR: failed with error (-6)
[    6.229403] ov7750.ov_camera_module_attach(256) ERR: failed with error -6
[    6.231249] of_get_named_gpiod_flags: parsed 'rockchip,pd-gpio' property of node '/i2c@ff660000/camera-module@10[0]' - status (0)
[    6.231276] of_get_named_gpiod_flags: can't parse 'rockchip,pwr-gpio' property of node '/i2c@ff660000/camera-module@10[0]'
[    6.231298] of_get_named_gpiod_flags: can't parse 'rockchip,flash-gpio' property of node '/i2c@ff660000/camera-module@10[0]'
[    6.231318] of_get_named_gpiod_flags: can't parse 'rockchip,torch-gpio' property of node '/i2c@ff660000/camera-module@10[0]'
[    6.231337] of_get_named_gpiod_flags: can't parse 'rockchip,rst-gpio' property of node '/i2c@ff660000/camera-module@10[0]'

video4linux 정보

$ v4l2-ctl -V
Format Video Capture:
        Width/Height      : 1920/1080
        Pixel Format      : 'NV12'
        Field             : Any
        Bytes per Line    : 0
        Size Image        : 0
        Colorspace        : Default
        Transfer Function : Default
        YCbCr/HSV Encoding: Default
        Quantization      : Default
        Flags             : 

Tinker Board : 기본설정, eMMC에 OS 설치

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

출처

OS 업데이트

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

IP 확인

$ ip addr | grep "inet "
    inet 127.0.0.1/8 scope host lo
    inet 192.168.137.223/24 brd 192.168.137.255 scope global dynamic eth0
    inet 192.168.0.115/24 brd 192.168.0.255 scope global wlan0

SD 확장

SD 확장전 용량확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.3G  4.4G  2.5G  64% /
devtmpfs        943M     0  943M   0% /dev
tmpfs          1007M     0 1007M   0% /dev/shm
tmpfs          1007M   17M  990M   2% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs          1007M     0 1007M   0% /sys/fs/cgroup
/dev/mmcblk0p1   63M  7.5M   56M  12% /boot
tmpfs           202M   12K  202M   1% /run/user/1000

SD FDisk

$ sudo fdisk /dev/mmcblk0

Welcome to fdisk (util-linux 2.29.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/mmcblk0: 29.8 GiB, 32010928128 bytes, 62521344 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x58bc1052

Device         Boot  Start      End  Sectors  Size Id Type
/dev/mmcblk0p1        8192   139263   131072   64M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      139264 15630335 15491072  7.4G 83 Linux

Command (m for help): d
Partition number (1,2, default 2): 2

Partition 2 has been deleted.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (2048-62521343, default 2048): 139264
Last sector, +sectors or +size{K,M,G,T,P} (139264-62521343, default 62521343): 

Created a new partition 2 of type 'Linux' and of size 29.8 GiB.
Partition #2 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: Y 

The signature will be removed by a write command.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Device or resource busy

The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).

linaro@tinkerboard:~$ sudo shutdown -r now

SD 확장

$ sudo resize2fs /dev/mmcblk0p2
resize2fs 1.43.4 (31-Jan-2017)
Filesystem at /dev/mmcblk0p2 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/mmcblk0p2 is now 7797760 (4k) blocks long.

SD 확장 확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        30G  4.4G   24G  16% /
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/mmcblk0p1   63M  7.5M   56M  12% /boot
tmpfs           202M  8.0K  202M   1% /run/user/1000

How to burn Linux image to eMMC

출처 : How to burn Linux image to eMMC
bpi-copy command

eMMC 용량 확인

$ sudo fdisk -l

... 생략 ...

Disk /dev/mmcblk1: 14.7 GiB, 15758000128 bytes, 30777344 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

... 생략 ...

Disk /dev/mmcblk0: 29.8 GiB, 32010928128 bytes, 62521344 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x58bc1052

Device         Boot  Start      End  Sectors  Size Id Type
/dev/mmcblk0p1        8192   139263   131072   64M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      139264 62521343 62382080 29.8G 83 Linux

이미지 복원

이미지 복원이 완료되면 SD 메모리를 제거하고 재부팅, eMMC 용량을 다 사용하지 않는 경우 eMMC 확장 필요

$ sudo dd if=tinkerOSplus207.img of=/dev/mmcblk1 bs=10MB
800+1 records in
800+1 records out
8002732032 bytes (8.0 GB, 7.5 GiB) copied, 241.641 s, 33.1 MB/s

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)

Font awesome 가운데 정렬

Programming/JavaScript, Sencha 2018.08.13 23:46 Posted by 파란크리스마스

출처

css 파일 참조

<link rel="stylesheet" href="<c:url value="/commons/fontawesome/css/all.css"/>">

css

.fa {
	vertical-align: middle;
}

html

<i class="fa fa-plus-circle fa-2x" aria-hidden="true" style="margin-left: 5px;"></i>
<i class="fa fa-minus-circle fa-2x" aria-hidden="true"></i>