Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 177 → Rev 178

/MoteCtrl/Sources/fc_comm.c
0,0 → 1,87
/*fc_comm.c allows encoding and decoding of the serial protocol, the
FlightCtrl uses.
The encode and decode algorithms are part of the FlightCtrl software and
are therefore written by the MikroKopter team. */
 
//Include header files, which provide resources, fc_comm.c needs:
#include "pc_serial_port.h"
 
#include "fc_comm.h"
 
//Global variables:
char tx_buffer[150]; //Transmit Buffer (SendOutData places coded frame here)
char rx_buffer[150]; //Receive Buffer (Decode64 reads this buffer)
 
 
 
/*AddCRC calculates two byte sized CRC checksums for the encoded frame and
adds them to the end of the data-frame. Additionally it adds an \r escape
sequence to the end of the frame (defined by the Mikrokopter-Protocoll) */
void AddCRC(unsigned int frame_length) { //length of #,adr,cmd,data
unsigned int tmpCRC = 0;
unsigned int i;
 
for (i=0; i < frame_length;i++)
{
tmpCRC += tx_buffer[i];
}
 
tmpCRC %= 4096;
tx_buffer[i++] = '=' + tmpCRC / 64;
tx_buffer[i++] = '=' + tmpCRC % 64;
tx_buffer[i++] = '\r';
 
}
 
 
void SendOutData(unsigned char cmd,unsigned char addr, unsigned char *snd, unsigned char len) {
 
unsigned int pt = 0;
unsigned char a,b,c;
unsigned char ptr = 0;
 
tx_buffer[pt++] = '#'; // Start-Byte
tx_buffer[pt++] = 'a' + addr; // Adress
tx_buffer[pt++] = cmd; // Command
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
tx_buffer[pt++] = '=' + (a >> 2);
tx_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
tx_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
tx_buffer[pt++] = '=' + ( c & 0x3f);
}
 
AddCRC(pt);
 
