2014年1月16日 星期四

【Arduino程式實作】機器娃娃 (wiichuck)

【實做影片】在開始介紹之前,先來看看機器娃娃做出來的效果








【緣起】
在閱讀「超圖解Arduino互動設計入門」一書時,對第11章操縱wii左手就留下了印象,但是覺得又要買轉接器(不像作者那麼強,可以自己銲),最麻煩的是那個機械手臂,應該做不來吧。

在一次上網找資料時,看到了國外maker僅了用簡單的材料就做出一個可用wii左手控制的娃娃,當下就覺得很有趣,而且也想自己應該也可以,於是上網買了轉接卡,找了一些材料做娃娃,當然這個娃娃的基本結構是與趙英傑老師書中的機械手臂相同的,於是便從影片、網路、書籍中,這邊看個概念,那邊用個library,這裡再借用一下例子,就開始拼拼湊湊了起來…





【使用軟體】arduinoIDE



【使用硬體及材料】
基本材料:arduino UNO r3 、Wiichuck(Wii左手)、Wiichuck轉接器V2.0、伺服馬達(2組,)



機器娃娃使用材料:餅干盒、花生土司夾心盒子、圖釘(扁頭)x4、輕質土(下圖中,在藍色圖釘上的那兩團)、積木、泡綿膠



【I2C 轉接器】

I2C(I-squared-C)是一種讓同一電路板的組件可以互相通信的一種介面(細節請參考邱小新筆記), 剛好Wii 左手採用的通訊也是用I2C標準,只是它的接頭是特別的,所以要用轉接器來連接arduino。下圖是在網路上買的轉接器,圖片左方的四個針腳,-與+分別接負電與正電,d與c是資料傳輸線,細節會比較複雜,還好國外高手已寫好的library,所以直接使用就方便多了(真是感謝)




【機器娃娃製作】
再來是機器娃娃本體的製作,下圖是餅干盒,剛好拿來做機器娃娃的大頭。



再來幫大頭加上表情


身體是用麵包盒子做的。


那伺服馬達要如何連到機器娃娃呢?9g伺服馬達本來就配有白色的十字或一字轉軸,試著用圖釘看看,剛好OK。

下圖是白字轉軸釘上兩個圖釘的情形,注意圖釘最後要壓到底,且圖釘不能卡到伺服馬達。



下圖是白色轉軸釘入機器娃娃身體的情形,另一邊我是用輕質土以白膠黏上(感謝太太的建議),過了一晚輕質土就會變硬(或許也可用徽章的小固定夾),要耐得住搖動而不脫落。



下圖是頭部連接身體的伺服馬達情形(用泡綿膠及膠帶固定)



下圖是伺服馬達與積木底座連接情形(用附的小鏍絲鎖上)


下圖是機器娃娃合體的情形(正面)

下圖是機器娃娃合體的情形(側面)



【arduino接線】


首先wii左手轉接器的4個針腳要接在arduino的4個類比輸入針腳(A2~A5),概念圖如下。




下圖是wii左手要連上轉接器的情形。這裡要特別小心,轉接器與wii左手接頭分別都有上下兩邊,一邊是3接點,一邊是2接點,兩邊都要吻合(雖然還沒接錯邊過,但看起來若接錯會讓正負電反接,不知是否會燒掉)。
下圖是轉接器接上arduino類比針腳(A2~A5)的情形



這樣wii左手接arduino就解決了,再來是伺服馬達,9克伺服馬達有三條線(SVG),中間的V要接上arduino的5V,G要接arduino的GND(我的G是褐色線),S是訊號線(我的S是橘黃色線),2台伺服馬達的S分別接上arduino數位接腳9與8,詳細接線如下圖。



【程式解析】本例的程式可在此下載

為了方便控制wii左手,本例有使用Wiichuck到這個library,因為不屬
內建的函式庫,所以必需另外下載(我是從coopermaa提供載點下載,連過去後畫面右下角有個Download zip即可下載),壓縮檔內的資料夾名稱要改為Wiichuck,並且要複製到arduino的libraries內。

若有困難,可先參考coopermaa文章:Wii Nunchuk 在 Arduino 的使用方法
確認可以捉到wii左手的X軸、Y軸及XYZ三個加速度等5個值。

機器娃娃程式內文如下:




---------------------------------------------------- 
#include <Servo.h>
#include <Wiichuck.h>
#include <Wire.h>
Servo servoX, servoY;
Wiichuck wii;
int posX, posY;

void setup(){
  servoX.attach(9);
  servoY.attach(8);
  wii.init();
  wii.calibrate();
}

void loop(){
   if (wii.poll()){
     if(wii.buttonC()){  //按下C鈕時,使用X軸加速度感測器
        posX = map(wii.accelX(), 250, 720, 10, 169);
        posY = 90;       

     } else if(wii.buttonZ()){  //按下Z鈕時,使用Y軸加速度感測器
        posX = 90;
        posY = map(wii.accelY(), 270, 750, 20, 159);       

     } else {    //不按鈕時,使用類比搖桿控制
        posX = map(wii.joyX(), 37, 235, 10, 169);
        posY = map(wii.joyY(), 25, 225, 20, 159);
        
        //類比搖桿5度內無效果,避免晃動
        if(posX >= 85 and posX <= 95)
           posX = 90;
        if(posY >= 85 and posY <= 95)
           posY = 90; 
     }      
     
     // 寫入兩個伺服馬達的角度
     servoX.write(posX);
     servoY.write(posY);
     delay(25);
   }
}

----------------------------------------------------
程式簡單說明:

程式庫方面,除了Wiichuck要另行安裝以外,另外兩個是arduinoIDE即有內建,Servo是控制伺服馬達,Wire是I2C使用,Wiichuck有用到Wire

函式setup內是伺服馬達與Wii左手的初始化



wii是Wii左手的物件,有下列幾個方法(method)來讀取感應的值:
    wii.joyX()是搖桿X軸的值
    wii.joyY()是搖桿Y軸的值
    wii.accelX()是X軸加速度感應的值
    wii.accelY()是Y軸加速度感應的值
    wii.accelZ()是Z軸加速度感應的值
    wii.buttonC()會回傳C鈕是否按下
    wii.buttonZ()會回傳Z鈕是否按下



函式loop內會不斷地把posX與posY兩個角度設定到伺服馬達上。若是按住Wii左手C鈕會用X軸加速度值使機器娃娃轉頭;若是按住Wii左手Z鈕會用Y軸加速度值使機器娃娃身體向前或向後。如果都不按鈕的話,就直接用搖桿XY軸控制機器娃娃。

map是arduino的內建函式,可以把一段範圍的值,對應到另一段範圍的值,因為Wii左手感應器傳回的範圍不會與伺服馬達的範圍(0~179)一樣,所以要做轉換。

在使用XY軸搖桿時,為減少晃動,如果角度與90度相差5度內, 則維持不動的90度。

【延伸閱讀】
書籍:超圖解Arduino互動設計入門第11章(趙英傑)

Wii Nunchuk 在 Arduino 的使用方法(coopermaa)



4 則留言:

  1. 很棒的應用,我也來搞給學生玩。感謝

    回覆刪除
    回覆
    1. 我給學生玩的心得是,一開始會覺得很新奇,但一下就退溫了,如果可以用S4A,讓學生實作出來一定更好。但用S4A就不能用wii chuck,如果要在S4A裡用wii chuck,也許可以過修改S4A Firmware的方式來做。

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 請問一下能把您做的arduino用wii控制機器娃娃線路圖完整接法用圖片方式上傳給我,看您影片上的線路接法身體卻不能上下控制,拜託一下,求解。

    回覆刪除