코코아팹은 누구나 창의적 아이디어를 현실로 만들어 낼 수 있도록
만들고, 공유하고, 배울 수 있는 터전이
되고자 합니다.
아이디와 비밀번호를 잊으셨나요?아이디 / 비밀번호 찾기
코코아팹 회원이 아니신가요? 회원가입
2014-09-01 15:53:39
NO | 부품명 | 수량 | 상세설명 |
1 | 아두이노 우노 R3 | 1 | 아두이노 |
2 | 눈차크 | 1 | 눈차크 |
3 | 눈차크 어뎁터 | 1 | 눈차크 어뎁터 |
부품명 | 아두이노 우노 R3 | 눈차크 | 눈차크 어뎁터 |
파트 |
#include <Wire.h> #include "Nunchuck.h" int offsetX, offsetY, offsetZ;
// 마우스가 중앙에 있을 때 0을 가져오기 위해 센서에 추가 하는 값 void setup(){ Serial.begin(57600); nunchuckSetPowerpins(); nunchuckInit(); // 초기화 핸드셰이크를 전송한다. nunchuckRead(); // 처음엔 무시한다. delay(50); } void loop(){ nunchuckRead(); delay(6); boolean btnC = nunchuckGetValue(wii_btnC); boolean btnZ = nunchuckGetValue(wii_btnZ); if(btnC) { offsetX = 127 - nunchuckGetValue(wii_accelX) ; offsetY = 127 - nunchuckGetValue(wii_accelY) ; } Serial.print("Data,"); printJoy(nunchuckGetValue(wii_joyX)); printJoy(nunchuckGetValue(wii_joyY)); printButton(nunchuckGetValue(wii_btnZ)); printAccel(nunchuckGetValue(wii_accelY), offsetY); printAccel(nunchuckGetValue(wii_accelX), offsetX); // 프로세싱에서 자료를 받아서 분석 하기 위해 "Data, 조이패드 X값, 조이패드 Y값, Z버튼, 가속도 Y값, 가속도 X값" 순서로 보낸다.
// 프로세싱에서는 아두이노에서 보낸 값을 " , " 로 나눠서 값을 저장한다.
Serial.println(); } void printAccel(int value, int offset){ // 가속도 값을 출력 하는 함수 Serial.print(adjReading(value, 127-50, 127+50, offset)); Serial.print(","); } void printJoy(int value){ // 조이패드 값을 출력하는 함수 Serial.print(adjReading(value,0, 255, 0)); Serial.print(","); } void printButton(int value){ // 버튼 값을 출력하는 함수 if( value != 0) value = 127; Serial.print(value,DEC); Serial.print(","); } int adjReading( int value, int min, int max, int offset){ // 받은 값의 범위를 재설정 해주는 함수 value = constrain(value + offset, min, max);
// 범위 한정(min값 보다 낮을경우 min값으로, max값보다 클 경우 max값으로 바꿔준다.) value = map(value, min, max, -127, 127); // 값의 범위 재설정 return value; }
// 출처 : 레시피로 배우는 아두이노 쿡북(저자 : 마이클 마골리스)
// 아두이노 쿡북에 있는 소스를 참고하여 수정, 추가하였습니다.
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import processing.serial.*;
import java.awt.Dimension;
Serial myPort; // Serial 클래스의 오브젝트를 생성한다.
arduMouse myMouse; // arduMouse 클래스의 오브젝트를 생성한다.
String message = null;
int maxDataFields = 7; // 최대 데이터 필드를 선언한다.(가속도계 3개, 버튼 2개, 조이스틱 축 2개)
boolean isStarted = false;
int accTemp, sightTemp, joyX, joyY, btnZ; // 아두이노에서 보낸 데이터 값이 여기에 저장이 된다.
void setup() {
size(260, 260);
PFont fontA = createFont("Arial.normal", 12);
textFont(fontA);
short portIndex = 0; // com 포트를 선택한다.(0번은 연결된 첫번째 포트)
String portName = Serial.list()[portIndex];
// 연결된 포트 리스트가 프로세싱에 출력이 된다. 이것을 보고 위에서 포트를 선택해 주면 된다.
println(Serial.list());
println(" Connecting to -> " + portName) ;
myPort = new Serial(this, portName, 57600);
myMouse = new arduMouse();
fill(0);
text("Start Google FS in the center of your screen", 5, 40);
text("Center the mouse pointer in Google earth", 10, 60);
text("Press and release Nunchuck Z button to play", 10, 80);
text("Press Z button again to pause mouse", 20, 100);
}
void draw() {
processMessages();
if (isStarted == false) {
if ( btnZ != 0) {
println("Release button to start");
do{ processMessages();}
while(btnZ != 0);
myMouse.mousePress(InputEvent.BUTTON1_MASK); // 눈차크에 Z버튼을 눌렀을 경우 눈차크 인식을 시작한다.
isStarted = true;
}
}
else
{
if ( btnZ != 0) {
isStarted = false;
background(204);
text("Release Z button to play", 20, 100);
print("Stopped, ");
}
else{
myMouse.move(joyX, joyY); // 조이스틱의 X, Y의 값을 이용해 마우스를 조정한다.
myMouse.speedCon(accTemp); // 눈차크 가속도의 Y축 값을 이용하여 시뮬레이터의 속도를 조정한다.
myMouse.sight(sightTemp); // 눈차크 가속도의 X축 값을 이용하여 시뮬레이터의 방향을 조정한다.
fill(0);
stroke(255, 0, 0);
background(#8CE7FC);
ellipse(127+joyX, 127+joyY, 4, 4);
}
}
}
void processMessages() {
while (myPort.available () > 0) {
message = myPort.readStringUntil(10);
if (message != null) {
String [] data = message.split(","); // 콤마(,) 를 이용하여 받은 데이터를 자른다.
if ( data[0].equals("Data"))// 자른 데이터중 제일 처음이 Data일 경우
{
try {
joyX = Integer.parseInt(data[1]); // 조이스틱의 X값
joyY = Integer.parseInt(data[2]); // 조이스틱의 Y값
btnZ = Integer.parseInt(data[3]); // Z버튼
accTemp = Integer.parseInt(data[4]); // 눈차크 가속도 Y축값
sightTemp = Integer.parseInt(data[5]); // 눈차크 가속도 X축값
}
catch (Throwable t) {
println(".");
}
}
}
}
}
class arduMouse {
Robot myRobot;
static final short rate = 4;
int centerX, centerY;
arduMouse() {
try {
myRobot = new Robot();
}
catch (AWTException e) {
e.printStackTrace();
}
Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
centerY = (int)screen.getHeight() / 2 ;
centerX = (int)screen.getWidth() / 2;
}
void move(int offsetX, int offsetY) { // 주어진 값으로 마우스를 이동한다.(조이스틱 x, y 값)
myRobot.mouseMove(centerX + (rate* offsetX), centerY - (rate * offsetY));
}
void mousePress( int button) { // Z버튼이 눌렸을 경우 마우스 클릭을 한다.
myRobot.keyRelease(KeyEvent.VK_SHIFT);
myRobot.mousePress(button) ;
}
void speedCon(int accTemp){ // 눈차크 가속도 Y축의 값을 기준으로 30이 넘어갈경우 가속, 0보다 낮을경우 감속을 한다.
// 가속일 경우 키보드 Page_UP키 감속일 경우 Page_Down키를 누르면 된다.
// keyPress함수를 사용할 경우 키가 계속 눌러진 상태로 있기 때문에 꼭 keyRelease함수를 사용해야한다.
if(accTemp > 30){
myRobot.keyRelease(KeyEvent.VK_PAGE_DOWN);
myRobot.keyPress(KeyEvent.VK_PAGE_UP);
}
else if(accTemp < 0){
myRobot.keyRelease(KeyEvent.VK_PAGE_UP);
myRobot.keyPress(KeyEvent.VK_PAGE_DOWN);
}
}
void sight(int sightTemp){ // 눈차크 가속도 X축의 값을 기준으로 100보다 크면 오른쪽으로, 100보다 작으면 왼쪽으로 이동한다.
// 키보드 입력은 쉬프트 + 오른쪽 화살표, 쉬프트 + 왼쪽 화살표
if(sightTemp >= 100){
myRobot.keyRelease(KeyEvent.VK_SHIFT);
myRobot.keyRelease(KeyEvent.VK_LEFT);
myRobot.keyPress(KeyEvent.VK_SHIFT);
myRobot.keyPress(KeyEvent.VK_RIGHT);
}
else if(sightTemp <= -100){
myRobot.keyRelease(KeyEvent.VK_SHIFT);
myRobot.keyRelease(KeyEvent.VK_RIGHT);
myRobot.keyPress(KeyEvent.VK_SHIFT);
myRobot.keyPress(KeyEvent.VK_LEFT);
}
else{
myRobot.keyRelease(KeyEvent.VK_SHIFT);
myRobot.keyRelease(KeyEvent.VK_LEFT);
myRobot.keyRelease(KeyEvent.VK_RIGHT);
}
}
}
/* * Nunchuck.h * Arduino library to interface with wii Nunchuck */ #ifndef Nunchuck_included #define Nunchuck_included // identities for each field provided by the wii nunchuck enum nunchuckItems { wii_joyX, wii_joyY, wii_accelX, wii_accelY, wii_accelZ, wii_btnC, wii_btnZ, wii_ItemCount }; // uses pins adjacent to I2C pins as power & ground for Nunchuck void nunchuckSetPowerpins(); // initialize the I2C interface for the nunchuck void nunchuckInit(); // Request data from the nunchuck void nunchuckRequest(); // Receive data back from the nunchuck, // returns true if read successful, else false bool nunchuckRead(); // Encode data to format that most wiimote drivers except char nunchuckDecode (uint8_t x); // return the value for the given item int nunchuckGetValue(int item); #endif
/* * Nunchuck.cpp * Arduino library to interface with wii Nunchuck */ #include "Arduino.h" // Arduino defines #include "Wire.h" // Wire (I2C) defines #include "Nunchuck.h" // Defines for this library // defines for standard Arduino board (use 19 and 18 for mega) const int vccPin = 17; // +v and gnd provided through these pins const int gndPin = 16; const int dataLength = 6; // number of bytes to request static byte rawData[dataLength]; // array to store nunchuck data // uses pins adjacent to I2C pins as power & ground for Nunchuck void nunchuckSetPowerpins() { pinMode(gndPin, OUTPUT); // set power pins to the correct state pinMode(vccPin, OUTPUT); digitalWrite(gndPin, LOW); digitalWrite(vccPin, HIGH); delay(100); // wait for power to stabilize } // initialize the I2C interface for the nunchuck void nunchuckInit() { Wire.begin(); // join i2c bus as master Wire.beginTransmission(0x52);// transmit to device 0x52 Wire.write((byte)0x40); // sends memory address Wire.write((byte)0x00); // sends sent a zero. Wire.endTransmission(); // stop transmitting } // Request data from the nunchuck void nunchuckRequest() { Wire.beginTransmission(0x52);// transmit to device 0x52 Wire.write((byte)0x00);// sends one byte Wire.endTransmission();// stop transmitting } // Receive data back from the nunchuck, // returns true if read successful, else false bool nunchuckRead() { byte cnt=0; Wire.requestFrom (0x52, dataLength);// request data from nunchuck while (Wire.available ()) { byte x = Wire.read(); rawData[cnt] = nunchuckDecode(x); cnt++; } nunchuckRequest(); // send request for next data payload if (cnt >= dataLength) return true; // success if all 6 bytes received else return false; //failure } // Encode data to format that most wiimote drivers except char nunchuckDecode (byte x) { return (x ^ 0x17) + 0x17; } // return the value for the given item int nunchuckGetValue(int item) { if( item <= wii_accelZ) return (int)rawData[item]; else if(item == wii_btnZ) return bitRead(rawData[5], 0) ? 0: 1; else if(item == wii_btnC) return bitRead(rawData[5], 1) ? 0: 1; }
short portIndex = 0; // com 포트를 선택한다.(0번은 연결된 첫번째 포트) String portName = Serial.list()[portIndex];
// 연결된 포트 리스트가 프로세싱에 출력이 된다. 이것을 보고 위에서 포트를 선택해 주면 된다. println(Serial.list()); println(" Connecting to -> " + portName) ; myPort = new Serial(this, portName, 57600);
myMouse.move(joyX, joyY); // 조이스틱의 X, Y의 값을 이용해 마우스를 조정한다. myMouse.speedCon(accTemp); // 눈차크 가속도의 Y축 값을 이용하여 시뮬레이터의 속도를 조정한다. myMouse.sight(sightTemp); // 눈차크 가속도의 X축 값을 이용하여 시뮬레이터의 방향을 조정한다.
while (myPort.available () > 0) { message = myPort.readStringUntil(10); if (message != null) { String [] data = message.split(","); // 콤마(,) 를 이용하여 받은 데이터를 자른다. if ( data[0].equals("Data"))// 자른 데이터중 제일 처음이 Data일 경우 { try { joyX = Integer.parseInt(data[1]); // 조이스틱의 X값 joyY = Integer.parseInt(data[2]); // 조이스틱의 Y값 btnZ = Integer.parseInt(data[3]); // Z버튼 accTemp = Integer.parseInt(data[4]); // 눈차크 가속도 Y축값 sightTemp = Integer.parseInt(data[5]); // 눈차크 가속도 X축값 } catch (Throwable t) { println("."); } } } }
void speedCon(int accTemp){ // 눈차크 가속도 Y축의 값을 기준으로 30이 넘어갈경우 가속, 0보다 낮을경우 감속을 한다.
// 가속일 경우 키보드 Page_UP키 감속일 경우 Page_Down키를 누르면 된다.
// keyPress함수를 사용할 경우 키가 계속 눌러진 상태로 있기 때문에 꼭 keyRelease함수를 사용해야한다. if(accTemp > 30){ myRobot.keyRelease(KeyEvent.VK_PAGE_DOWN); myRobot.keyPress(KeyEvent.VK_PAGE_UP); } else if(accTemp < 0){ myRobot.keyRelease(KeyEvent.VK_PAGE_UP); myRobot.keyPress(KeyEvent.VK_PAGE_DOWN); } } void sight(int sightTemp){ // 눈차크 가속도 X축의 값을 기준으로 100보다 크면 오른쪽으로, 100보다 작으면 왼쪽으로 이동한다.
// 키보드 입력은 쉬프트 + 오른쪽 화살표, 쉬프트 + 왼쪽 화살표 if(sightTemp >= 100){ myRobot.keyRelease(KeyEvent.VK_SHIFT); myRobot.keyRelease(KeyEvent.VK_LEFT); myRobot.keyPress(KeyEvent.VK_SHIFT); myRobot.keyPress(KeyEvent.VK_RIGHT); } else if(sightTemp <= -100){ myRobot.keyRelease(KeyEvent.VK_SHIFT); myRobot.keyRelease(KeyEvent.VK_RIGHT); myRobot.keyPress(KeyEvent.VK_SHIFT); myRobot.keyPress(KeyEvent.VK_LEFT); } else{ myRobot.keyRelease(KeyEvent.VK_SHIFT); myRobot.keyRelease(KeyEvent.VK_LEFT); myRobot.keyRelease(KeyEvent.VK_RIGHT); } }
판다마니아