Search

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

실행 동영상

Blueinno2(RFduinoBLE) - Raspberry PI 3 / BLE 연동

OS/Raspberry Pi 2016.12.14 01:11 Posted by 파란크리스마스

출처 : Raspberry Pi: Control WS2812B (NeoPixels) With Bluetooth LE
Eclipse Kura™ Documentation
The Pi4J Project

Bluetooth 모듈이 내장된 블루이노2로 BLE 송신하고, 라즈베리파이3의 Bluetooth 모듈로 수신 받아 데이터처리 해보았습니다.

블루이노2 코드

#include <RFduinoBLE.h>

int Potent=2;
boolean is_connect;

void setup() {
  // put your setup code here, to run once:
  RFduinoBLE.deviceName = "bluexmas";

  // this is the data we want to appear in the advertisement
  //RFduinoBLE.advertisementData = "My BLE LED";
  
  //RFduinoBLE.advertisementInterval = MILLISECONDS(300);
  //RFduinoBLE.txPowerLevel = -20;  // (-20dbM to +4 dBm)
    
  Serial.begin(9600);  
  Serial.println("Start Test");      // With more than 15 characters thie Start Test keeps happening

  // start the BLE stack
  RFduinoBLE.begin();  
}

void loop() {
  char BPM_lcd[10];
  
  RFduino_ULPDelay(100);  
  // Switch to lower power mode
  //RFduino_ULPDelay(INFINITE);
  //RFduino_ULPDelay( SECONDS(1) ); //sample once per second

  if (is_connect) {
    int sensorValue = analogRead(Potent);
    Serial.println(sensorValue);             // debug value

    //sprintf(BPM_lcd, "%10d", sensorValue);
    //lcd.println(BPM_lcd);     
    
    RFduinoBLE.sendInt(sensorValue);  //sends the char array
  }
}

void RFduinoBLE_onConnect() {
  // Debug message printed to Serial interface
  Serial.println("RFduino connected");
  is_connect = true;
}

void RFduinoBLE_onDisconnect() { 
  // Debug message printed to Serial interface
  Serial.println("RFduino disconnected");
  is_connect = false;
}

void RFduinoBLE_onReceive(char *data, int len) {
  // Debug message printed to Serial interface
  Serial.println("Data received: ");
  for(int i=0;i<len;i++)
    Serial.print(data[i]);
    Serial.println();
    Serial.println(data);
}

Blueinno.java

BLE 관련 코드만 보기 편하게 하기 위해서 모터 제어 관련 코드는 빼고 블루이노2와 통신하는 부분만 공개

package ble.blueinno2;

import java.util.List;
import java.util.Scanner;

