Research Topics/Arduino2009.02.23 12:54
Arduino에서 XBee 를 사용하는 방법입니다. 책 Making Things Talk 의 203페이지에서는 XBee 칩의 초기화
및 주소 설정 과정이 있습니다만, 브로드케스팅방식을 사용하는데는 굳이 위의 주소설정 과정을 거치지 않아도 잘 동작 합니다.

책에서는 XBee 의 좁은 핀을 넓혀주는 Breakout board를 사용하거나 Arduino 에 장착되기 쉽게 만든 XBee Shield를 사용합니다. 여기서는 sadi의 XBee Shield 를 사용하였으나, 굳이 Shield 가 없어도 구성 방법은 동일합니다. XBee의 핀에 소켓등을 꽂아 핀번호에 맞게 Power / Tx, Rx 등을 연결만 해주면 됩니다. (선들이 좀 주렁주렁 지저분 해지겠지만요)

sadi XBee shield 를 사용할 경우 다음과 같이 Analog 와 Digital Pin 을 사용할 수 있습니다.
주의할점은, USB 를 통하여 컴퓨터와 통신 (Arduino 프로그램 작성 및 다운로드 등) 하는 경우는 우측하단의 점퍼 두개를 왼쪽두개로 잡아주어야 합니다. (XBee 와 통신시에는 오른쪽 두개)

XBee 간의 통신은 브로드캐스팅 방식으로, 별 특별한 코드 없이 일반적인 Serial.print() 와 Serial.read() 로 정보를 쏘고 수신할 수 있습니다. 다음과 같이 마스터/슬레이브 또는 서버/클라이언트 구분없이 동일 코드에서 송신/수신을 테스트 해 볼 수 있습니다.

void setup() {
  Serial.begin(19200);
  pinMode(txLed, OUTPUT);
  pinMode(rxLed, OUTPUT);
}