sendStringToCom(tx_buffer, pt+3); //whole frame length is pt+3
} //#,adr,cmd,data ; crc1,crc2,\r
 
 
void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max) {
 
unsigned char a,b,c,d;
unsigned char ptr = 0;
unsigned char x,y,z;
 
while(len)
{
a = rx_buffer[ptrIn++] - '=';
b = rx_buffer[ptrIn++] - '=';
c = rx_buffer[ptrIn++] - '=';
d = rx_buffer[ptrIn++] - '=';
 
if(ptrIn > max - 2) break; // dont process more data than recieved
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
}
/MoteCtrl/Sources/fc_comm.h
0,0 → 1,7
 
//Function Prototypes of fc_comm.c, which are provided to interface with,
//respectively to communicate with the Flightcontrol:
void SendOutData(unsigned char cmd,unsigned char addr, unsigned char* snd, unsigned char len);
 
//not yet used (decoding of received data):
//void Decode64(unsigned char* ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max);
/MoteCtrl/Sources/main.c
0,0 → 1,207
/*
* *****MoteCtrl*****
* written by Andreas Benzin (aka Alpin)
*
* lets you control your MikroKopter with a Wiimote!
*
*
* Copyright December 2008
*
* Credits & Thx:
* - Holger & Ingo for the MikroKopter Project (www.mikrokopter.de)
* - ExternalControl implementation of the FlightControl
* - Ligi for RIDDIM, proof of external control concept
* - Documentation of the MK's SerialProtocol (www.mikrokopter.de/ucwiki/en/SerialProtocol)
* - Michael Laforest for the wiiuse API (www.wiiuse.net)
*
*
* http://www.mikrokopter.de/ucwiki/en/MoteCtrl
*/
 
/*
*****Use at your own risk! No warranty. Only for private usage.*****
 
#LICENSE: Released under the GNU General Public License Version 2 or
(at your option) a later version of this license.
For further details see <www.gnu.org/licenses/>.
 
#DISCLAIMER: Use this project at your own risk!
No warrenty.
Only for private usage.
 
***** See READ_ME_FIRST.txt for further details about MoteCtrl *****
*/
 
/*
Compiler & Linker Porperties:
Set "Character Set"-CompilerFlag to "Not Set" or "Multi Byte Character Set" to
avoid Errors about Windows API functions that can handle Unicode paramters.
In Visual Studio: Properties of Project -> Configuration Properties -> General
*/
 
/*
When compiling, don't forget to link wiiuse.lib (interface to the wiiuse.dll)
In Visual Studio: Copy wiiuse.lib & wiiuse.dll to project directory.
Afterwards: Properties of Project -> Configuration Properties -> Linker
-> Input -> add "wiiuse.lib" to additional dependencies
*/
 
/*
To avoid problems with dependencies on other windows machines, link the used
windows DLLs statically to the project.
In Visual Studio: Properties of Project -> Config. Properties -> C/C++
-> Code Generation -> set "Runtime Library" to Multi-Threaded (/MT)
*/
 
/*Main.c merges all the resources provided by the header files to a functional
program. The follwing "includes" include all the needed and used headers (which
provide the resources, like fuctions, wrappers, structs, etc. main.c uses)
*/
 
/**********Main Header*********/
//OS libs:
#include <windows.h> //Windows API, for API macros, constants, etc. (like stdlib.h)
#include <stdio.h> //Standard I/O (printf for instance)
 
//MoteCtrl libs:
#include "pc_serial_port.h" //interface with a PC's serial port
#include "fc_comm.h" //encode & send data to FlightControl
#include "wiimote.h" //interface with the wiimote connected via Bluetooth
 
//#include "main.h"
 
 
//Pretty Text output: (==fun ;)
void prettyText(char* string) {
int printed;
int i;
//pretty text output:
printed = printf("*****%s", string);
 
for (i=0;i<(65-printed);i++) {
printf("*");
}
printf("\n");
}
 
 
int main(int argc, char* argv[]) {
//temps & counters
int tmp;
int tmp1;
//int i;
//Print title:
printf("\n"); prettyText("*"); printf("*v0.1\n"
"*\t****MoteCtrl**** written by Alpin\n"
"*\tlets you control your MikroKopter with a Wiimote!\n*\n");
prettyText("*"); printf("\n");
 
//**********Serial COM Port init & config:
prettyText("COM Port init");
printf("Serial COM Port you want to use to connect to the MikroKopter\n"
"(only type the number then hit enter):\n");
 
scanf_s("%d", &tmp); //read a decimal from terminal
tmp1 = init_com_port(tmp); //initialize & config COM port tmp
//init_com_port returned successfull?
if( tmp1 == EXIT_FAILURE ) {
printf("\n***COM%i Initilizaition/Configuration failed\n\n", tmp);
prettyText("COM Port Init FAILED!");
printf("exiting MoteCtrl...\n");
Sleep(1000);
return EXIT_FAILURE;
}
else { prettyText("Init & config of COM DONE!"); printf("\n\n"); }
 
//**********Wiimote init & config:
prettyText("Wiimote Init");
Sleep(1000);
 
tmp = init_wiimote (); //initialize wiimote
//was init_wiimote successfull?
if (tmp == EXIT_FAILURE ) {
prettyText("Wiimote Init FAILED!");
printf("exiting MoteCtrl...\n");
Sleep(1000);
return EXIT_FAILURE;
}
else { prettyText("Wiimote Init DONE!"); printf("\n\n"); }
/* Does not work yet:
if(mote[0]->exp.type == EXP_NUNCHUK) {printf("Nunchuck plugged in!"); }
else { printf("No Nunchuck extension found!"); }
*/
 
 
/***********Main: reading acc-values of wiimote, sending them as external-
control data to the MikroKopter's FlightControl: */
/* This is the Core of MotionCtrl, since it transfers the Wiimote data via the
external control srtuct and the serial protocol encoding to the
FlightCtrl.*/
 
//Initialize entire ExternControl-struct with zeros
SecureZeroMemory(&ExternControl, sizeof(struct str_ExternControl));
 
//Activate the ExternalControl
//gas = 0; //init gas value
ExternControl.Config = 1;
 
//Main loop, "virtual" polling the wiimote events:
while (1) {
//wiiuse_poll returns the number of wiimotes, at which an event occured:
if (wiiuse_poll(mote, MAX_WIIMOTES)) {
switch (mote[0]->event) { //what type of event happened?
 
case WIIUSE_EVENT:
//a generic event occured!
/*Call function, which does the following: transferring
the wiimote data to the ExternalControl struct: */
handle_event(mote[0]);
 
//Send the (by handle_event) updated ExternControl struct
//to the FlightCtrl:
SendOutData('b', 1, (unsigned char *) &ExternControl, sizeof(struct str_ExternControl));
break;
 
default:
break;
}
}
}
 
/* Some early tests
muh:
i=0;
while (1) {
//externcon typedeffen
SendOutData('b', 1, (unsigned char *) &ExternControl, sizeof(struct str_ExternControl));
//i++;
}
//sendStringToCom("#bR@T\r",6); //send reset
i=0;
while(i<255) {
tmp = getCharFromCom(&b);
if (tmp) {
printf("%c", b);
i++;
}
}
goto muh;
 
*/
 
 
return EXIT_SUCCESS;
}
/MoteCtrl/Sources/pc_serial_port.c
0,0 → 1,132
/* This file is part of MoteCtrl
http://www.mikrokopter.de/ucwiki/en/MoteCtrl
*/
 
//Include header files, which provide resources, pc_serial_port.c needs:
#include <windows.h> //Windows API, to interface with the serial port
#include <stdio.h> //Standard I/O (printf for instance)
 
#include "pc_serial_port.h"
 
 
/*
Compiler & Linker Porperties:
Set "Character Set"-CompilerFlag to "Not Set" or "Multi Byte Character Set" to
avoid Errors about Windows API functions that can handle Unicode paramters.
In Visual Studio: Properties of Project -> Configuration Properties -> General
*/
 
 
HANDLE hCom; //Handle, which contains inf about the opened Device File
//(the opened COM-Port, returned by CreateFile function)
 
//Initialize & Configure COMx-Port
//return value: EXIT_FAILURE=1, EXIT_SUCCESS=0 (stdlib macros)
int init_com_port(int comNumber) {
DCB dcb; //Device Control Block, contains Configuration for COM-Port
char comPort[5] = {'C','O','M'}; //Number and String Terminator to be added
int fSuccess; //Stores inf about file-actions (action succeeded or failed)
COMMTIMEOUTS timeouts; //Struct, which stores inf about the timeout
//behaviour of the COM-Port
 
//Get the Com-Port Number:
comPort[3] = 48 + comNumber; //COMx (x is ASCII coded)
comPort[4] = 0; //add string Terminator 'NUL'
 
//Create Device File, initialize serial Port:
hCom = CreateFile( comPort, //open COMx Device (pointer to comPort-String)
GENERIC_READ | GENERIC_WRITE, //write/read permisions
0, // must be opened with exclusive-access
NULL, // default security
OPEN_EXISTING, // must use OPEN_EXISTING
0, // no overlapping
NULL // hTemplate must be NULL for comm devices
);
 
//Check, if CreateFile succeeded:
if (hCom == INVALID_HANDLE_VALUE) {
printf ("***ERR: CreateFile failed with error %d.\n", GetLastError());
return EXIT_FAILURE;
}
 
//Get the currently active Device Control Block (DCB) for the COMx:
SecureZeroMemory(&dcb, sizeof(DCB)); //initialize entire dcb-struct with zeros
dcb.DCBlength = sizeof(DCB);
fSuccess = GetCommState(hCom, &dcb); //write the current configuration to
//our dcb-struct
 
//GetCommState returns 0, if error occured while getting the DCB
if (!fSuccess) {
printf ("***ERR: GetCommState failed with error %d.\n", GetLastError());
return EXIT_FAILURE;
}
 
/*Change the values of the obtained dcb-struct to match the config of the
*Mikrokopter. Currently the FlightControl communicates at:
*57600 Baud (bps), 8 Data bits, no parity bit, 1 stop bit */
 
dcb.BaudRate = CBR_57600; // Set Baudrate
dcb.ByteSize = 8; // data size, transmit and receive
dcb.Parity = NOPARITY; // no parity bit
dcb.StopBits = ONESTOPBIT; // one stop bit
//Send reconfigured dcb back to COMx Device-File:
fSuccess = SetCommState(hCom, &dcb);
//SetCommState returns a 0, if error occured while setting the DCB for COMx
if (!fSuccess) {
printf ("***ERR: SetCommState failed with error %d.\n", GetLastError());
return EXIT_FAILURE;
}
 
//Configure the Read-Timeout behaviour of the initialized COMx-Port:
 
/* The following Read-Timeout config determines the behaviour of the
ReadFile cmd (applied to the initialized COMx-Port):
If a Byte is in the Hardware UART-Buffer of the initialized COM-Port and
the ReadFile function is called, this byte is read. If theres no byte in
the UART-InputBuffer and the ReadFile function is called, the ReadFile
function will return *immediatly* (BytesRead parameter is zero then).
*/
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
//Send the Timeout-Config to the COM-Port:
fSuccess = SetCommTimeouts (hCom, &timeouts);
//Check, if setting the timeout-settings was successfull:
if(!fSuccess) {
printf("***ERR: SetCommTimeouts failed with error %d.\n", GetLastError());
return EXIT_FAILURE;
}
 
 
//Initialization & Configuration of COMx done!
return EXIT_SUCCESS;
}
 
 
//Function which reads 1 Byte of the Rx-Buffer of the initialized COM-Port:
//Return value: Number of the bytes read (should be 0 or 1)
int getCharFromCom (char* inputBuffer) {
 
int numOfBytesRead;
ReadFile (hCom, inputBuffer, 1, &numOfBytesRead, NULL);
//read char is stored in the passed char-buffer
 
return numOfBytesRead;
}
 
 
//Function which writes [length] Byte to the Tx-Buffer of the initialized COM-Port:
//Returns something>0 if write failed, 0 if successfull
int sendStringToCom (char* toSend, int length) {
int numOfBytesWritten;
 
//write char to which the passed char-pointer points to
return WriteFile (hCom, toSend, length, &numOfBytesWritten, NULL);
}
/MoteCtrl/Sources/pc_serial_port.h
0,0 → 1,5
 
//Function Prototypes of pc_serial_port.c :
int init_com_port(int comNumber);
int getCharFromCom(char* inputBuffer);
int sendStringToCom(char* toSend, int length);
/MoteCtrl/Sources/wiimote.c
0,0 → 1,186
/* This file is part of MoteCtrl
http://www.mikrokopter.de/ucwiki/en/MoteCtrl
*/
 
#include <stdio.h> //I/O functions
#include <windows.h> //like stdlib.h
//#include "wiiuse.h" //the wiiuse lib to communicate with the wiimote
 
#include "wiimote.h"
 
/*Nunchuck struct, main.c don't needs this, only wiimote.c needs this
in the handle_event function */
struct nunchuk_t* nc;
 
 
int init_wiimote (void) {
 
int tmp;
/*Initialize / create one Wiimote handle:
wiiuse_init is creating the corresponding wiimote struct and returns
a pointer to the created typedefed struct */
mote = wiiuse_init(MAX_WIIMOTES);
 
/*Now connect to the wiimote, that should be in discovery mode (all 4 leds
should be blinking, after you activated the Bluetooth HID service
--> means: "I'm in discovery mode, searching for a Wii").
wiiuse_find will scan and connect the number of wiimotes passed.
The information about the connected wiimote will be stored in the
passed wiimote struct. */
printf("\nAutodetecting your Bluetooth Stack (like Blue Soleil for instance)\n"
"Scanning for available Wiimotes...\n"
"(make sure BT HID service is running and the 4 LEDs of the Wiimote are blinking)\n\n");
 
tmp = wiiuse_find(mote, MAX_WIIMOTES, 8); //8 sec timeout
if(tmp == 0) {
printf("***ERR: Couldn't find Bluetooth stack / No Wiimote found\n"
"Bluetooth stack supported by wiiuse? HID service running?\n"
"Wiimote in discovery mode (all 4 LED's blinking)?\n\n");
return EXIT_FAILURE;
}
else { printf("\n***Wiimote found, trying to connect...\n\n"); }
//for backup (since wiiuse_find already connected) call wiiuse_connect:
tmp = wiiuse_connect(mote, MAX_WIIMOTES);
if(tmp == 0) {
printf("***ERR:Couldn't establish connection with found Wiimote\n\n");
return EXIT_FAILURE;
}
else { printf("***Connection to Wiimote established!\n\n"); }
 
 
//Wiimote is connected, everything could be done now
 
//Do a bit of fun:
 
wiiuse_rumble(mote[0], 1); //switch rumble on
 
//blinking with leds ;)
wiiuse_set_leds(mote[0], WIIMOTE_LED_1);
Sleep(100);
wiiuse_set_leds(mote[0], WIIMOTE_LED_NONE);
wiiuse_set_leds(mote[0], WIIMOTE_LED_2);
Sleep(100);
wiiuse_set_leds(mote[0], WIIMOTE_LED_NONE);
wiiuse_set_leds(mote[0], WIIMOTE_LED_3);
Sleep(100);
wiiuse_set_leds(mote[0], WIIMOTE_LED_NONE);
wiiuse_set_leds(mote[0], WIIMOTE_LED_4);
Sleep(100);
wiiuse_set_leds(mote[0], WIIMOTE_LED_NONE);
wiiuse_rumble(mote[0], 0); //switch rumble off
/*if there happens no LED change event (or some event) after rumble-turn-off,
the rumble-turn-off has no effect (seems to be a bug in the wiiuse API) */
wiiuse_set_leds(mote[0], WIIMOTE_LED_1);
 
Sleep(1000); //wait a sek to let the rumble vibe off
//do not press any buttons in that time!
//Avtivate the motion sensing feature of the wiimote:
wiiuse_motion_sensing(mote[0], 1);
 
 
return EXIT_SUCCESS;
}
 
 
int check_nunchuck(void) {
if(mote[0]->exp.type){
return 1;
}
else { return 0; }
}
 
 
//write Disconnect Wrapper ?
//wiiuse_disconnect(mote[0]);
 
 
/*This Subroutine is called, when the wiimote sends a generic event, like
a pushed button or the tilt changing by at least 0.5 degrees:
(it passes the wiimote data to the ExternalControl struct) */
void handle_event(struct wiimote_t* wm) {
 
/***** Button and tilt-sensor assignments for the WIIMOTE: *****/
 
/*GAS: (better use the nunchuck buttons to control the gas, since the
wiimotes tilt sensor is very sensitive and when pressing buttons on
the wiimote you atomatically change the state of the tilt)*/
 
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_HOME)) { //reset gas value to 0
ExternControl.Gas = 0; //(be careful with that!)
printf("\n***************Resetting GAS to ZERO!***************\n\n");
}
 
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_UP)) {
if (ExternControl.Gas < 240) { //overflow protection, max gas limit
ExternControl.Gas++; //increment gas value
}
}
 
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) {
if (ExternControl.Gas > 0) { //underflow protection (0-- = 255!!!GAS)
ExternControl.Gas--; //decrement gas value
}
}
//NICK & ROLL:
if( (wm->orient.roll > 127.0) || //overrun protections
(wm->orient.roll < -127.0) ||
(wm->orient.pitch > 127.0) ||
(wm->orient.pitch < -127.0))
{ return; }
else {
/*Associate the degree-Values of the wiimotes tilt sensor to the
corresponding ExternalControl struct values: */
ExternControl.Nick = (signed char) wm->orient.pitch;
ExternControl.Roll = -( (signed char) wm->orient.roll );
}
 
