펜 사용하기

01. 스마트 북을 만들자

펜을 이용하여 책에 인쇄되어 있는 OID 코드를 읽어보자. 펜을 사용하기 위해서는 그림 1과 같이 먼저 스마트 로봇 론처의 환경 설정 > 주변기기에서 펜을 등록해야 한다. 각각의 펜은 제품 번호로 구분되는데, 펜의 제품 번호는 그림 1과 같이 등록할 때 표시된다(펜 종류 #1).

그림 1. 주변기기 등록

펜으로 OID 코드를 읽는 프로그램을 작성하시오.

새 프로젝트 만들기를 참고하여 안드로이드 프로젝트와 플래시 파일을 만들고, setOnInitialized(callback:Function) 메소드와 setOnExecute(callback:Function) 메소드를 사용하여 콜백 함수를 등록하자. 또한, activate() 메소드를 호출하여 스마트 로봇 론처와 연결하도록 하자.

 import org.roboid.robot.Robot;
 import org.smartrobot.android.SmartRobot;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.setOnExecute(onExecute);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
 }

 function onExecute():void
 {
 }

펜에는 OID 값을 읽는 디바이스로 EVENT_OID가 있다. OID 데이터는 -1부터 65535까지의 값을 가지는데, -1은 OID 코드를 읽지 못하였을 때 표시하는 값이다. 정상적으로 코드를 읽은 경우에는 0 이상의 값을 가진다.

알버트 로봇에서는 Robot 클래스의 findDeviceById(deviceId:int) 메소드를 사용하여 필요한 디바이스의 객체를 얻었지만, 주변기기의 경우에는 Robot 클래스의 findPeripheralDeviceById(productId:int, deviceId:int) 메소드를 사용하여야 한다. 디바이스 ID만으로는 어느 펜의 디바이스인지 구분할 수가 없기 때문에 productId에 제품 번호를 넣어주어야 한다. 여기서는 제품 번호가 1인 경우라고 가정하자.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 var oidDevice:Device;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.setOnExecute(onExecute);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     oidDevice = robot.findPeripheralDeviceById(1, Pen.EVENT_OID); // 1번 펜의 OID 디바이스
 }

 function onExecute():void
 {
     var oid:int = -1;
     if(oidDevice.e())
         oid = oidDevice.read();
 }

OID 디바이스는 이벤트 디바이스라는 것에 주의해야 한다. 이벤트가 발생하였을 때만 데이터가 갱신되기 때문에 데이터를 읽기 전에 반드시 Device 클래스의 e() 메소드를 사용하여 이벤트가 발생하였는지 확인해야 한다.

펜에는 작고 앙증맞은 버튼이 있다. 똑같은 OID 코드에 대해서도 버튼 상태에 따라 다른 동작을 하도록 만들 수 있다. 버튼 상태에 대한 디바이스는 EVENT_BUTTON이다. 이벤트 디바이스이며, 버튼을 눌렀을 때는 1, 누르지 않았을 때는 0의 값을 가진다.

OID 코드와 함께 버튼의 상태도 읽어보도록 하자.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 var oidDevice:Device;
 var buttonDevice:Device;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.setOnExecute(onExecute);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     oidDevice = robot.findPeripheralDeviceById(1, Pen.EVENT_OID);
     buttonDevice = robot.findPeripheralDeviceById(1, Pen.EVENT_BUTTON); // 1번 펜의 버튼 디바이스
 }

 function onExecute():void
 {
     var oid:int = -1;
     var button:int = 0;
     if(oidDevice.e())
         oid = oidDevice.read();
     if(buttonDevice.e())
         button = buttonDevice.read();
 }

이번에는 리스너 함수를 사용하여 구현해 보자. 리스너 함수는 Robot 클래스의 addDeviceDataChangedListener(listener:Function) 메소드를 사용하여 등록할 수 있다.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     robot.addDeviceDataChangedListener(onDeviceDataChanged);
 }

 function onDeviceDataChanged(device:Device, values:Array, timestamp:int):void
 {
     var oid:int = -1;
     var button:int = 0;
     if(device.getProductId() == 1)
     {
         switch(device.getId())
         {
         case Pen.EVENT_OID:
             oid = values[0];
             break;
         case Pen.EVENT_BUTTON:
             button = values[0];
             break;
         }
     }
 }

Device 클래스의 getProductId() 메소드를 사용하여 제품 번호가 1인 경우인지 확인하였는데, 어느 펜을 사용해도 상관이 없다면 이 조건문은 없어도 된다.

02. 멀리 가면 안되요

펜은 지그비 무선 통신으로 로봇에 데이터를 전달한다. 와이파이 존에서 멀어지면 통신이 안되듯이 펜도 로봇에서 멀어지면 데이터를 전달하지 못한다.

지그비 신호 세기를 알아내는 프로그램을 작성하시오.

펜에는 지그비 신호 세기에 해당하는 디바이스로 SENSOR_SIGNAL이 있다. 신호 세기는 0부터 255까지의 값을 가지는데 펜이 로봇 가까이 있으면 신호 세기가 커져서 값이 증가하고, 멀어지면 신호 세기가 작아져서 값이 감소하게 된다.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 var signalDevice:Device;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.setOnExecute(onExecute);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     signalDevice = robot.findPeripheralDeviceById(1, Pen.SENSOR_SIGNAL);
 }

 function onExecute():void
 {
     var signal:int = signalDevice.read();
 }

이번에는 리스너 함수를 사용하여 구현해 보자.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     robot.addDeviceDataChangedListener(onDeviceDataChanged);
 }

 function onDeviceDataChanged(device:Device, values:Array, timestamp:int):void
 {
     var signal:int;
     switch(device.getId())
     {
     case Pen.SENSOR_SIGNAL:
         signal = values[0];
         break;
     }
 }

03. 배고파요

펜에 내장된 배터리의 상태를 알려 주는 센서 디바이스는 SENSOR_BATTERY이다. 0부터 100까지의 값을 가지며 배터리의 잔량을 %로 나타낸다.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 var batteryDevice:Device;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.setOnExecute(onExecute);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     batteryDevice = robot.findPeripheralDeviceById(1, Pen.SENSOR_BATTERY);
 }

 function onExecute():void
 {
     var battery:int = batteryDevice.read();
 }

리스너 함수를 사용하여 구현하면 다음과 같다.

 import org.roboid.robot.Device;
 import org.roboid.robot.Robot;
 import kr.robomation.peripheral.Pen;
 import org.smartrobot.android.SmartRobot;

 SmartRobot.setOnInitialized(onInitialized);
 SmartRobot.activate();

 function onInitialized(robot:Robot):void
 {
     robot.addDeviceDataChangedListener(onDeviceDataChanged);
 }

 function onDeviceDataChanged(device:Device, values:Array, timestamp:int):void
 {
     var battery:int;
     switch(device.getId())
     {
     case Pen.SENSOR_BATTERY:
         battery = values[0];
         break;
     }
 }