void loop() {

  if(Serial.available() > 0) { // Listening
    digitalWrite(rxLed, HIGH);
    handleSerial();
 
    ... 중간생략
 
  char sensorValue = readSensor();
 
  if(sensorValue > 0) {
   
    digitalWrite(txLed, HIGH);
    Serial.print(sensorValue, DEC);
    Serial.print("\r");
    digitalWrite(txLed, LOW);
  }
}

void handleSerial() {

  inByte = Serial.read();
 
  if((inByte >= '0') && (inByte <= '9')) {
   inString[stringPos] = inByte;
   stringPos++;
  }
 
  if(inByte == '\r') {
   int brightness = atoi(inString);
   analogWrite(analogLed, brightness);
  
   for(int c=0 ; c<stringPos ; c++) {
    inString[c] = 0;  
   }
  
   stringPos = 0;
 
  }


통신 가능한 거리는 실내에서는 30미터가 안되는 것 같고 확 트인 야외에서는 100미터 정도 가능하다고 합니다.


Posted by 박동윤(http://www.cre8ive.kr) cre8ive

댓글을 달아 주세요

  


1. Navigation-Based Application 으로 프로젝트 생성
   - AppDelegate 와 RootViewController 가 기본적으로 생성됨
   - 이때 RootViewController 는 UITableViewController 를 상속받고, tableView 라는 UITableView 를 담고 있음
      그리고, AppDelegate 의 UINavigationController 에서 보여지는 첫 화면이 됨
   - AppDelegate 는 UINavigationController *navigationController 를 담고 있음 
 
2. RootViewController의 tableView 를 위한 모델(데이터) 생성
   - AppDelegate의 applicationDidFinishLaunching와 같은 초기화 부분에서 NSArray 등의 데이터 생성
   - RootViewController 는 UITableViewController를 상속받으므로, tableView와 관련된 메소드가 정의되어 있음
      이 메소드들을 수정하여 데이터를 채워줄 수 있도록 함
      (numberOfSectionsInTableView, numberOfRowsInSection, cellForRowAtIndexPath)

3. 메뉴 선택시 로드될 UIViewController 추가 
   - Add - New File - UIViewController subclass 또는 기타 목적에 맞는 클래스 선택
   - xib 파일도 RootViewController.xib 등을 열어 새이름으로 저장, 새클래스 이름 지정

4. 하위 계층의 새로운 UI 로딩(push) 구현
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 부분에서
       하위 계층의 새로운 UIViewController (또는 다른 UIView 화면)를 로딩하도록 구현 (pushViewController 사용)

       예)
        AboutViewController *aboutViewController = [[AboutViewController alloc]
        initWithNibName:@"AboutViewController" bundle:nil];
        [self.navigationController pushViewController:aboutViewController animated:YES];
        [aboutViewController release];

    - 이때 self.navigationController 는 UINavigationController 에 담긴 View controller 라면 접근 가능하도록 되어있음
     
5. 하위계층에서 복귀(pop)는 특별히 구현하지 않아도 됨
    - UINavigationController 의 Back 버튼 처리가 자동으로 됨
    - 다른 버튼 등을 사용한 수동 구현시는 [self.navigationController popViewControllerAnimated:YES]; 사용



Posted by 박동윤(http://www.cre8ive.kr) cre8ive

댓글을 달아 주세요


안녕하세요 박동윤입니다.
지난 Hello sadi! 프로젝트에 가속도 센서의 데이터를 받아 이미지를 움직이는 부분을 추가해보도록 하겠습니다.

단, 지난 프로젝트에서 Window-Based Application 으로 시작한 것과는 달리 View-Based Application 으로 제작하도록 하겠습니다. (ViewController를 사용)

특별히 다른 것은 없고 Window-Based Application 으로 생성한 프로젝트에서는 AppDelegate 만 존재하여, 우리가 UIView 를 상속한 MyView 라는 클래스를 직접 파일 생성하여 추가해주었습니다만, View-Based Application 에서는 AppDelegate 과 함께 ViewController 라는 것이 생성됩니다. 이 ViewController 는 이미 View 를 담고 있기에 이를 바로 사용하면 됩니다.

View-Based Application 으로 프로젝트 생성



저는 HelloSADIAccel 이라는 이름으로 프로젝트를 생성하였습니다


다음과 같이 AppDelegate 와 ViewController 가 기본적으로 생성됩니다


HelloSADIAccelAppDelegate.h 를 보면 다음과 같이 HelloSADIAccelViewController 를 담고 있습니다.
#import <UIKit/UIKit.h>

@class HelloSADIAccelViewController;

@interface HelloSADIAccelAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    HelloSADIAccelViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet HelloSADIAccelViewController *viewController;

@end

HelloSADIAccelAppDelegate.m 을 보면 HelloSADIAccelViewController 의 view 를 addSubview 로 window에 추가하는 것을 볼 수 있습니다. 즉, 우리는 이미 존재하는 HelloSADIAccelViewController 의 view 를 사용하면 됩니다.
#import "HelloSADIAccelAppDelegate.h"
#import "HelloSADIAccelViewController.h"

@implementation HelloSADIAccelAppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {   
   
    // Override point for customization after app launch   
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}


@end

HelloSADIAccelViewController.xib 을 더블클릭하여 인터페이스빌더를 실행하고, 지난번 프로젝트와 동일하게 UI 제작을 합니다. 지난번 처럼, 일단 SADI_LOGO.png 를 프로젝트의 Resource 폴더에 Add 해야겠지요. (지난 세미나자료 참조)

  


 
  

역시 주의할점은 다음과 같이 File's Owner 를 선택한 상태에서 (HelloSADIAccelViewController가 선택된 상태에서)위의 Action/Outlet 연결작업을 해야합니다. 종종 다른 요소의 정보창이 표시된 상태에서 하는 경우가 있습니다.
이때 File's Owner 는 HelloSADIAccelViewController 자신이라고 보면 됩니다.(인스턴스)


제작이 끝났으면 일단 File - Save 하여 수정된 인터페이스 정보를 xib 파일에 저장하고,
다시, File 메뉴의 Write Class Files 를 눌러 변경사항을 기록합니다. 이때 Merge 를 선택하여 기존 클래스에
정보를 추가합니다.





Merge 를 누르면 머지 프로그램이 실행되고 두 코드를 비교하는데,
키보드의 좌우키와 상하키를 이용하여 다음과 같이 변경/추가된 내용들을 좌측 (추가된 내용) 으로 선택하고 save 해줍니다.




HelloSADIAccelViewController.m 파일에 다음과 같이 버튼이 눌렸을때 텍스트가 바뀌도록 수정합니다. (지난번과 동일)

#import "HelloSADIAccelViewController.h"

@implementation HelloSADIAccelViewController
- (IBAction)button1Pressed {
    textLabel.text = @"Communication Design";
}

- (IBAction)button2Pressed {
    textLabel.text = @"Fashion Design";
}

- (IBAction)button3Pressed {
    textLabel.text = @"Product Design";
}




이제 View-Based Application 템플릿으로 지난번과 같은 내용이 완성이 되었습니다.
여기서 가속도 센서를 사용하여 로고를 움직이는 부분을 추가하도록 하겠습니다.

다음과 같이 HelloSADIAccelAppDelegate.h 에 UIAccelerometerDelegate 를 추가해줍니다.
#import <UIKit/UIKit.h>

@class HelloSADIAccelViewController;

@interface HelloSADIAccelAppDelegate : NSObject <UIApplicationDelegate, UIAccelerometerDelegate> {
    UIWindow *window;
    HelloSADIAccelViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet HelloSADIAccelViewController *viewController;

@end

HelloSADIAccelAppDelegate.m 에는 다음과 같이 추가하여 가속도 센서를 초기화 하고 didAccelerate 를 구현합니다.
setUpdateInterval 은 말그대로 초당 업데이트 회수(Hertz)를 지정해주는 부분입니다.
#import "HelloSADIAccelAppDelegate.h"
#import "HelloSADIAccelViewController.h"

@implementation HelloSADIAccelAppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {   
    // Configure and start the accelerometer
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 40)];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
   
    // Override point for customization after app launch   
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    [viewController handleAccelerometerX:acceleration.x Y:acceleration.y Z:acceleration.z];
}

- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}
@end

위에서 handleAccelerometerX:Y:Z: 는 우리가 ViewController 에 구현하여 이미지를 움직일 메소드 입니다.

그럼 다음과 같이 HelloSADIAccelViewController.h 에 메소드를 정의를 하고
#import <UIKit/UIKit.h>

@interface HelloSADIAccelViewController : UIViewController {
    IBOutlet UIButton *button1;
    IBOutlet UIButton *button2;
    IBOutlet UIButton *button3;
    IBOutlet UIImageView *imageSADI;
    IBOutlet UILabel *textLabel;
}
- (IBAction)button1Pressed;
- (IBAction)button2Pressed;
- (IBAction)button3Pressed;
- (void)handleAccelerometerX:(float)x Y:(float)y Z:(float)z;

@end

HelloSADIAccelViewController.m 에 다음과 같이 구현을 합니다.
x, y 축 기울기 에 따라 로고 이미지가 좌우 상하로 움직이게 됩니다.

가속도 센서는 시뮬레이터에서는 테스트 불가능하며, 기기에서만 테스트 가능합니다.
#import "HelloSADIAccelViewController.h"

@implementation HelloSADIAccelViewController
- (IBAction)button1Pressed {
    textLabel.text = @"Communication Design";
}

- (IBAction)button2Pressed {
    textLabel.text = @"Fashion Design";
}

- (IBAction)button3Pressed {
    textLabel.text = @"Product Design";
}

- (void)handleAccelerometerX:(float)x Y:(float)y Z:(float)z {
    if(y<-0.5)   
        imageSADI.center = CGPointMake(imageSADI.center.x, imageSADI.center.y+3);
    if(y>0.5)
        imageSADI.center = CGPointMake(imageSADI.center.x, imageSADI.center.y-3);
    if(x<-0.5)   
        imageSADI.center = CGPointMake(imageSADI.center.x-3, imageSADI.center.y);
    if(x>0.5)
        imageSADI.center = CGPointMake(imageSADI.center.x+3, imageSADI.center.y);
   
}


Posted by 박동윤(http://www.cre8ive.kr) cre8ive

댓글을 달아 주세요

dip소개2009.02.21 14:15
디지털 미디어의 다변화와 더불어 오늘날의 디자인과 기술은 그 경계를 허물며 새로운 가능성을 창조해내고 있습니다. 효과적인 정보전달과 사용성, 심미성 등의 디자인의 기본적인 기능을 넘어 이제는, 어떤 사용자 경험(User Experience)을 창출해 낼 것인가를 주목하게 되면서 이를 가능하게 하는 다양한 디자인 방법과 기술과 디자인의 융합이 화두가 되고 있습니다. 한편, 이러한 상황에 따라 디자이너도 기본적인 디지털 미디어와 기술에 대한 이해가 뒷받침 되어야 보다 효과적이고 훌륭한 디자인을 할 수 있게되었습니다.

DIP(Design In Programming)는 이러한 사용자 경험과 인터렉션 디자인 및 이와 관련된 기술에 관심을 가지는 sadi communiction design 학과 학생들에 의한 SIG(Special Interest Group)입니다. 인터렉션 디자인 분야에서 다양한 방면으로 활용되고 있는 소프트웨어 및 하드웨어들에 대한 스터디를 진행고 있으며, 멤버들은 학교 정규 수업의 과제 만으로도 매우 바쁜 상황에서도 적극적으로 참여하고 있습니다.

보다 실용적인 공부가 될 수 있도록, 학기별로 정해진 주제의 스터디에대한 성과물로, 방학기간에 실질적인 작업 및 작품 활동을 하며, 전시회를 통하여 디자인 결과물에 대한 사람들의 피드백을 얻으며 소중한 경험을 하게됩니다. 2007년 가을의 일본 디자인페스타 전시 참여를 시작으로하여, 2008년 겨울 및 여름의 두차례의 sadi space gallery의 전시를 통해 인터렉션 디자인 작업의 기획 단계부터 디자인, 구현 및 전시 부스 설치와 관객의 피드백이라는 일련의 과정을 경험하고 있습니다.

하드웨어 분야에서는 Arduino와 다양한 센서등을 이용한 물리적인 사용자 입력을 받아들이는 방법과 이에 대한 반응을 구현하는 방법 및 구조에 대한 제반지식과 능력을 갖추는데 초점을 맞추고 있으며 Processing 등의 프로그램과의 연동 및 비주얼화에 대한 공부가 이루어지고 있습니다.

소프트웨어 분야에서는 인터렉션 디자인에서 가장 널리 활용되고 있는 Processing 을 비롯하여, 웹과 멀티미디어 분야에서 막강한 영향을 발휘하고 있는 Flash 및 ActionScript 3.0 에 대한 공부와 관련된 작업이 진행중이며, 우리의 삶과 뗄수 없는 관계가 된 모바일 플랫폼에 대한 공부 역시 많은 관심을 가지고 진행중입니다. 특히 최근의 큰 화두인 Apple의 iPhone SDK 역시 지속적인 세미나와 스터디를 통하여 모바일 기기에서의 사용자 경험과 다양한 디자인의 가능성을 탐구하고 있습니다.

이와같은 하드웨어 및 소프트웨어에 대한 스터디와 더불어, Ben Fry의 저서인 Visualizing Data 등을 통해 커뮤니케이션 디자인의 중요한 요소인 information design의 측면에서 인터렉티브한 요소가 어떻게 적용되고 디자인에 힘을 불어넣을 수 있는가에 대하여 공부하고 있습니다.

아직, 인터렉션 디자인의 근간이 되는 HCI 나 UX 분야의 이론적인 접근과 경험이 많이 부족하여 앞으로는 이러한 부분에 있어서 수업과 연계하여 공부를 해 나갈 예정이며, Interaction Lab의 다양한 하드웨어 장비들을 활용한 폭넓은 사용자 경험 구현에 대하여 공부를 해 나갈 예정입니다.

한편, 이러한 소프트웨어나 하드웨어 기술을 활용하는데 있어서 주객이 전도되지 않도록, 기술보다는 디자인의 측면에서 더욱 고려하고 생각하며 기술을 활용하여 그 가능성을 넓힐 수 있는 스터디 모임이 될 수 있도록 노력할 계획입니다.



-----------------------------
Website
http://cdsig.tistory.com

Members
지도교수님 : 김우정, 서효정
3학년 대표 : CD학과 박동윤 (前 삼성전자 정보통신총괄 통신연구소, S/W 엔지니어)
2학년 대표 : CD학과 함경석 (前 삼성전자 정보통신총괄 무선사업부, H/W 엔지니어)
Posted by 박동윤(http://www.cre8ive.kr) cre8ive

댓글을 달아 주세요


Papervision3D 의 기본 뼈대가 되는 코드는 다음과 같습니다.

기본적으로 Sprite 클래스를 상속받고, Viewport3D, Scene3D, Camera3D, BasicRenderEngine 들을 생성/초기화 한 후,
Event.ENTER_FRAME 의 이벤트헨들러에서 계속적으로 renderScene 을 호출하여 3D 화면을 렌더링 합니다.
아래는 검은 배경에 와이어프레임형태의 구(Sphere)를 하나 그리는 내용입니다.

package
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
 
    [SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
    public class HelloPV3D extends Sprite
    {
        private var viewport:Viewport3D;
        private var scene:Scene3D;
        private var camera:Camera3D;
        private var renderer:BasicRenderEngine;
 
        public function HelloPV3D()
        {
            viewport = new Viewport3D();
            addChild(viewport);
 
            scene = new Scene3D();
            camera = new Camera3D();
            renderer = new BasicRenderEngine();
 
            var sphere:Sphere = new Sphere();
            scene.addChild(sphere);
 
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        private function enterFrameHandler(event:Event):void
        {
            renderer.renderScene(scene, camera, viewport);
        }
 
    }
}

Viewport3D, Scene3D, Camera3D, BasicRenderEngine 이들이 핵심이라고 할 수 있는데, 이들의 정체를 Reference 에서 살펴보면 다음과 같습니다.

Viewport3D Inheritance flash.display.Sprite
Scene3D Inheritance SceneObject3D Inheritance DisplayObjectContainer3D Inheritance flash.events.EventDispatcher
Camera3D Inheritance CameraObject3D Inheritance DisplayObject3D Inheritance DisplayObjectContainer3D Inheritance flash.events.EventDispatcher
BasicRenderEngine Inheritance AbstractRenderEngine Inheritance flash.events.EventDispatcher

BasicRenderEngine links Viewport3Ds, Scene3D, and Camera3Ds together by gathering in all of their data, rendering the data, then calling the necessary functions to update from the rendered data

한편, 위와 같은 일련의 기본적인 초기화 코드를 구현해 놓은 클래스가 있는데, 바로 BasicView 입니다.
BasicView 를 사용하면 Viewport3D, Scene3D, Camera3D, BasicRenderEngine 초기화 과정을 거치지 않아도 됩니다.

package
{
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
 
    [SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
    public class BasicViewTest extends BasicView
    {
        public function BasicViewTest()
        {
            var sphere:Sphere = new Sphere();
            scene.addChild(sphere);
            startRendering();
        }
 
    }
}

이때 render.renderScene(scene, camera, viewport) 부분이 startRendering() 으로 바뀐 것을 볼 수 있습니다.
만약 매 프레임 렌더시에 무언가를 하려면 다음과 같이 BasicView 의 render 함수를 오버라이드해서 우리가 구현할 수 있습니다.

package
{
    import flash.events.Event;

    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
 
    [SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
    public class BasicViewTest extends BasicView
    {
        public function BasicViewTest()
        {
            var sphere:Sphere = new Sphere();
            scene.addChild(sphere);
            startRendering();
        }

        override protected function onRenderTick(event:Event=null):void
        {
            // 여기서 추가적인 무엇인가를 수행
            renderer.renderScene(scene, camera, viewport);
        }

    }
}

onRenderTick 은 BasicView 클래스에 구현되어 있습니다만, 우리가 여기서 override 하여 우리만의 추가적인
기능을 부여할 수 있습니다.


이번엔 면(Plane)을 하나 만들어 빙글빙글 돌려 보겠습니다.



package
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    
    import org.papervision3d.materials.ColorMaterial; // 면에 입힐 재질 라이브러리
    import org.papervision3d.objects.primitives.Plane; // 면을 위한 라이브러리 

    [SWF(width="640", height="480", backgroundColor="#ffffff", frameRate="60")]
    public class HelloPV3D extends Sprite
    {
        private var viewport:Viewport3D;
        private var scene:Scene3D;
        private var camera:Camera3D;
        private var renderer:BasicRenderEngine;
        public var plane:Plane; // Plane(면) 클래스의 인스턴스변수 선언

        public function HelloPV3D()
        {
            viewport = new Viewport3D();
            addChild(viewport);
 
            scene = new Scene3D();
            camera = new Camera3D();
            renderer = new BasicRenderEngine();
 
            var material:ColorMaterial = new ColorMaterial(0x33ddff, 1); // 파란색 재질 생성
            material.doubleSided = true;

            plane = new Plane(material, 300, 300, 1, 1); // 위에서 만든 재질로 면을 생성
            scene.addChild(plane); // 씬에 면을 추가
 
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        private function enterFrameHandler(event:Event):void
        {
            plane.yaw(2); // 면을 2도씩 Y축을 기준으로돌린다
            renderer.renderScene(scene, camera, viewport);
        }
 
    }
}

위에서 x, y, z 축의 회전은 각각 pitch, yaw, roll 을 사용합니다. 즉,
plane.pitch(2);
plane.yaw(2);
plane.roll(2);
이렇게 다 써주면 x,y,z 축 모두를 기준으로 빙글빙글 돌겠죠.
Posted by 박동윤(http://www.cre8ive.kr) cre8ive

댓글을 달아 주세요


티스토리 툴바