/***** Button and joystick assignments for the NUNCHUCK extension: *****/
nc = (nunchuk_t*)&mote[0]->exp.nunchuk;
//GAS:
if (IS_JUST_PRESSED(nc, NUNCHUK_BUTTON_C)) {
if (ExternControl.Gas < 240) { //overflow protection, max gas limit
ExternControl.Gas++; //increment gas value
}
}
 
if (IS_JUST_PRESSED(nc, NUNCHUK_BUTTON_Z)) {
if (ExternControl.Gas > 0) { //underflow protection (0-- = 255!!!GAS)
ExternControl.Gas--; //decrement gas value
}
}
//GIER:
if( (nc->js.ang > 0.0) && (nc->js.ang < 180) ) {
/* Nunchuck joystick is pressed to the right half, means
gier with the MikroKopter to the right: */
ExternControl.Gier = (signed char) (nc->js.mag * 100);
}
 
if( (nc->js.ang > 180) ) {
/* Nunchuck joystick is pressed to the left half, means
gier with the MikroKopter to the left: */
ExternControl.Gier = -(signed char) (nc->js.mag * 100);
}
 
 
//DEBUG Output: Print ExternControl status
printf("Gas: %3d Gier: %4d Nick: %4d Roll: %4d \n",
ExternControl.Gas, ExternControl.Gier, ExternControl.Nick, ExternControl.Roll);
 
}
/*
TODO: bei connectionabbruch (ext.config=0),
ctrl+q / ctrl+x -> abbruch (disconnect, ext.config=0)
*/
/MoteCtrl/Sources/wiimote.h
0,0 → 1,35
 
#include "wiiuse.h" //main.c also needs this (next to wiimote.c)
//wiiuse is a library to interface with the Wiimote
//and written by Michael Laforest
 
#define MAX_WIIMOTES 1 //Has to be 4; at first I tested it with 1, because
//only 1 Wiimote is needed. But some functions do not
//work then, so seems to be a bug in the wiiuse API.
 
