לרבים היה הצעצוע הזה בילדותנו: שלטנו בו בעזרת שתי ידיות סיבוב. כבר אז היה אפשר לחבר אליו שני מנועי DC עם הילוכים ולשלוט עליהם מהכפתורים. ועכשיו לשם כך התאפשר התאמת הג'ויסטיקים. וזה מה שעשה מחבר ה- Instructables תחת הכינוי millerman4487.
כל הרכיבים תוצרת בית הוא הניח על דף קרטון:
אבל היה צורך להדפיס שני חלקים זהים - אלה מתאמים לחיבור הילוכים לידיות מסך הקסם. זה נראה כמו כל אחד מהמתאמים:
וכך הוא מתחבר לתיבת ההילוכים (אולי זה ידרוש התחממות קלה של המתאם עם מייבש שיער):
קובץ STL.
התרשים החשמלי של המבנה מוצג להלן:
יש רק רכיב אחד בלתי מובן - שבב L293D. הוא מכיל שני גשרים H שנקראים, שכל אחד מהם יכול להפוך את המנוע המחובר אליו. מתחת ללוח מוצג אילו מסקנות ארדואינו חבר איזה מהסיכות של מחבר הג'ויסטיק של Wii Nunchuck. ניתן לרשום מחדש את הסקיצה שלהלן לעבודה עם כל סוג אחר של ג'ויסטיקים, בצורתה הנוכחית היא תידרש.
# כלול
#if (ARDUINO & gt; = 100)
# כלול
#else
# כלול
// # define Wire.write (x) Wire.send (x)
// # define Wire.read () Wire.receive ()
#endif
סטטי uint8_t nunchuck_buf [6]; // מערך לאחסון נתונים של nunchuck,
// משתמש בסיכות יציאה C (אנלוגיות) ככוח וקרקע לנונצ'וק
סטטי חלל nunchuck_setpowerpins () {
# הגדר pwrpin PORTC3
# הגדר gndpin PORTC2
DDRC | = _BV (pwrpin) | _BV (gndpin);
PORTC & = ~ _BV (gndpin);
PORTC | = _BV (pwrpin);
עיכוב (100); // חכה שהדברים יתייצבו
}
// לאתחל את מערכת I2C, להצטרף לאוטובוס I2C,
// ותגיד לנונצ'אק שאנחנו מדברים עם זה
static void nunchuck_init () {
Wire.begin (); // הצטרף לאוטובוס i2c כמאסטר
Wire.beginTransmission (0x52); // העבר למכשיר 0x52
#if (ARDUINO & gt; = 100)
Wire.write ((uint8_t) 0x40); // שולח כתובת זיכרון
Wire.write ((uint8_t) 0x00); // שולחים נשלחו אפס.
#else
Wire.send ((uint8_t) 0x40); // שולח כתובת זיכרון
Wire.send ((uint8_t) 0x00); // שולחים נשלחו אפס.
#endif
Wire.endTransmission (); // להפסיק לשדר
}
// שלח בקשה לנתונים לנונטאק
// היה "send_zero ()"
static void nunchuck_send_request () {
Wire.beginTransmission (0x52); // העבר למכשיר 0x52
#if (ARDUINO & gt; = 100)
Wire.write ((uint8_t) 0x00); // שולח בייט אחד
#else
Wire.send ((uint8_t) 0x00); // שולח בייט אחד
#endif
Wire.endTransmission (); // להפסיק לשדר
}
// קידוד נתונים לפורמט שרוב מנהלי ההתקנים Wiimote למעט
// נחוץ רק אם אתה משתמש באחד ממנהלי ההתקנים הרגילים של wiimote
char charic סטטי nunchuk_decode_byte (char x) {
x = (x ^ 0x17) + 0x17;
להחזיר x;
}
// קבל נתונים בחזרה מהנאנצ'וק,
// מחזירה 1 בקריאה מוצלחת. מחזירה 0 על כישלון
סטטי int nunchuck_get_data () {
int cnt = 0;
Wire.requestFrom (0x52, 6); // בקש נתונים מ- nunchuck
while (Wire.available ()) {
// קבל בתים כמספר שלם
#if (ARDUINO & gt; = 100)
nunchuck_buf [cnt] = nunchuk_decode_byte (Wire.read ());
#else
nunchuck_buf [cnt] = nunchuk_decode_byte (Wire.receive ());
#endif
cnt ++;
}
nunchuck_send_request (); // שלח בקשה לעומס הנתונים הבא
// אם קיבלנו את 6 הבתים, אז הדפס אותם
אם (cnt & gt; = 5) {
תשואה 1; // הצלחה
}
להחזיר 0; // כישלון
}
// הדפיס את נתוני הקלט שקיבלנו
// אורך נתוני אקסל 10 סיביות
// אז אנו קוראים 8 ביטים, ואז עלינו להוסיף
// על 2 הסיביות האחרונות. זו הסיבה שאני
// להכפיל אותם ב -2 * 2
חלל סטטי nunchuck_print_data () {
סטטי int i = 0;
int joy_x_axis = nunchuck_buf [0];
int joy_y_axis = nunchuck_buf [1];
int accel_x_axis = nunchuck_buf [2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf [3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf [4]; // * 2 * 2;
int z_button = 0;
int c_ כפתור = 0;
// byte nunchuck_buf [5] מכיל ביטים לכפתורי z ו- c
// הוא מכיל גם את הקטעים הפחות משמעותיים עבור נתוני מד האצה
// אז עלינו לבדוק כל פיסת בייט תוצרת [5]
אם ((nunchuck_buf [5] & gt; & gt; 0) & 1)
z_ כפתור = 1;
אם ((nunchuck_buf [5] & gt; & gt; 1) & 1)
c_ כפתור = 1;
אם ((nunchuck_buf [5] & gt; & gt; 2) & 1)
accel_x_axis + = 1;
אם ((nunchuck_buf [5] & gt; & gt; 3) & 1)
accel_x_axis + = 2;
אם ((nunchuck_buf [5] & gt; & gt; 4) & 1)
accel_y_axis + = 1;
אם ((nunchuck_buf [5] & gt; & gt; 5) & 1)
accel_y_axis + = 2;
אם ((nunchuck_buf [5] & gt; & gt; 6) & 1)
accel_z_axis + = 1;
אם ((nunchuck_buf [5] & gt; & gt; 7) & 1)
accel_z_axis + = 2;
Serial.print (i, DEC);
Serial.print ("\ t");
Serial.print ("שמחה:");
Serial.print (joy_x_axis, DEC);
Serial.print (",");
Serial.print (joy_y_axis, DEC);
Serial.print ("\ t");
Serial.print ("acc:");
Serial.print (accel_x_axis, DEC);
Serial.print (",");
Serial.print (accel_y_axis, DEC);
Serial.print (",");
Serial.print (accel_z_axis, DEC);
Serial.print ("\ t");
Serial.print ("אבל:");
Serial.print (z_button, DEC);
Serial.print (",");
Serial.print (c_button, DEC);
Serial.print ("\ r \ n"); // newline
i ++;
}
// מחזיר מצב כפתור: 1 = לחוץ, 0 = לא מודפס
static int nunchuck_zbutton () {
להחזיר ((nunchuck_buf [5] & gt; & gt; 0) & 1)? 0-1 // וודו
}
// מחזיר מצב כפתור: 1 = לחוץ, 0 = לא מודפס
static int nunchuck_cbutton () {
להחזיר ((nunchuck_buf [5] & gt; & gt; 1) & 1)? 0-1 // וודו
}
// מחזיר ערך של ג'ויסטיק ציר x
סטטי int nunchuck_joyx () {
להחזיר nunchuck_buf [0];
}
// מחזירה את ערך הג'ויסטיק של ציר ה- Y
סטטי int nunchuck_joyy () {
להחזיר nunchuck_buf [1];
}
// מחזיר ערך של מד תאוצה ציר x
static int nunchuck_accelx () {
להחזיר nunchuck_buf [2]; // FIXME: זה משאיר 2 סיביות מהנתונים
}
// מחזיר ערך של מד תאוצה ציר y
סטטי int nunchuck_accely () {
להחזיר nunchuck_buf [3]; // FIXME: זה משאיר 2 סיביות מהנתונים
}
// מחזיר ערך של מד תאוצה ציר z
static int nunchuck_accelz () {
להחזיר nunchuck_buf [4]; // FIXME: זה משאיר 2 סיביות מהנתונים
}
int loop_cnt = 0;
בתים joyx, joyy, zbut, cbut, accx, accy, accz;
void _print () {
Serial.print ("\ tX Joy:");
Serial.print (מפה (joyx, 15, 221, 0, 255));
Serial.print ("\ tY Joy:");
Serial.println (מפה (שמחה, 29, 229, 0, 255));
}
int joyx1 = 129; // 15 - 221
int joyy1 = 124; // 29 - 229
הגדרת ביטול () {
Serial.begin (9600);
nunchuck_setpowerpins ();
nunchuck_init (); שלח את לחיצת היד
Serial.println ("מוכן Wii Nunchuck");
pinMode (3, פלט);
pinMode (5, פלט);
pinMode (6, פלט);
pinMode (9, OUTPUT);
// סוג ();
}
לולאת חלל () {
אם (loop_cnt & gt; 10) {// כל 100 mss מקבלים נתונים חדשים
loop_cnt = 0;
nunchuck_get_data ();
zbut = nunchuck_zbutton ();
joyx = nunchuck_joyx (); // 15 - 221
שמחה = nunchuck_joyy (); // 29 - 229
_print ();
}
loop_cnt ++;
אם (zbut == 1) {
סוג ();
zbut = 0;
}
אחרת {
אם (joyx & gt; (joyx1 + 20)) {
int speed1 = מפה (joyx - joyx1, 0, 80, 40, 255);
speed1 = אילוץ (speed1, 0, 255);
analogWrite (6, 0);
analogWrite (9, speed1);
}
אחרת אם (joyx & lt; (joyx1 - 20)) {
int speed2 = מפה (joyx1 - joyx, 0, 90, 40, 255);
speed2 = אילוץ (speed2, 0, 255);
analogWrite (6, speed2);
analogWrite (9, 0);
}
אחרת {
analogWrite (6, 0);
analogWrite (9, 0);
}
אם (שמחה & gt; (joyy1 + 20)) {
int speed3 = מפה (שמחה - joyy1, 0, 80, 40, 255);
speed3 = אילוץ (speed3, 0, 255);
analogWrite (3, 0);
analogWrite (5, speed3);
}
אחרת אם (שמחה & lt; (joyy1 - 20)) {
int speed4 = מפה (joyy1 - joyy, 0, 90, 40, 255);
speed4 = אילוץ (speed4, 0, 255);
analogWrite (3, speed4);
analogWrite (5, 0);
}
אחרת {
analogWrite (3, 0);
analogWrite (5, 0);
}
}
עיכוב (1);
}
סוג חלל () {
int rltime = 200;
// digitalWrite (6, 1); // מקור
// digitalWrite (9, 0);
// digitalWrite (3, 1);
// digitalWrite (5, 0);
// עיכוב (1000);
// H ===============
// digitalWrite (3, 0); // רגע
// digitalWrite (5, 0);
// digitalWrite (6, 0);
// digitalWrite (9, 0);
// עיכוב (250);
// digitalWrite (3, 0); // up
digitalWrite (5, 1);
עיכוב (500);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (3, 1); // למטה
// digitalWrite (5, 0);
עיכוב (250);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
// digitalWrite (6, 0); // מימין
digitalWrite (9, 1);
עיכוב (זמן אמת);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
// digitalWrite (3, 0); // up
digitalWrite (5, 1);
עיכוב (250);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (3, 1); // למטה
// digitalWrite (5, 0);
עיכוב (500);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
// digitalWrite (6, 0); // מימין
digitalWrite (9, 1);
עיכוב (זמן הפעלה);
// I ==========================
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (3, 0); // למעלה
digitalWrite (5, 1);
עיכוב (500);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (6, 0); // מימין
digitalWrite (9, 1);
עיכוב (100);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (6, 1); // שמאל
digitalWrite (9, 0);
עיכוב (זמן הפעלה);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (6, 0); // מימין
digitalWrite (9, 1);
עיכוב (100);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (3, 1); // למטה
digitalWrite (5, 0);
עיכוב (500);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (6, 0); // מימין
digitalWrite (9, 1);
עיכוב (100);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
digitalWrite (6, 1); // שמאל
digitalWrite (9, 0);
עיכוב (זמן הפעלה);
digitalWrite (3, 0); // המתן
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
עיכוב (250);
}
לאחר ההפעלה מכשיר שהורכב כהלכה מתחיל לעבוד מייד. Nunchuck הוא ג'ויסטיק אנלוגי, כך שתוכל לשלוט לא רק על הכיוון, אלא גם על מהירות התנועה. ארדואינו משתלט על בקרת המהירות של PWM. אם תנועה לאורך הצירים מתרחשת בכיוון ההפוך, יש להפוך את המנוע המקביל. על ידי הצבת הסמן בערך באמצע המסך ולחיצה על כפתור Z, אתה יכול לגרום למכשיר לכתוב אוטומטית את המילה HI.