import org.eclipse.kura.KuraException;
import org.eclipse.kura.bluetooth.BluetoothDevice;
import org.eclipse.kura.bluetooth.BluetoothGatt;
import org.eclipse.kura.bluetooth.BluetoothGattService;
import org.eclipse.kura.bluetooth.BluetoothLeNotificationListener;
import org.eclipse.kura.bluetooth.BluetoothLeScanListener;
import org.eclipse.kura.linux.bluetooth.util.BluetoothProcess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Blueinno implements BluetoothLeNotificationListener, BluetoothLeScanListener {
	
	private static final Logger logger = LoggerFactory.getLogger(BluetoothProcess.class);

	private BluetoothGatt m_bluetoothGatt;
	private BluetoothDevice m_device;
	private boolean m_connected;

	public Blueinno(BluetoothDevice bluetoothDevice) {
		// m_device = bluetoothDevice;
		m_connected = false;
	}

	public BluetoothDevice getBluetoothDevice() {
		return m_device;
	}

	public void setBluetoothDevice(BluetoothDevice device) {
		m_device = device;
	}

	public boolean isConnected() {
		return m_connected;
	}

	public boolean connect(BluetoothLeNotificationListener listener) throws KuraException {
		m_bluetoothGatt = m_device.getBluetoothGatt();
		logger.info("접속시도");
		boolean connected = m_bluetoothGatt.connect();
		if (connected) {
			m_bluetoothGatt.setBluetoothLeNotificationListener(listener);
			logger.info("리스너등록");
			m_connected = true;
			return true;
		} else {
			// If connect command is not executed, close gatttool
			m_bluetoothGatt.disconnect();
			m_connected = false;
			return false;
		}
	}

	public void disconnect() {
		if (m_bluetoothGatt != null) {
			m_bluetoothGatt.disconnect();
			m_connected = false;
		}
	}

	/*
	 * Discover services
	 */
	public List<BluetoothGattService> discoverServices() {
		return m_bluetoothGatt.getServices();
	}

	@Override
	public void onScanFailed(int errorCode) {
		// TODO Auto-generated method stub
		System.out.println("error = " + errorCode);
	}

	@Override
	public void onScanResults(List<BluetoothDevice> devices) {
		logger.info("onScanResults = " + devices.size());

		for (BluetoothDevice device : devices) {
			logger.info("Found Bluetooth Device " + device.getName() + " [" + device.getAdress() + "]");
		}
		
		System.out.print("ble address > ");
		Scanner scanner = new Scanner(System.in);
		String blc_address = scanner.next();
		
		BluetoothDevice nurum_device = null;
		for (BluetoothDevice device : devices) {
			if (device.getAdress().equals(blc_address)) {
				nurum_device = device;
			}
		}
		
		if (nurum_device != null) {
			//ble_nurum = new Blueinno(nurum_device);
			this.setBluetoothDevice(nurum_device);
			try {
				if (this.connect(this)) {
					System.out.println("ble connect");
					
					Runnable aa = new Runnable() {
						
						@Override
						public void run() {
							while (true) {
								try {
									String sensorValue = m_bluetoothGatt.readCharacteristicValue("0x000e");
									System.out.println(sensorValue);
									
									// 모터제어
									// 생략
								} catch (KuraException e1) {
									e1.printStackTrace();
								}
								try {
									Thread.sleep(100);
								} catch (Exception e) {
									
								}
							}
						}
					};
					
					Thread bb = new Thread(aa);
					bb.start();
				}
			} catch (KuraException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public void onDataReceived(String handle, String value) {
		System.out.println("handle: " + handle + " value: " + value);
	}
}

BlueinnoMain.java

package ble.blueinno2;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.eclipse.kura.linux.bluetooth.le.BluetoothLeScanner;

public class BlueinnoMain {
	
	Logger logger = Logger.getLogger(this.getClass());

	private Blueinno blueinno = null;
	
	public static void main(String[] args) throws Exception {
		BlueinnoMain bletest = new BlueinnoMain();
		bletest.init();
		bletest.startScan();
	}
	
	public void init() {
		Logger.getRootLogger().setLevel(Level.DEBUG);
		logger.info("초기화");
		blueinno = new Blueinno();
	}

	public void startScan() throws InterruptedException {
		BluetoothLeScanner m_bls = new BluetoothLeScanner();
		m_bls.startScan("hci0", blueinno);
		Thread.sleep(10000);
		m_bls.killScan();
	}
}

실행


Raspberry Pi & Bluetooth LE(nurum) / LED Control

OS/Raspberry Pi 2016.11.20 02:11 Posted by 파란크리스마스

출처 : Eclipse Kura™ Documentation
The Pi4J Project

라즈베리파이2에 BLE 동글이와 BLE 스마트 버튼인 nurum으로 클릭 이벤트를 받아서
GPIO를 이용해서 LED를 컨트롤 해보았습니다.

BleNurum class

package bletest;

import java.util.List;

import org.eclipse.kura.KuraException;
import org.eclipse.kura.bluetooth.BluetoothDevice;
import org.eclipse.kura.bluetooth.BluetoothGatt;
import org.eclipse.kura.bluetooth.BluetoothGattService;
import org.eclipse.kura.bluetooth.BluetoothLeNotificationListener;

public class BleNurum {

	private BluetoothGatt m_bluetoothGatt;
	private BluetoothDevice m_device;
	private boolean m_connected;

	public BleNurum(BluetoothDevice bluetoothDevice) {
		m_device = bluetoothDevice;
		m_connected = false;
	}

	public BluetoothDevice getBluetoothDevice() {
		return m_device;
	}

	public void setBluetoothDevice(BluetoothDevice device) {
		m_device = device;
	}

	public boolean isConnected() {
		return m_connected;
	}

	public boolean connect(BluetoothLeNotificationListener listener) throws KuraException {
		m_bluetoothGatt = m_device.getBluetoothGatt();
		boolean connected = m_bluetoothGatt.connect();
		if (connected) {
			m_bluetoothGatt.setBluetoothLeNotificationListener(listener);
			m_connected = true;
			return true;
		} else {
			// If connect command is not executed, close gatttool
			m_bluetoothGatt.disconnect();
			m_connected = false;
			return false;
		}
	}

	public void disconnect() {
		if (m_bluetoothGatt != null) {
			m_bluetoothGatt.disconnect();
			m_connected = false;
		}
	}

	/*
	 * Discover services
	 */
	public List<BluetoothGattService> discoverServices() {
		return m_bluetoothGatt.getServices();
	}
}

BleTestMain class

package bletest;

import java.nio.ByteBuffer;
import java.util.List;
import java.util.Scanner;

import org.eclipse.kura.KuraException;
import org.eclipse.kura.bluetooth.BluetoothDevice;
import org.eclipse.kura.bluetooth.BluetoothLeNotificationListener;
import org.eclipse.kura.bluetooth.BluetoothLeScanListener;
import org.eclipse.kura.linux.bluetooth.le.BluetoothLeScanner;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

public class BleTestMain implements BluetoothLeScanListener, BluetoothLeNotificationListener {
	
	private BleNurum ble_nurum = null;
	private GpioController gpio = null;
	private GpioPinDigitalOutput led_01 = null;
	private GpioPinDigitalOutput led_02 = null;
	
	public static void main(String[] args) throws Exception {
		BleTestMain bletest = new BleTestMain();
		bletest.init();
		bletest.startScan();
	}
	
	public void init() {
		// create gpio controller
		gpio = GpioFactory.getInstance();
		led_01 = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_08, "Red LED", PinState.HIGH);
		led_02 = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_09, "Blue LED", PinState.HIGH);
		// set shutdown state for this pin
		led_01.setShutdownOptions(true, PinState.LOW);
		led_02.setShutdownOptions(true, PinState.LOW);
		led_01.low();
		led_02.low();
	}

	public void startScan() throws InterruptedException {
		BluetoothLeScanner m_bls = new BluetoothLeScanner();
		m_bls.startScan("hci0", this);

		Thread.sleep(3000);

		m_bls.killScan();
	}

	@Override
	public void onScanFailed(int errorCode) {
		// TODO Auto-generated method stub
		System.out.println("error = " + errorCode);
	}

	@Override
	public void onScanResults(List<BluetoothDevice> devices) {
		System.out.println("onScanResults = " + devices.size());

		for (BluetoothDevice device : devices) {
			System.out.println("Found Bluetooth Device " + device.getName() + " [" + device.getAdress() + "]");
		}
		
		System.out.print("ble address > ");
		Scanner scanner = new Scanner(System.in);
		String blc_address = scanner.next();
		
		BluetoothDevice nurum_device = null;
		for (BluetoothDevice device : devices) {
			if (device.getAdress().equals(blc_address)) {
				nurum_device = device;
			}
		}
		
		if (nurum_device != null) {
			ble_nurum = new BleNurum(nurum_device);
			try {
				if (ble_nurum.connect(this)) {
					System.out.println("ble connect");
				}
			} catch (KuraException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public static byte[] decode(String hex) {

		String[] list = hex.split("(?<=\\G.{2})");
		ByteBuffer buffer = ByteBuffer.allocate(list.length);
		System.out.println(list.length);
		for (String str : list)
			buffer.put(Byte.parseByte(str, 16));

		return buffer.array();

	}

	@Override
	public void onDataReceived(String handle, String value) {
		String val = new String( decode(value.replaceAll("\\p{Z}", "")) );
		
		System.out.println("handle: " + handle + " value: " + value + " / " + val);
		
		if (val.equals("!1")) {
			led_01.toggle();
		}
		
		if (val.equals("!2")) {
			led_02.toggle();
		}
		
		if (val.equals("!3")) {
			led_01.low();
			led_02.low();
		}		
		
		if (val.equals("!H")) {
			ble_nurum.disconnect();
			gpio.shutdown();
			System.exit(1);
		}
	}
}

실행

$ sudo java -cp .:pi4j-core.jar:org.apache.commons.io_2.4.0.jar:org.eclipse.equinox.io_1.0.400.v20120522-2049.jar:org.eclipse.osgi_3.8.1.v20120830-144521.jar:org.eclipse.osgi.services_3.3.100.v20120522-1822.jar:org.eclipse.osgi.util_3.2.300.v20120522-1822.jar:org.eclipse.soda.dk.comm_1.2.1.jar:slf4j.api_1.6.4.jar:slf4j.jdk14_1.6.4.jar:slf4j.log4j12_1.6.0.jar:usb4java-javax_1.0.0.jar bletest.BleTestMain