//ExternalControl struct, which is send to the MikroKopter:
struct str_ExternControl
{
unsigned char Digital[2]; //two 1/0-buttons, not used atm
unsigned char RemoteButtons; // ? something to control the lcd menues?!
signed char Nick;
signed char Roll;
signed char Gier;
unsigned char Gas; //gas value is limited (in the fc sw) to the gas *stick* value
signed char Hight; //sets the hight for the barometric-hight-sensor
unsigned char free; //not used atm
unsigned char Frame; //value, which is send back by the fc for confirmation
unsigned char Config; //if set to 1 the ExternControl is set active
};
struct str_ExternControl ExternControl; //create an instance of the struct
 
 
//Global Variables:
wiimote** mote; //create a wiimote handle/identifier pointerarray
 
 
//Function Prototypes offered:
int init_wiimote (void);
void handle_event(struct wiimote_t* wm);
int check_nunchuck(void);
/MoteCtrl/Sources/wiiuse.dll
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/MoteCtrl/Sources/wiiuse.dll
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/MoteCtrl/Sources/wiiuse.h
0,0 → 1,653
/*
* wiiuse
*
* Written By:
* Michael Laforest < para >
* Email: < thepara (--AT--) g m a i l [--DOT--] com >
*
* Copyright 2006-2007
*
* This file is part of wiiuse.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Header$
*
*/
 
/**
* @file
*
* @brief API header file.
*
* If this file is included from inside the wiiuse source
* and not from a third party program, then wiimote_internal.h
* is also included which extends this file.
*/
 
#ifndef WIIUSE_H_INCLUDED
#define WIIUSE_H_INCLUDED
 
#ifdef _WIN32
/* windows */
#include <windows.h>
#else
/* nix */
#include <bluetooth/bluetooth.h>
#endif
 
#ifdef WIIUSE_INTERNAL_H_INCLUDED
#define WCONST
#else
#define WCONST const
#endif
 
/* led bit masks */
#define WIIMOTE_LED_NONE 0x00
#define WIIMOTE_LED_1 0x10
#define WIIMOTE_LED_2 0x20
#define WIIMOTE_LED_3 0x40
#define WIIMOTE_LED_4 0x80
 
/* button codes */
#define WIIMOTE_BUTTON_TWO 0x0001
#define WIIMOTE_BUTTON_ONE 0x0002
#define WIIMOTE_BUTTON_B 0x0004
#define WIIMOTE_BUTTON_A 0x0008
#define WIIMOTE_BUTTON_MINUS 0x0010
#define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020
#define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040
#define WIIMOTE_BUTTON_HOME 0x0080
#define WIIMOTE_BUTTON_LEFT 0x0100
#define WIIMOTE_BUTTON_RIGHT 0x0200
#define WIIMOTE_BUTTON_DOWN 0x0400
#define WIIMOTE_BUTTON_UP 0x0800
#define WIIMOTE_BUTTON_PLUS 0x1000
#define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000
#define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000
#define WIIMOTE_BUTTON_UNKNOWN 0x8000
#define WIIMOTE_BUTTON_ALL 0x1F9F
 
/* nunchul button codes */
#define NUNCHUK_BUTTON_Z 0x01
#define NUNCHUK_BUTTON_C 0x02
#define NUNCHUK_BUTTON_ALL 0x03
 
/* classic controller button codes */
#define CLASSIC_CTRL_BUTTON_UP 0x0001
#define CLASSIC_CTRL_BUTTON_LEFT 0x0002
#define CLASSIC_CTRL_BUTTON_ZR 0x0004
#define CLASSIC_CTRL_BUTTON_X 0x0008
#define CLASSIC_CTRL_BUTTON_A 0x0010
#define CLASSIC_CTRL_BUTTON_Y 0x0020
#define CLASSIC_CTRL_BUTTON_B 0x0040
#define CLASSIC_CTRL_BUTTON_ZL 0x0080
#define CLASSIC_CTRL_BUTTON_FULL_R 0x0200
#define CLASSIC_CTRL_BUTTON_PLUS 0x0400
#define CLASSIC_CTRL_BUTTON_HOME 0x0800
#define CLASSIC_CTRL_BUTTON_MINUS 0x1000
#define CLASSIC_CTRL_BUTTON_FULL_L 0x2000
#define CLASSIC_CTRL_BUTTON_DOWN 0x4000
#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000
#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF
 
/* guitar hero 3 button codes */
#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001
#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008
#define GUITAR_HERO_3_BUTTON_GREEN 0x0010
#define GUITAR_HERO_3_BUTTON_BLUE 0x0020
#define GUITAR_HERO_3_BUTTON_RED 0x0040
#define GUITAR_HERO_3_BUTTON_ORANGE 0x0080
#define GUITAR_HERO_3_BUTTON_PLUS 0x0400
#define GUITAR_HERO_3_BUTTON_MINUS 0x1000
#define GUITAR_HERO_3_BUTTON_STRUM_DOWN 0x4000
#define GUITAR_HERO_3_BUTTON_ALL 0xFEFF
 
 
/* wiimote option flags */
#define WIIUSE_SMOOTHING 0x01
#define WIIUSE_CONTINUOUS 0x02
#define WIIUSE_ORIENT_THRESH 0x04
#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH)
 
#define WIIUSE_ORIENT_PRECISION 100.0f
 
/* expansion codes */
#define EXP_NONE 0
#define EXP_NUNCHUK 1
#define EXP_CLASSIC 2
#define EXP_GUITAR_HERO_3 3
 
/* IR correction types */
typedef enum ir_position_t {
WIIUSE_IR_ABOVE,
WIIUSE_IR_BELOW
} ir_position_t;
 
/**
* @brief Check if a button is pressed.
* @param dev Pointer to a wiimote_t or expansion structure.
* @param button The button you are interested in.
* @return 1 if the button is pressed, 0 if not.
*/
#define IS_PRESSED(dev, button) ((dev->btns & button) == button)
 
/**
* @brief Check if a button is being held.
* @param dev Pointer to a wiimote_t or expansion structure.
* @param button The button you are interested in.
* @return 1 if the button is held, 0 if not.
*/
#define IS_HELD(dev, button) ((dev->btns_held & button) == button)
 
/**
* @brief Check if a button is released on this event. \n\n
* This does not mean the button is not pressed, it means \n
* this button was just now released.
* @param dev Pointer to a wiimote_t or expansion structure.
* @param button The button you are interested in.
* @return 1 if the button is released, 0 if not.
*
*/
#define IS_RELEASED(dev, button) ((dev->btns_released & button) == button)
 
/**
* @brief Check if a button has just been pressed this event.
* @param dev Pointer to a wiimote_t or expansion structure.
* @param button The button you are interested in.
* @return 1 if the button is pressed, 0 if not.
*/
#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button))
 
/**
* @brief Return the IR sensitivity level.
* @param wm Pointer to a wiimote_t structure.
* @param lvl [out] Pointer to an int that will hold the level setting.
* If no level is set 'lvl' will be set to 0.
*/
#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \
do { \
if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \
else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \
else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \
else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \
else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \
else *lvl = 0; \
} while (0)
 
#define WIIUSE_USING_ACC(wm) ((wm->state & 0x020) == 0x020)
#define WIIUSE_USING_EXP(wm) ((wm->state & 0x040) == 0x040)
#define WIIUSE_USING_IR(wm) ((wm->state & 0x080) == 0x080)
#define WIIUSE_USING_SPEAKER(wm) ((wm->state & 0x100) == 0x100)
 
#define WIIUSE_IS_LED_SET(wm, num) ((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num)
 
/*
* Largest known payload is 21 bytes.
* Add 2 for the prefix and round up to a power of 2.
*/
#define MAX_PAYLOAD 32
 
/*
* This is left over from an old hack, but it may actually
* be a useful feature to keep so it wasn't removed.
*/
#ifdef WIN32
#define WIIMOTE_DEFAULT_TIMEOUT 10
#define WIIMOTE_EXP_TIMEOUT 10
#endif
 
