Styra din Robot med en Wii Nunchuck (och en Arduino) (3 / 4 steg)
Steg 3: programmering
(stort tack till Tchad i windmeadow.com för forskningen och skriva verkligen lätt förstod Arduino kod att interagera med Wii nunchuck, innehåller programmet nedan hans koden praktiskt taget oförändrad).
Vad den gör
- Programmet kommer som standard med nunchucks styrspaken för kontroll. Om du trycker minnet fram kommer att din robot gå framåt, bakåt, bakåt och så vidare.
- Om du håller ner knappen "Z" (den stora en på framsidan). Din robot nu flyttar baserat på lutningen på nunchuck. Tilt framåt gå vidare...
- Slutligen om det inte riktigt fungerar sänder programmet staten knapparna nunchaku, joystick och accelerometrar, varje sekund över den Arduino USB-port. (bara öppna fönstret debug på 9600 se dessa data)
För de intresserade helt enkelt att få det att gå.
Kopiera och klistra in
- Kopiera den Arduino koden nedan
- Klistra in den i utvecklingsmiljön Arduino.
- Ladda upp och börja spela
Med hjälp av koden i ditt eget Program
- Först initiera nunchuck genom att anropa nunchuck_init ();
- Nästa varje gång du vill uppdatera kallar värdena för nunchuck i din skiss readNunchuck();
- Vid direkt tillgång kallar värdena getNunValue(Variable Constant); (ex. YAXIS)
- Slutligen om du vill använda accelerometern men har det skalas till ett antal Gs (dvs. 1 g = 1 styrkan av gravitation). Du kan ringa getXGs(); getYGs(), eller getZGs();
Tillägg 1 - _SERB_WiiNunchuckControl.pde
BÖRJAN av NUNCHUCK INGRESSEN - för mer djupgående information besök ursprungliga källan till denna kod http://www.windmeadow.com/node/42
//-------------------------------------------------
/*
* Ledningar Detaljer
* vit - jorda
* röd - 3.3 + v - 5 volt verkar fungera
* grön - data - Analog 4
* gul - klocka - Analog 5
*/
#include #include #undef int #include uint8_t outbuf [6]. matrisen att lagra arduino utgång int cnt = 0; räknare för nunchuck comunication int ledPin = 13. int nunchuckValues [] = {0,0,0,0,0,0,0,0,0,0}. En matris att lagra nuncheck värden / * * index för varje värde i arrayen nunchuckValues [] * dvs. XSTICK värdet lagras vid nunchuckValues [XSTICK] (0) * / #define XSTICK 0 //The joystick värden #define YSTICK 1 #define XAXIS 2 //The tre accelerometer värden #define YAXIS 3 #define ZAXIS 4 #define ZBUTTON 5 //Front knappen värden (0 när du trycker) #define c-knappen 6 #define XAXISDELTA 7 //Change i accelerometer data från senaste Läs; #define YAXISDELTA 8 #define ZAXISDELTA 9 //Nunchuck G beräkning av konstanter / * * för skalning raw värdena från nunchuck till G-värden * detaljer på kalibreringsmönstret och matematik finns på * http://www.wiili.org/index.php/Motion_analysis (kopierad från http://www.wiili.org/index.php/Motion_analysis) noll poäng x_0 = (x_1 + x_2) / 2\, y_0 = (y_1 + y_3) / 2\, z_0 = (z_2 + z_3) / 2\ En G poäng x = \frac{x_{raw}-x_0} {x_3 - x_0} y = \frac{y_{raw}-y_0} {y_2 - y_0} z = \frac{z_{raw}-z_0} {z_1 - z_0} * / / * inte alla av dessa används och kunde tas bort (höll för att göra interpretting matematik * lättare 0 G värde 1-värde noll när handpåläggning tabell 2-värde när de vilar på näsan * 3-värde när de vilar på sidan (vänster sida upp) * / #define X0 500 #define X1 500 # definiera X2 500 #define X3 711 #define Y0 465 #define Y1 481 #define Y2 621 #define Y3 449 #define Z0 578 #define Z1 785 #define Z2 575 #define Z3 582 //END av NUNCHUCK INGRESSEN - för mer djupgående information besök denna kod http://www.windmeadow.com/node/42 ursprungliga källa / /---/ /---/ / START av ARDUINO kontrollerade SERVO ROBOT (SERBISKT) ingress #include #define LEFTSERVOPIN 10 #define RIGHTSERVOPIN 9 #define MAXOMDR 10 //due till kontinuerlig rotation servon arbeta som högsta hastighet är nåddes vid en mycket lägre värde än 90 (detta värde ändras beroende på din servon) (för Parallax servon) Servo leftServo; Servo rightServo; int leftSpeed = 100; Anger hastigheten på roboten (vänster servon) //a andel mellan - MAXOMDR och MAXOMDR int rightSpeed = 100; Anger hastigheten på roboten (båda servon) //a andel mellan - MAXOMDR och MAXOMDR int hastighet = 100; används för enkel kontroll (goForward, goBackward, goLeft och goRight //a andel mellan 0 och MAXOMDR / / slutet av ARDUINO kontrollerade SERVO ROBOT (serbiska) ingress / /---lång lastPrint; //a länge variabel för lagring av tidpunkten som wiimote staten var sista tryckta #define PRINTINTERVAL 1000 //the antalet millisekunder mellan mata nunchuck staten över usb port #define DÖDBAND 20 //A procentsatsen från centrum som är tolkas som fortfarande noll void setup() {Serial.begin(9600); //Starts den seriella porten (används för debuging men gör servon jumpy) nunchuck_init (); Skicka nunchuck initilization handslag serbSetup(); lägger till servon och förbereder alla serbiska relaterade variabler lastPrint = millis(); } void loop() {readNunchuck(); //Reads det aktuella läget för nunchaku knappar och accelerometrar om ()! getNunValue(ZBUTTON)) {moveWiiAcelerometer(); //moves wii deoending på nunchucks accelerationsvärdena} annat {moveWiiJoystick();} if((millis() - lastPrint) > PRINTINTERVAL) {//If en sekund förflutit sedan senaste utskrift nunchuck värden skriva ut dem printData(); //print nunchuck värden Serial.println(); //add en retur lastPrint = millis(); //store aktuell tid som lastPrint}} void moveWiiAcelerometer() {moveDifferential(getYGs() * (float)100,getXGs()*(float)100);} void moveWiiJoystick() {moveDifferential(map(getNunValue(YSTICK) , 30,220,-100,100),map(getNunValue(XSTICK),30,220,-100,100)); } //Takes i en hastighet och en riktning ingång (som en joystick) och översätter till hastighet kommandon void moveDifferential (int ET1, int direction1) {ET1 = deadBandFilter(speed1); direction1 = deadBandFilter(direction1), setSpeedLeft (speed1 + direction1), setSpeedRight (speed1 - direction1);} int deadBandFilter (int value) {om (värde > - DÖDBAND & & värdet < DÖDBAND) {värde = 0;} annat {if(value > 0) {värde = värde - DÖDBAND * 100 / (100-DÖDBAND);} annat {värde = värde + DÖDBAND * 100 / (100-DÖDBAND);}} returvärde;} //START av NUNCHUCK rutiner / /---//Calculates och returnerar xAxis acceleration i Gs flyta getXGs() {return ((float)getNunValue(XAXIS) - X0) / (X-3 - X 0).} //Calculates och returnerar yAxis acceleration i Gs float getYGs() {återvända ((float)getNunValue(YAXIS)-Y0) / (Y2 - Y0);} //Calculates och returnerar zAxis accelerationen i Gs float getZGs() {återvända ((float)getNunValue(YAXIS)-Z0) / (Z1 - Z0);} //START av NUNCHUCK behandlingen kod - mer djupgående information vänligen besök den ursprungliga källa //of denna kod http://www.windmeadow.com/node/42 / /---void readNunchuck() {Wire.requestFrom (0x52 , 6); begära data från nunchuck samtidigt (Wire.available ()) {outbuf [cnt] = nunchuk_decode_byte (Wire.receive ()); / / få byte som ett heltal digitalWrite (ledPin, hög); / / sätter LED på cnt ++;} / / om vi fått 6 byte, gå sedan skriva ut dem om (cnt > = 5) {nunchuckValues [XSTICK] = outbuf [0]; nunchuckValues [YSTICK] = outbuf [1]; int tempNun_xAxis = outbuf [2] * 2 * 2; int tempNun_yAxis = outbuf [3] * 2 * 2; int tempNun_zAxis = outbuf [4] * 2 * 2; nunchuckValues [ZBUTTON] = 0;
nunchuckValues [c-knappen] = 0;
byte outbuf [5] innehåller bitar för z- och c-knapparna
den innehåller också de minst signifikanta bitarna för accelerometer data
så vi måste kontrollera varje bit av byte outbuf [5]
om ((outbuf [5] >> 0) & 1) {nunchuckValues [ZBUTTON] = 1;} //checking om Z-knappen trycks (0 = pressad 1 = Kolfiberförstärkt)
om ((outbuf [5] >> 1) & 1) {nunchuckValues [c-knappen] = 1;} //checking om C-knappen trycks (0 = pressad 1 = Kolfiberförstärkt)
om ((outbuf [5] >> 2) & 1) {tempNun_xAxis += 2;} //adding näst minst signifikanta lite till x_axis
om ((outbuf [5] >> 3) & 1) {tempNun_xAxis += 1;} //adding minst signifikanta lite till x_axis
om ((outbuf [5] >> 4) & 1) {tempNun_yAxis += 2;} //adding näst minst signifikanta lite till y_axis
om ((outbuf [5] >> 5) & 1) {tempNun_yAxis += 1;} //adding minst signifikanta lite till x_axis
om ((outbuf [5] >> 6) & 1) {tempNun_zAxis += 2;} //adding näst minst signifikanta lite till z_axis
om ((outbuf [5] >> 7) & 1) {tempNun_zAxis += 1;} ///adding minst signifikanta lite till x_axis
nunchuckValues [XAXISDELTA] = tempNun_xAxis - nunchuckValues [XAXIS];
nunchuckValues [XAXIS] = tempNun_xAxis;
nunchuckValues [YAXISDELTA] = tempNun_yAxis - nunchuckValues [YAXIS];
nunchuckValues [YAXIS] = tempNun_yAxis;
nunchuckValues [ZAXISDELTA] = tempNun_zAxis - nunchuckValues [ZAXIS];
nunchuckValues [ZAXIS] = tempNun_zAxis;
}
CNT = 0;
send_zero (); skicka begäran om nästa byte
}
int getNunValue (int valueIndex) {
återgå nunchuckValues [valueIndex];
}
void nunchuck_init () {
Wire.BEGIN (); gå med i2c bussen med adress 0x52
Wire.beginTransmission (0x52); överföra till enhet 0x52
Wire.send (0x40); skickar minnesadress
Wire.send (0x00); skickar skickade en nolla.
Wire.endTransmission (); stoppa överföring
}
void send_zero () {
Wire.beginTransmission (0x52); överföra till enhet 0x52
Wire.send (0x00); skickar en byte
Wire.endTransmission (); stoppa överföring
}
Koda data om du vill formatera som de flesta wiimote förare utom
behövs endast om du använder en av de regelbundna wiimote förarna
char nunchuk_decode_byte (char x) {
x = (x ^ 0x17) + 0x17;
återvändande x;
}
SLUTET av NUNCHUCK-koden - för mer djupgående information vänligen besök den
ursprungliga källan av denna kod http://www.windmeadow.com/node/42
//---------------------------------------------------------------
//------------------------------------------------------------------------
BÖRJAN AV ARDUINO KONTROLLERADE SERVO ROBOT (SERBISKA) RUTINER
/*
* sätter upp din arduino att ta itu med din serbiska med hjälp av de medföljande rutinerna
*/
void serbSetup() {
setSpeed(speed);
pinMode (LEFTSERVOPIN, OUTPUT); Anger den vänstra servo signal stiftet
att mata
pinMode (RIGHTSERVOPIN, OUTPUT); anger rätt servo signalen pin
att mata
leftServo.attach(LEFTSERVOPIN); fäster vänster servo
rightServo.attach(RIGHTSERVOPIN); fäster rätt servo
goStop();
}
/*
* Anger hastigheten av roboten mellan 0-(stopped) och 100-(full hastighet)
* Obs: hastighet ändras inte den aktuella hastigheten måste du ändra hastighet
* sedan ringa gå metoder innan förändringar sker.
*/
void setSpeed (int newSpeed) {
om (newSpeed > = 100) {newSpeed = 100;} //if hastighet är större än 100
göra det 100
om (newSpeed < = 0) {newSpeed = 0;} //if hastighet är mindre än 0 gör
det 0
hastighet = newSpeed * MAXOMDR / 100; skalar hastigheten för att vara
mellan 0 och MAXOMDR
}
/*
* Anger hastigheten av robotar rightServo mellan-100-(reversed) och 100-(forward)
* Obs: samtal till denna rutin kommer att gälla omedelbart
*/
void setSpeedRight (int newSpeed) {
om (newSpeed > = 100) {newSpeed = 100;} //if hastighet är större än 100
göra det 100
om (newSpeed < = -100) {newSpeed = -100;} //if hastighet är mindre än -100 gör
det -100
rightSpeed = newSpeed * MAXOMDR / 100; skalar hastigheten för att vara
mellan - MAXOMDR och MAXOMDR
rightServo.write (90 - rightSpeed); skickar det nya värdet till servo
}
/*
* Anger hastigheten av robotar leftServo mellan-100-(reversed) och 100-(forward)
* Obs: samtal till denna rutin kommer att gälla omedelbart
*/
void setSpeedLeft (int newSpeed) {
om (newSpeed > = 100) {newSpeed = 100;} //if hastighet är större än 100
göra det 100
om (newSpeed < = -100) {newSpeed = -100;} //if hastighet är mindre än -100 gör
det -100
leftSpeed = newSpeed * MAXOMDR / 100; skalar hastigheten för att vara
mellan - MAXOMDR och MAXOMDR
leftServo.write (90 + leftSpeed); skickar det nya värdet till servo
}
/*
* skickar roboten framlänges
*/
void goForward() {
leftServo.write (90 + hastighet);
rightServo.write (90 - hastighet);
}
/*
* skickar roboten bakåt
*/
void goBackward() {
leftServo.write (90 - hastighet);
rightServo.write (90 + hastighet);
}
/*
* skickar roboten rätt
*/
void goRight() {
leftServo.write (90 + hastighet);
rightServo.write (90 + hastighet);
}
/*
* skickar roboten vänster
*/
void goLeft() {
leftServo.write (90 - hastighet);
rightServo.write (90 - hastighet);
}
/*
* stannar roboten
*/
void goStop() {
leftServo.write(90);
rightServo.write(90);
}
SLUTET AV ARDUINO KONTROLLERADE SERVO ROBOT (SERBISKA) RUTINER
//---------------------------------------------------------------------------
STARTA om PRINT rutiner (kan ta bort om du inte använder)
//---------------------------------------------------------------
Utskrifter av Nunchucks senast läste data (måste ringa NUN_readNunchuck(), innan ringer
void printData() {
Serial.Print ("XJoy ="); Serial.Print (getNunValue(XSTICK), DEC); Serial.Print ("\t");
Serial.Print ("YJoy ="); Serial.Print (getNunValue(YSTICK), DEC); Serial.Print ("\t");
Serial.Print ("XGs ="); Serial.Print (getXGs() * 1000, DEC); Serial.Print ("\t");
Serial.Print ("YGs ="); Serial.Print (getYGs() * 1000, DEC); Serial.Print ("\t");
Serial.Print ("ZGs ="); Serial.Print (getZGs() * 1000, DEC); Serial.Print ("\t");
Serial.Print ("ZBut ="); Serial.Print (getNunValue(ZBUTTON), DEC); Serial.Print ("\t");
Serial.Print ("YBut ="); Serial.Print (getNunValue(CBUTTON), DEC); Serial.Print ("\t");
}
SLUTET AV PRINT RUTINER
//--------------------------------------------------------------------