손근질
[아두이노]RF모듈을 이용하여 마우스 데이터 받아보기
epari
2013. 5. 14. 14:28
개요>>
심심하고 따분할 때 누가 날 위로해줄 사람이 없다면 사용하지 않는 마우스를 무선 송신기로 변경시켜보자.
그리하면 마우스 조작으로 무선 수신기로 데이터를 받아서 수신쪽에서 이러쿵 저러쿵 조작이 가능하지 않을까?
준비물>>
1)무선 송수신 모듈
2)아두이노 송수신용 2개
3)기타 배선 및 헤더
방법>>
1) 무선송수신 모듈을 편리하게 사용하기 위하여 VirtualWire를 http://www.open.com.au/mikem/arduino/ 에서 1.5(2011년 6월21일 현재 최신)버전을 다운 받아서 arduino\libraries 폴더 안에 압축을 풀기.
2) P/S2 마우스 라이브러리를 http://thepotterproject.net/TPPNews/?page_id=180을 참고하여 같은 방법으로 라이브러리 등록.
이때 홈페이지 설명과 같이 ps2.h 에 include된 Proram.h를 Arduino.h로 변경할것.
아주 오래전 부품을 적출하기 위해 분해 해논 마우스 발견 케이스는 버리고 기판만 남아있다.
사실 이 마우스 기판이 정상작동 하는지는 잘 모르겠고, 발광 다이오드도 하나가 보이지 않는다.
어찌 되었든...
http://thepotterproject.net/TPPNews/?page_id=180 이곳에서 마우스 핀맵을 알수 있었다.
왼쪽부터 Vcc(5v), Gnd, data, sck, nc 테스트를 위해 배선을 버리고 헤더 납땜.
아두이노 소스는
http://cafe.naver.com/arduinostory/9850
세상 참 넓군.. 나와 같은 생각을 하다니..
수신측 아두이노 스케치
#include <VirtualWire.h>
#define RXpin 16
#define PW 10
// pin mapping to analog PWM
unsigned char FLPin=3;//Foward Left
unsigned char FRPin=5;//Foward Right
unsigned char BLPin=13;//Backward Left
unsigned char BRPin=11;//Backward Right
unsigned char FLPower=0;
unsigned char FRPower=0;
unsigned char BLPower=0;
unsigned char BRPower=0;
unsigned char BasePower=0;
signed char ElevatorToggle=0;//0 for stop 1 for down 2 for up
boolean EnterNoInput=false;
boolean Emergency = false;
boolean Landing = false;
unsigned int Elapsed =0;
unsigned int EntryMillis = 0;
signed char name;
signed char arg1;
signed char arg2;
void Balancing(signed char);
void NoInput();
void Shift();
void Scend();
void Elevator();
void SetMotorPower();
//use as global variable so no passing overhead -> faster
void setup(){
pinMode(PW,OUTPUT);
digitalWrite(PW,HIGH);
vw_set_rx_pin(RXpin);
vw_set_ptt_inverted(true);
vw_setup(2000); // Bits per sec
vw_rx_start();
Serial.begin(9600);
pinMode(FLPin, OUTPUT);
pinMode(FRPin, OUTPUT);
pinMode(BLPin, OUTPUT);
pinMode(BRPin, OUTPUT);
Serial.print("started");
}
void loop(){
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
EnterNoInput = false;
Emergency = false;
Landing = false;
Elapsed = 0;
name = buf[0];
arg1 = buf[1];
arg2 = buf[2];
Serial.print("name:");
Serial.print(name,DEC);
Serial.print(" arg1:");
Serial.print(arg1,DEC);
Serial.print(" arg2:");
Serial.print(arg2,DEC);
Serial.println("");
Shift();
Scend();
Elevator();
}
else
{//NoInput();
}
SetMotorPower();
delay(25);
}
//function will be called successively
//so the function only need to slow all motor down
//1 step at each call Give delay as it needs by caller
void Balancing(signed char val = 0)
{
BasePower>0 ? BasePower += val : 0;//zero?
FLPower = FRPower = BLPower = BRPower = BasePower;
}
//millis() to count elapsed time since board started
void NoInput()//called when there is no Input
{
if(EnterNoInput ==false)
{ EnterNoInput=true;
EntryMillis = millis();
}
else if(EnterNoInput == true)
{
Elapsed = millis()-EntryMillis;
if(Elapsed > 2000)//no input for 2 sec
{ Balancing(-1); delay(15);}//Give delay as it needs
else if(Elapsed > 200)//no input for 0.2 sec
{ Balancing(0); }
}
}
void Shift()
{
if(name == B00000001 && (arg1 != 0 || arg2 != 0))
{//it's shift command!
FLPower = FRPower = BLPower = BRPower = BasePower;
signed int TempResult = FLPower + arg1;
TempResult > 255 ? FLPower = 255 : 0;
TempResult < 0 ? FLPower = 0 : FLPower += arg1;
TempResult = BLPower + arg1;
TempResult > 255 ? BLPower = 255 : 0;
TempResult < 0 ? BLPower = 0 : BLPower += arg1;
TempResult = FRPower - arg1;
TempResult > 255 ? FRPower = 255 : 0;
TempResult < 0 ? FRPower = 0 : FRPower -= arg1;;
TempResult = BRPower - arg1;
TempResult > 255 ? BRPower = 255 : 0;
TempResult < 0 ? BRPower = 0 : BRPower -= arg1;;
TempResult = FLPower - arg2;
TempResult > 255 ? FLPower = 255 : 0;
TempResult < 0 ? FLPower = 0 : FLPower += arg2;
TempResult = FRPower - arg2;
TempResult > 255 ? FRPower = 255 : 0;
TempResult < 0 ? FRPower = 0 : FRPower += arg2;
TempResult = BRPower + arg2;
TempResult > 255 ? BRPower = 255 : 0;
TempResult < 0 ? BRPower = 0 : BRPower -= arg2;
TempResult = BLPower + arg2;
TempResult > 255 ? BLPower = 255 : 0;
TempResult < 0 ? BLPower = 0 : BLPower -= arg2;
name = arg1 = arg2 = 0;//prevent unintentional automatic moving
}
}
void Scend(){
if(name == B00000010 && (arg1 == 0 && arg2 != 0))
{
signed int TempResult = BasePower + arg2;
TempResult>255 ? BasePower = 255 : 0;
TempResult<0 ? BasePower = 0 : BasePower+=arg2;
FLPower = FRPower = BLPower = BRPower = BasePower;
}
}
void Elevator(){
if(name == B00000011 && (arg1 == 0 && arg2 == 1))
{
ElevatorToggle += 1;
ElevatorToggle %= 3;
}
}
void SetMotorPower(){
analogWrite(FLPin, FLPower);
analogWrite(FRPin, FRPower);
analogWrite(BLPin, BLPower);
analogWrite(BRPin, BRPower);
Serial.print("FL: ");
Serial.print(FLPower,DEC);
Serial.print("FR: ");
Serial.print(FRPower,DEC);
Serial.print("BL: ");
Serial.print(BLPower,DEC);
Serial.print("BR: ");
Serial.println(BRPower,DEC);
}
송신측 아두이노 스케치
#include <ps2.h>
#include <VirtualWire.h>
#define TXpin 9
#define PS2CLK 10
#define PS2DATA 8
PS2Mouse mouse(PS2CLK, PS2DATA);
////////////////////////////////////////////////////////////////
//int is signed 2byte data type
//char is signed 1byte data type
//casting (char) for sending as binary or itoa would be applied
unsigned char ShiftSensitivity=50; //1~127
unsigned char ScendSensitivity=10; //1~127
signed int cY1;
signed int cS1;
signed int cY2;
signed int cS2;
boolean sSwitch=false;
////////////////////////////////////////////////////////////////
//how to read 3 byte from RX side? read/read/read?
////////////////////////////////////////////////////////////////
//TX side Source Code
boolean Transfer(signed char *, signed char *, signed char *);
void Shift(MouseInfo *);
void Scend(MouseInfo *);
void Elevator(MouseInfo *);
void Sensitivity(MouseInfo *);
void setup()
{
vw_set_tx_pin(TXpin);
mouse.init();
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000);
Serial.begin(9600);
Serial.println("ready");
}
/*
* get a reading from the mouse and report it back to the
* host via the serial line.
*/
void loop()
{
MouseInfo mouseInfo;
mouse.getData(&mouseInfo);
Shift(&mouseInfo);
Scend(&mouseInfo);
Elevator(&mouseInfo);
Sensitivity(&mouseInfo);
}
boolean Transfer(signed char *Name, signed char *First, signed char *Second){
char data[3];
data[0]=*Name;
data[1]=*First;
data[2]=*Second;
boolean ret=vw_send((uint8_t *)data, 3);
vw_wait_tx();
Serial.print("name");
Serial.print(*Name);
Serial.print("First");
Serial.print(*First);
Serial.print("Second");
Serial.print(*Second);
Serial.println("");
return ret;
}
//call by reference syntax? should be corrected
void Shift(MouseInfo *m){
if((m->x != 0 || m->y != 0) && m->rightClick == 0 && sSwitch==false )
{
signed char name = 1;
signed char zero = 0;
signed int y = m->y/ShiftSensitivity;
signed int x = m->x/ShiftSensitivity;
signed char bytey = y>127 ? 127 : y;
bytey = y<-128 ? -128 : y;
signed char bytex = x>127 ? 127 : x;
bytex = x<-128 ? -128 : x;
if(m->middleClick == 1)
{//right angle move
abs(bytey)>=abs(bytex)? Transfer(&name,&zero,&bytey) : Transfer(&name,&bytex,&zero);
}
else Transfer(&name,&bytex,&bytey);//normal move
}
}
void Scend(MouseInfo *m){//cumulative on RX side
if((m->scroll != 0) && m->rightClick == 0 && sSwitch==false){
signed char name = 2;
signed char arg1 = 0;
//use int because it multiply
signed int scroll = m->scroll * ScendSensitivity;
signed char bytescroll = scroll>127 ? 127 : scroll;
bytescroll = scroll<-128 ? -128 : scroll;
Transfer(&name,&arg1,&bytescroll);
}
}
void Elevator(MouseInfo *m){//cyclic toggle on RX side : up/stop/down
if(m->leftClick != 0 && m->rightClick == 0 && sSwitch==false){
signed char name,arg1,arg2;
name = 3;
arg1 = 0;
arg2 = 1;
Transfer(&name,&arg1,&arg2);
}
}
void Sensitivity(MouseInfo *m){
if(m->rightClick == 1 && sSwitch==false){
sSwitch = true;
cY1 = m->cY;
cS1 = m->cScroll;
}else if(m->rightClick == 0 && sSwitch==true){
sSwitch = false;
cY2= m->cY;
cS2= m->cScroll;
ShiftSensitivity = abs(cY2-cY1);
ScendSensitivity = abs(cS2-cS1);
}
}