typedef unsigned char byte;
typedef char sbyte;
 
struct wiimote_t;
struct vec3b_t;
struct orient_t;
struct gforce_t;
 
 
/**
* @brief Callback that handles a read event.
*
* @param wm Pointer to a wiimote_t structure.
* @param data Pointer to the filled data block.
* @param len Length in bytes of the data block.
*
* @see wiiuse_init()
*
* A registered function of this type is called automatically by the wiiuse
* library when the wiimote has returned the full data requested by a previous
* call to wiiuse_read_data().
*/
typedef void (*wiiuse_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len);
 
 
/**
* @struct read_req_t
* @brief Data read request structure.
*/
struct read_req_t {
wiiuse_read_cb cb; /**< read data callback */
byte* buf; /**< buffer where read data is written */
unsigned int addr; /**< the offset that the read started at */
unsigned short size; /**< the length of the data read */
unsigned short wait; /**< num bytes still needed to finish read */
byte dirty; /**< set to 1 if not using callback and needs to be cleaned up */
 
struct read_req_t* next; /**< next read request in the queue */
};
 
 
/**
* @struct vec2b_t
* @brief Unsigned x,y byte vector.
*/
typedef struct vec2b_t {
byte x, y;
} vec2b_t;
 
 
/**
* @struct vec3b_t
* @brief Unsigned x,y,z byte vector.
*/
typedef struct vec3b_t {
byte x, y, z;
} vec3b_t;
 
 
/**
* @struct vec3f_t
* @brief Signed x,y,z float struct.
*/
typedef struct vec3f_t {
float x, y, z;
} vec3f_t;
 
 
/**
* @struct orient_t
* @brief Orientation struct.
*
* Yaw, pitch, and roll range from -180 to 180 degrees.
*/
typedef struct orient_t {
float roll; /**< roll, this may be smoothed if enabled */
float pitch; /**< pitch, this may be smoothed if enabled */
float yaw;
 
float a_roll; /**< absolute roll, unsmoothed */
float a_pitch; /**< absolute pitch, unsmoothed */
} orient_t;
 
 
/**
* @struct gforce_t
* @brief Gravity force struct.
*/
typedef struct gforce_t {
float x, y, z;
} gforce_t;
 
 
/**
* @struct accel_t
* @brief Accelerometer struct. For any device with an accelerometer.
*/
typedef struct accel_t {
struct vec3b_t cal_zero; /**< zero calibration */
struct vec3b_t cal_g; /**< 1g difference around 0cal */
 
float st_roll; /**< last smoothed roll value */
float st_pitch; /**< last smoothed roll pitch */
float st_alpha; /**< alpha value for smoothing [0-1] */
} accel_t;
 
 
/**
* @struct ir_dot_t
* @brief A single IR source.
*/
typedef struct ir_dot_t {
byte visible; /**< if the IR source is visible */
 
unsigned int x; /**< interpolated X coordinate */
unsigned int y; /**< interpolated Y coordinate */
 
short rx; /**< raw X coordinate (0-1023) */
short ry; /**< raw Y coordinate (0-767) */
 
byte order; /**< increasing order by x-axis value */
 
byte size; /**< size of the IR dot (0-15) */
} ir_dot_t;
 
 
/**
* @enum aspect_t
* @brief Screen aspect ratio.
*/
typedef enum aspect_t {
WIIUSE_ASPECT_4_3,
WIIUSE_ASPECT_16_9
} aspect_t;
 
 
/**
* @struct ir_t
* @brief IR struct. Hold all data related to the IR tracking.
*/
typedef struct ir_t {
struct ir_dot_t dot[4]; /**< IR dots */
byte num_dots; /**< number of dots at this time */
 
enum aspect_t aspect; /**< aspect ratio of the screen */
 
enum ir_position_t pos; /**< IR sensor bar position */
 
unsigned int vres[2]; /**< IR virtual screen resolution */
int offset[2]; /**< IR XY correction offset */
int state; /**< keeps track of the IR state */
 
int ax; /**< absolute X coordinate */
int ay; /**< absolute Y coordinate */
 
int x; /**< calculated X coordinate */
int y; /**< calculated Y coordinate */
 
float distance; /**< pixel distance between first 2 dots*/
float z; /**< calculated distance */
} ir_t;
 
 
/**
* @struct joystick_t
* @brief Joystick calibration structure.
*
* The angle \a ang is relative to the positive y-axis into quadrant I
* and ranges from 0 to 360 degrees. So if the joystick is held straight
* upwards then angle is 0 degrees. If it is held to the right it is 90,
* down is 180, and left is 270.
*
* The magnitude \a mag is the distance from the center to where the
* joystick is being held. The magnitude ranges from 0 to 1.
* If the joystick is only slightly tilted from the center the magnitude
* will be low, but if it is closer to the outter edge the value will
* be higher.
*/
typedef struct joystick_t {
struct vec2b_t max; /**< maximum joystick values */
struct vec2b_t min; /**< minimum joystick values */
struct vec2b_t center; /**< center joystick values */
 
float ang; /**< angle the joystick is being held */
float mag; /**< magnitude of the joystick (range 0-1) */
} joystick_t;
 
 
/**
* @struct nunchuk_t
* @brief Nunchuk expansion device.
*/
typedef struct nunchuk_t {
struct accel_t accel_calib; /**< nunchuk accelerometer calibration */
struct joystick_t js; /**< joystick calibration */
 
int* flags; /**< options flag (points to wiimote_t.flags) */
 
byte btns; /**< what buttons have just been pressed */
byte btns_held; /**< what buttons are being held down */
byte btns_released; /**< what buttons were just released this */
 
float orient_threshold; /**< threshold for orient to generate an event */
int accel_threshold; /**< threshold for accel to generate an event */
 
struct vec3b_t accel; /**< current raw acceleration data */
struct orient_t orient; /**< current orientation on each axis */
struct gforce_t gforce; /**< current gravity forces on each axis */
} nunchuk_t;
 
 
/**
* @struct classic_ctrl_t
* @brief Classic controller expansion device.
*/
typedef struct classic_ctrl_t {
short btns; /**< what buttons have just been pressed */
short btns_held; /**< what buttons are being held down */
short btns_released; /**< what buttons were just released this */
 
float r_shoulder; /**< right shoulder button (range 0-1) */
float l_shoulder; /**< left shoulder button (range 0-1) */
 
struct joystick_t ljs; /**< left joystick calibration */
struct joystick_t rjs; /**< right joystick calibration */
} classic_ctrl_t;
 
 
/**
* @struct guitar_hero_3_t
* @brief Guitar Hero 3 expansion device.
*/
typedef struct guitar_hero_3_t {
short btns; /**< what buttons have just been pressed */
short btns_held; /**< what buttons are being held down */
short btns_released; /**< what buttons were just released this */
 
float whammy_bar; /**< whammy bar (range 0-1) */
 
struct joystick_t js; /**< joystick calibration */
} guitar_hero_3_t;
 
 
/**
* @struct expansion_t
* @brief Generic expansion device plugged into wiimote.
*/
typedef struct expansion_t {
int type; /**< type of expansion attached */
 
union {
struct nunchuk_t nunchuk;
struct classic_ctrl_t classic;
struct guitar_hero_3_t gh3;
};
} expansion_t;
 
 
/**
* @enum win32_bt_stack_t
* @brief Available bluetooth stacks for Windows.
*/
typedef enum win_bt_stack_t {
WIIUSE_STACK_UNKNOWN,
WIIUSE_STACK_MS,
WIIUSE_STACK_BLUESOLEIL
} win_bt_stack_t;
 
 
/**
* @struct wiimote_state_t
* @brief Significant data from the previous event.
*/
typedef struct wiimote_state_t {
/* expansion_t */
float exp_ljs_ang;
float exp_rjs_ang;
float exp_ljs_mag;
float exp_rjs_mag;
unsigned short exp_btns;
struct orient_t exp_orient;
struct vec3b_t exp_accel;
float exp_r_shoulder;
float exp_l_shoulder;
 
/* ir_t */
int ir_ax;
int ir_ay;
float ir_distance;
 
struct orient_t orient;
unsigned short btns;
 
struct vec3b_t accel;
} wiimote_state_t;
 
 
/**
* @enum WIIUSE_EVENT_TYPE
* @brief Events that wiiuse can generate from a poll.
*/
typedef enum WIIUSE_EVENT_TYPE {
WIIUSE_NONE = 0,
WIIUSE_EVENT,
WIIUSE_STATUS,
WIIUSE_CONNECT,
WIIUSE_DISCONNECT,
WIIUSE_UNEXPECTED_DISCONNECT,
WIIUSE_READ_DATA,
WIIUSE_NUNCHUK_INSERTED,
WIIUSE_NUNCHUK_REMOVED,
WIIUSE_CLASSIC_CTRL_INSERTED,
WIIUSE_CLASSIC_CTRL_REMOVED,
WIIUSE_GUITAR_HERO_3_CTRL_INSERTED,
WIIUSE_GUITAR_HERO_3_CTRL_REMOVED
} WIIUSE_EVENT_TYPE;
 
/**
* @struct wiimote_t
* @brief Wiimote structure.
*/
typedef struct wiimote_t {
WCONST int unid; /**< user specified id */
 
#ifndef WIN32
WCONST bdaddr_t bdaddr; /**< bt address */
WCONST char bdaddr_str[18]; /**< readable bt address */
WCONST int out_sock; /**< output socket */
WCONST int in_sock; /**< input socket */
#else
WCONST HANDLE dev_handle; /**< HID handle */
WCONST OVERLAPPED hid_overlap; /**< overlap handle */
WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */
WCONST int timeout; /**< read timeout */
WCONST byte normal_timeout; /**< normal timeout */
WCONST byte exp_timeout; /**< timeout for expansion handshake */
#endif
 
WCONST int state; /**< various state flags */
WCONST byte leds; /**< currently lit leds */
WCONST float battery_level; /**< battery level */
 
WCONST int flags; /**< options flag */
 
WCONST byte handshake_state; /**< the state of the connection handshake */
 
WCONST struct read_req_t* read_req; /**< list of data read requests */
WCONST struct accel_t accel_calib; /**< wiimote accelerometer calibration */
WCONST struct expansion_t exp; /**< wiimote expansion device */
 
WCONST struct vec3b_t accel; /**< current raw acceleration data */
WCONST struct orient_t orient; /**< current orientation on each axis */
WCONST struct gforce_t gforce; /**< current gravity forces on each axis */
 
WCONST struct ir_t ir; /**< IR data */
 
WCONST unsigned short btns; /**< what buttons have just been pressed */
WCONST unsigned short btns_held; /**< what buttons are being held down */
WCONST unsigned short btns_released; /**< what buttons were just released this */
 
WCONST float orient_threshold; /**< threshold for orient to generate an event */
WCONST int accel_threshold; /**< threshold for accel to generate an event */
 
WCONST struct wiimote_state_t lstate; /**< last saved state */
 
WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */
WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */
} wiimote;
 
 
/*****************************************
*
* Include API specific stuff
*
*****************************************/
 
#ifdef _WIN32
#define WIIUSE_EXPORT_DECL __declspec(dllexport)
#define WIIUSE_IMPORT_DECL __declspec(dllimport)
#else
#define WIIUSE_EXPORT_DECL
#define WIIUSE_IMPORT_DECL
#endif
 
#ifdef WIIUSE_COMPILE_LIB
#define WIIUSE_EXPORT WIIUSE_EXPORT_DECL
#else
#define WIIUSE_EXPORT WIIUSE_IMPORT_DECL
#endif
 
#ifdef __cplusplus
extern "C" {
#endif
 
/* wiiuse.c */
WIIUSE_EXPORT extern const char* wiiuse_version();
 
WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes);
WIIUSE_EXPORT extern void wiiuse_disconnected(struct wiimote_t* wm);
WIIUSE_EXPORT extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes);
WIIUSE_EXPORT extern void wiiuse_rumble(struct wiimote_t* wm, int status);
WIIUSE_EXPORT extern void wiiuse_toggle_rumble(struct wiimote_t* wm);
WIIUSE_EXPORT extern void wiiuse_set_leds(struct wiimote_t* wm, int leds);
WIIUSE_EXPORT extern void wiiuse_motion_sensing(struct wiimote_t* wm, int status);
WIIUSE_EXPORT extern int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len);
WIIUSE_EXPORT extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len);
WIIUSE_EXPORT extern void wiiuse_status(struct wiimote_t* wm);
WIIUSE_EXPORT extern struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid);
WIIUSE_EXPORT extern int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable);
WIIUSE_EXPORT extern float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha);
WIIUSE_EXPORT extern void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type);
WIIUSE_EXPORT extern void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold);
WIIUSE_EXPORT extern void wiiuse_resync(struct wiimote_t* wm);
WIIUSE_EXPORT extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout);
WIIUSE_EXPORT extern void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold);
 
/* connect.c */
WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout);
WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes);
WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm);
 
/* events.c */
WIIUSE_EXPORT extern int wiiuse_poll(struct wiimote_t** wm, int wiimotes);
 
/* ir.c */
WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status);
WIIUSE_EXPORT extern void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y);
WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos);
WIIUSE_EXPORT extern void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect);
WIIUSE_EXPORT extern void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level);
 
/* nunchuk.c */
WIIUSE_EXPORT extern void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold);
WIIUSE_EXPORT extern void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold);
 
 
#ifdef __cplusplus
}
#endif
 
 
#endif /* WIIUSE_H_INCLUDED */
 
/MoteCtrl/Sources/wiiuse.lib
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/MoteCtrl/Sources/wiiuse.lib
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/MoteCtrl/ChangeLog.txt
0,0 → 1,5
 
***** MoteCtrl ChangeLog *****
 
v0.1 2008.12.26
- initial release
/MoteCtrl/MoteCtrl.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/MoteCtrl/MoteCtrl.exe
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/MoteCtrl/READ_ME_FIRST_CRLF_WIN.txt
0,0 → 1,189
/* ============================================================================
* v0.1
*
* *****MoteCtrl*****
* written by Andreas Benzin (aka Alpin)
*
* lets you control your MikroKopter with a Wiimote!
*
*
* Copyright December 2008
*
* #Credits & Thx:
* - Holger & Ingo for the MikroKopter Project (www.mikrokopter.de)
* - ExternalControl implementation of the FlightControl
* - Ligi for RIDDIM, proof of external control concept
* - Documentation of the MK's SerialProtocol (www.mikrokopter.de/ucwiki/en/SerialProtocol)
* - Michael Laforest for the wiiuse API
*
* #WEBSITE: http://www.mikrokopter.de/ucwiki/en/MoteCtrl
*
* *****Use at your own risk! No warranty. Only for private usage.*****
*
* #LICENSE: Released under the GNU General Public License Version 2 or
* (at your option) a later version of this license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* For further details see <www.gnu.org/licenses/>.
*
* #DISCLAIMER: Use this project at your own risk!
* No warrenty.
* Only for private usage.
*
* ============================================================================
*/
***** Table of Contents *****
1. Description
2. What you need
3. Short checklist
4. Controls
5. Usage of MoteCtrl - Step by Step
6. Useful Tips & Practical Experiences
 
== 1. Description ==============================================================
 
MoteCtrl is a small terminal-based programm, which acts as an
interface to the Wiimote and the MikroKopter platform.
The MikroKopter is usually controlled by a normal 35MHz remote control.
However, the FlightControl software also allows you to control your MikroKopter
with a so called ExternControl struct, which is send via the serial
communications line.
MoteCtrl.exe, running on your windows pc, exactly does this. It captures the
Wiimote's and Nunchuck's (extension to the wiimote) data and transfers it to the
FlightCtrl.
 
 
== 2. What you need ============================================================
 
- MikroKopter with at least FlightCtrl firmware version 0.71h running
- wireless serial communication to the FilghtCtrl via Bluetooth
(I use the F2M03GXA Bluetooth modul, with the wireless UART service activated,
see <http://www.mikrokopter.de/ucwiki/F2M03GXA> for more information)
- Wiimote with Nunchuck extension
- Laptop running windows xp
- Bluetooth-dongle or build-in bluetooth communications in your laptop
- Since I use the wiiuse lib v0.12 to connect to the Wiimote, your bluetooth
stack should be compatible with the wiiuse lib
On their page wiiuse.org they say, they successfully tested wiiuse with
BlueSoleil, Windows XP SP2 stack and Widcomm
(my BT-dongle uses the BlueSoleil stack and it works fine)
- Backup Pilot at the 35MHz Remote Control (see =Usage=)
- MoteCtrl.exe along with the wiiuse.dll file (both in one folder)
 
 
== 3. Short Checklist ===========================================================
(for more detailed step by step instructions, see =Usage of MoteCtrl=)
 
-MK ready?, ExternalControl switch assigned?, Backup pilot ready?
-Nunchuck plugged in to Wiimote? (software check does not work yet, seems to be
a bug in the wiiuse API)
-BT connections to Wiimote (HID service running) and MikroKopter (Serial Port
Service running) established?
== 4. Controls ================================================================
GAS: Controlled by the two buttons on the Nunchuck extension ('c' and 'z').
Press 'c' = Increment(++) gas value by 1
Press 'z' = Decrement(--) gas value by 1
YAW(GIER): Controlled by the Nunchuck's joystick.
Pressed to the right half = yaw to the right
Pressed to the left half = yaw to the left
The more you push the joystick to one of the two directions, the
MK yaws faster.
NICK(PITCH): Controlled by the Wiimote's pitch-tilt.
Tilting your Wiimote to the left means, tilting the Quadro left.
To the right accordingly.
 
ROLL: Controlled by the Wiimote's roll-tilt.
Same like with pitch.
SPECIAL: You can reset the GAS value immediatly to ZERO (==no gas!!) with the
HOME-Button. Be carefull with that!
 
== 5. Usage of MoteCtrl - Step by Step =========================================
 
Preparations:
1. Make sure your all the items listed under "What you need" work
 
2. To allow external control you have to allocate a switch of your normal
35MHz RemoteCtrl to the "External Control" variable in the MikroKopter-Tool.
You should find this option in the MK Tool -> Configuration/Settings
Explanation:
Your normal Remote Control is always used as a backup device, in case the
operator at the Wiimote looses control of the Quadrokopter or the Bluetooth
connection is somehow interruted. Therefore the backup pilot at the 35MHz
control can pass the control to the pilot with the Wiimote via his "external
control" switch. If he feels that the Quadro is out of control or the
connection is interrupted he just flips the switch back, gets control himself
again and can rescue the poor -out of control- MikroKopter ;)
 
Flight:
1. Turn your MikroKopter and your normal remote on. Make sure everything is
running perfectly (perhaps do a "normal" test flight to check everything's ok)
2. Establish the wireless UART connection to your Mikrokopter with your
Bluetooth stack. The BT stack should assign a windows COM Port to the
established connection, so you can access it (make sure Serial Port Service
is running). You need to remember the NUMBER OF THE COM PORT, e.g COM4.
So you established the link to your MK.
3. Next establish the connection to the Wiimote:
- Press both, the 1 and 2 Button at the same time. All the 4 LEDs should be
blinking now. Your wiimote is now in "discovery mode", which means it is
searching for a little Nintendo Wii to pair with it.
- Now we are (or our BT stack is) the Wii: While the wiimote is in discovery
mode search for devices in your BT stack program. You should find the wiimote
now. Do NOT pair with it. Rather search for services the wiimote offers.
This should bring up the HID (Human Interface Device) service offer.
Check that the wiimote is still in discovery mode (only 30 seks active) and
activate the HID service. You should now be connected with the wiimote and
the 4 leds of the wiimote should still blink but shouldn't stop blinking
anymore.
4. So the BT stack is now connected to both, the Wiimote and the MK (BT can
connect up to 7 devices at a time). Now start the MoteCtrl.exe via a
windows commandline. Make sure you put the wiiuse.dll in the same folder
like MoteCtrl.exe, otherwise the program will return immediatly without
an error message (and you think huh?).
5. Next you should be asked for your COM Port number, which is linked to your MK.
Type in the number, hit enter.
6. Next is the Wiimote initalizaition. If you your HID service is running every-
thing should be fine now and MoteCtrl connects to it.
7. Your Wiimote should rumble now for a sek and the LEDs should have stopped
blinking (now only LED 1 is permanently on).
--> This tells you, that MoteCtrl established the connection to the
Wiimote successfully.
8. You should now see the DEBUG Output scrolling down your terminal screen.
9. First familiarize yourself with the new Wiimote's and Nunchuck's controls,
with the engines of the MK deactivated. Watch the Debug output changing
its values while you play with the Wiimote & Nunchuck.
For Controls, see the chapter =Controls=.
10. Flight: Your MAX GAS is always limited by the gas value, which is set at
the backup pilot's 35MHz remote. So the backup pilot "gives you a limit"
of the GAS value.
The backup pilot can now pass the control up to you by using his
"External Control" switch ;)
== 6. Useful Tips & Practical Experiences ======================================
 
- It happens often hat the connection to the Wiimote or the MK can't be
established with your bt stack. Just disconnect everything then and try to
reconnect all the devices.
- While paring your MK's bluetooth with the one of your laptop place the
MK text to your laptop. Bluetooth has a very limited range.
- The Bluettoth's range is very limited. Don't fly far away from your MK! This
will definitely interrupt or cancel your connection (at least your backup
pilot will have a bit of fun then ;)
- Don't go far away from your laptop with you wiimote in hand. Same like above.
 
 
--EOF 26th of December 2008, Andreas Benzin
/MoteCtrl/READ_ME_FIRST_LF_UNIX.txt
0,0 → 1,189
/* ============================================================================
* v0.1
*
* *****MoteCtrl*****
* written by Andreas Benzin (aka Alpin)
*
* lets you control your MikroKopter with a Wiimote!
*
*
* Copyright December 2008
*
* #Credits & Thx:
* - Holger & Ingo for the MikroKopter Project (www.mikrokopter.de)
* - ExternalControl implementation of the FlightControl
* - Ligi for RIDDIM, proof of external control concept
* - Documentation of the MK's SerialProtocol (www.mikrokopter.de/ucwiki/en/SerialProtocol)
* - Michael Laforest for the wiiuse API
*
* #WEBSITE: http://www.mikrokopter.de/ucwiki/en/MoteCtrl
*
* *****Use at your own risk! No warranty. Only for private usage.*****
*
* #LICENSE: Released under the GNU General Public License Version 2 or
* (at your option) a later version of this license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* For further details see <www.gnu.org/licenses/>.
*
* #DISCLAIMER: Use this project at your own risk!
* No warrenty.
* Only for private usage.
*
* ============================================================================
*/
***** Table of Contents *****
1. Description
2. What you need
3. Short checklist
4. Controls
5. Usage of MoteCtrl - Step by Step
6. Useful Tips & Practical Experiences
 
== 1. Description ==============================================================
 
MoteCtrl is a small terminal-based programm, which acts as an
interface to the Wiimote and the MikroKopter platform.
The MikroKopter is usually controlled by a normal 35MHz remote control.
However, the FlightControl software also allows you to control your MikroKopter
with a so called ExternControl struct, which is send via the serial
communications line.
MoteCtrl.exe, running on your windows pc, exactly does this. It captures the
Wiimote's and Nunchuck's (extension to the wiimote) data and transfers it to the
FlightCtrl.
 
 
== 2. What you need ============================================================
 
- MikroKopter with at least FlightCtrl firmware version 0.71h running
- wireless serial communication to the FilghtCtrl via Bluetooth
(I use the F2M03GXA Bluetooth modul, with the wireless UART service activated,
see <http://www.mikrokopter.de/ucwiki/F2M03GXA> for more information)
- Wiimote with Nunchuck extension
- Laptop running windows xp
- Bluetooth-dongle or build-in bluetooth communications in your laptop
- Since I use the wiiuse lib v0.12 to connect to the Wiimote, your bluetooth
stack should be compatible with the wiiuse lib
On their page wiiuse.org they say, they successfully tested wiiuse with
BlueSoleil, Windows XP SP2 stack and Widcomm
(my BT-dongle uses the BlueSoleil stack and it works fine)
- Backup Pilot at the 35MHz Remote Control (see =Usage=)
- MoteCtrl.exe along with the wiiuse.dll file (both in one folder)
 
 
== 3. Short Checklist ===========================================================
(for more detailed step by step instructions, see =Usage of MoteCtrl=)
 
-MK ready?, ExternalControl switch assigned?, Backup pilot ready?
-Nunchuck plugged in to Wiimote? (software check does not work yet, seems to be
a bug in the wiiuse API)
-BT connections to Wiimote (HID service running) and MikroKopter (Serial Port
Service running) established?
== 4. Controls ================================================================
GAS: Controlled by the two buttons on the Nunchuck extension ('c' and 'z').
Press 'c' = Increment(++) gas value by 1
Press 'z' = Decrement(--) gas value by 1
YAW(GIER): Controlled by the Nunchuck's joystick.
Pressed to the right half = yaw to the right
Pressed to the left half = yaw to the left
The more you push the joystick to one of the two directions, the
MK yaws faster.
NICK(PITCH): Controlled by the Wiimote's pitch-tilt.
Tilting your Wiimote to the left means, tilting the Quadro left.
To the right accordingly.
 
ROLL: Controlled by the Wiimote's roll-tilt.
Same like with pitch.
SPECIAL: You can reset the GAS value immediatly to ZERO (==no gas!!) with the
HOME-Button. Be carefull with that!
 
== 5. Usage of MoteCtrl - Step by Step =========================================
 
Preparations:
1. Make sure your all the items listed under "What you need" work
 
2. To allow external control you have to allocate a switch of your normal
35MHz RemoteCtrl to the "External Control" variable in the MikroKopter-Tool.
You should find this option in the MK Tool -> Configuration/Settings
Explanation:
Your normal Remote Control is always used as a backup device, in case the
operator at the Wiimote looses control of the Quadrokopter or the Bluetooth
connection is somehow interruted. Therefore the backup pilot at the 35MHz
control can pass the control to the pilot with the Wiimote via his "external
control" switch. If he feels that the Quadro is out of control or the
connection is interrupted he just flips the switch back, gets control himself
again and can rescue the poor -out of control- MikroKopter ;)
 
Flight:
1. Turn your MikroKopter and your normal remote on. Make sure everything is
running perfectly (perhaps do a "normal" test flight to check everything's ok)
2. Establish the wireless UART connection to your Mikrokopter with your
Bluetooth stack. The BT stack should assign a windows COM Port to the
established connection, so you can access it (make sure Serial Port Service
is running). You need to remember the NUMBER OF THE COM PORT, e.g COM4.
So you established the link to your MK.
3. Next establish the connection to the Wiimote:
- Press both, the 1 and 2 Button at the same time. All the 4 LEDs should be
blinking now. Your wiimote is now in "discovery mode", which means it is
searching for a little Nintendo Wii to pair with it.
- Now we are (or our BT stack is) the Wii: While the wiimote is in discovery
mode search for devices in your BT stack program. You should find the wiimote
now. Do NOT pair with it. Rather search for services the wiimote offers.
This should bring up the HID (Human Interface Device) service offer.
Check that the wiimote is still in discovery mode (only 30 seks active) and
activate the HID service. You should now be connected with the wiimote and
the 4 leds of the wiimote should still blink but shouldn't stop blinking
anymore.
4. So the BT stack is now connected to both, the Wiimote and the MK (BT can
connect up to 7 devices at a time). Now start the MoteCtrl.exe via a
windows commandline. Make sure you put the wiiuse.dll in the same folder
like MoteCtrl.exe, otherwise the program will return immediatly without
an error message (and you think huh?).
5. Next you should be asked for your COM Port number, which is linked to your MK.
Type in the number, hit enter.
6. Next is the Wiimote initalizaition. If you your HID service is running every-
thing should be fine now and MoteCtrl connects to it.
7. Your Wiimote should rumble now for a sek and the LEDs should have stopped
blinking (now only LED 1 is permanently on).
--> This tells you, that MoteCtrl established the connection to the
Wiimote successfully.
8. You should now see the DEBUG Output scrolling down your terminal screen.
9. First familiarize yourself with the new Wiimote's and Nunchuck's controls,
with the engines of the MK deactivated. Watch the Debug output changing
its values while you play with the Wiimote & Nunchuck.
For Controls, see the chapter =Controls=.
10. Flight: Your MAX GAS is always limited by the gas value, which is set at
the backup pilot's 35MHz remote. So the backup pilot "gives you a limit"
of the GAS value.
The backup pilot can now pass the control up to you by using his
"External Control" switch ;)
== 6. Useful Tips & Practical Experiences ======================================
 
- It happens often hat the connection to the Wiimote or the MK can't be
established with your bt stack. Just disconnect everything then and try to
reconnect all the devices.
- While paring your MK's bluetooth with the one of your laptop place the
MK text to your laptop. Bluetooth has a very limited range.
- The Bluettoth's range is very limited. Don't fly far away from your MK! This
will definitely interrupt or cancel your connection (at least your backup
pilot will have a bit of fun then ;)
- Don't go far away from your laptop with you wiimote in hand. Same like above.
 
 
--EOF 26th of December 2008, Andreas Benzin
/MoteCtrl/wiiuse.dll
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/MoteCtrl/wiiuse.dll
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property