2014年7月9日 星期三

用 AVR 控制 Wii Remote Camera

新玩具入手


這是 Wii Remote 前端的紅外線攝影頭
幾年前寫過一篇 在 Linux 下控制 Wii Remote 有描述過透過藍牙來聯繫 Wii Remote
接著再透過函式庫取得 Wii Remote 看到的紅外線點來搞些應用
這東西在當年可是領先的科技, 當年用攝影機做的紅外線點識別都是用 USB 攝影機
加上一台至少 P4 等級的電腦拼命運算, 攝影機解析度也只有 640x480
結果 Wii Remote  這顆攝影頭居然可以辨識 1024x768
而且最多四個點, 還只要兩顆電池就能驅動, 根本外星科技XD
據說是老任委託台灣廠商開晶片客製化的, 花了不少銀兩
不過這都是聽來的謠言就是了, 而且這也不是重點XD

幾年過去了, 老任也出新產品了, 不知道是不是這樣所以解禁了
坊間開始有副廠的 Wii 手把流竄, 以前一支 Wii Remote 要一張小朋友
現在, 一支 Wii Remote 加上 Nunchuk 只要三張國父啊, 真是夠殺
掏寶上更是出現一批好便宜的(?) Wii Remote 攝影頭模組
然後有日本人放出控制資料, 老外把它丟去用 Arduino 控制了一下
所以就有這篇文章

這顆攝影頭是個 i2c 設備, 它把影像解擷取以及分析的功能都做進模組裡了
所以不會有什麼 Camera Bus, 就只有少少的幾隻腳, 接線圖是這樣的

老外網站拿到的是有外殼的, 而我只買到裡面的模組, 所以線要自己焊
這沒什麼, 沒幾顆料, 簡單的
上圖畫的模組方向是有突起的那端朝下, 可參考本文第一張圖以及下面這張

它有做一個突起的卡榫, 安裝到 Wii Remote 時這卡榫是朝下的
把 VCC 接上 3.3V, SDL 和 SDA 接給 AVR, 還有 Reset 電路
和 AVR 類似, 電阻電容的組合, 然後給它振盪器
這顆振盪器要是有源的, 也就是這種大顆方形的
日本人的網站有用 NOT 閘搭配無源的石英振盪器做成一個有源振盪器
那個還要搞電路板, 而且面積不會比較小, 所以我比較傾向用方形有源振盪器
反正這兩個成本差不多, 選簡單的吧
振盪頻率老外寫 20-25MHz 都可以, 我就拿 24MHz 的
AVR 方面我的板子和接法同前一篇 用 PN532 讀取 Mifare 卡
由於我是上 Atmega32L, 一開始就是 3.3V 系統, 所以 i2c 可以直接接上 AVR
如果要接給 Arduino 就要準位轉換, 3.3V 轉接 5V, 可參考老外這篇

Wii Remote IR Camera Hack with Arduino Interface

軟體部份這貨的 i2c 位址是 0x58, 向左 shift 一位後加上 r/w bit 就可丟上 bus
主要參考這篇:

Hacking the Wiimote IR camera

基本初始化:
wiicam_write_reg(0x30, 0x01);
wiicam_write_reg(0x30, 0x08);
wiicam_write_reg(0x06, 0x90);
wiicam_write_reg(0x08, 0xC0);
wiicam_write_reg(0x1A, 0x40);
wiicam_write_reg(0x33, 0x33);

以第一行為例, 就是先在 i2c bus 上發送位址 0x58 << 1
然後第一個 byte 送 0x30, 表示寫入 0x30 這暫存器
第二個 byte 送 0x01, 表示寫入資料為 0x01
接著完成傳輸, 送出 stop 結束通訊
然後依序把上面那幾行都做完就完成初始化
這些值代表什麼意義沒人知道, 都是日本人反向工程抽出來的
若有興趣歡迎打電話給老任詢問 (通常會被罵XD)

該日本人的網站似乎有擋大中華的 IP, 我連進去都 403
要用 Google 翻譯去打開, 挺麻煩的, 所以直接參考老外的文章
除了上面那種初始化, 日本人寫另一種初始化, 可以設定感測器的敏感度
一共定義了四個參數, p0, p1, p2, p3

p0: MAXSIZE: Maximum blob size. Wii uses values from 0×62 to 0xc8
p1: GAIN: Sensor Gain. Smaller values = higher gain
p2: GAINLIMIT: Sensor Gain Limit. Must be less than GAIN for camera to function. No other effect?
p3: MINSIZE: Minimum blob size. Wii uses values from 3 to 5

目前我試基本初始化就會動, 剩下的就沒測了, 有興趣的可以自己試試
接著就依照以下順序去出初始化 (每一行是一次傳輸, 即有的暫存器會塞多個 byte)

0x30, 0x01
0x00, 0x02, 0x00, 0x00, 0x71, 0x01, 0x00, p0
0x07, 0x00, p1
0x1A, p2, p3
0x33, 0x03
0x30, 0x08

日本人提供了五組參數

Level 1: p0 = 0x72, p1 = 0x20, p2 = 0x1F, p3 = 0x03
Level 2: p0 = 0xC8, p1 = 0x36, p2 = 0x35, p3 = 0x03
Level 3: p0 = 0xAA, p1 = 0x64, p2 = 0x63, p3 = 0x03
Level 4: p0 = 0x96, p1 = 0xB4, p2 = 0xB3, p3 = 0x04
Level 5: p0 = 0x96, p1 = 0xFE, p2 = 0xFE, p3 = 0x05

最後是讀取資料, 先寫要讀的暫存器 0x36
然後讀取 16 個 byte 即可
從讀出的資料看來應該只有 13 byte, 第一個 byte 總是 0
然後第 2-4 個 byte 是第一個點, 5-7 個 byte 是第二個點...等
每 3 個 byte 代表一個點, 座標算法請見下面提供的源碼
不過日本人提供的資料是讀 16 個 byte, 我們就照讀, 別管它
這裡提供我寫的測試程式:

wii-cam.zip


以前面接線圖的模組方向為例, 這是攝影頭看到的畫面:

X 軸視角約 33 度, Y 軸約 23 度, 解析度 1024x768 (128x96 灰階感測器 + 8x subpixel analysis)
右上為座標 (0,0), 向左向下增加, 到左下角為 (1023,767)
資料出自 http://wiibrew.org/wiki/Wiimote
這裡有很多關於 Wii Remote 的技術資料

接著是我做的 demo, 使用 WT-10 板子


Wii Remote 接線, 沒幾顆料, 直接搭棚


然後是發紅外線的設備

就鋰電池和 IR LED 而已
本實驗室做過筆形的, 可參考這篇 製作指揮 Wii Remote 專用光筆
只是放倉庫懶得去挖 (正確說是找不到了XD)

讀取結果:

上圖黃色字是讀出的原始 16 byte 資料
藍色字是計算後的座標, 共四個點, 若座標都是 FF 代表沒資料

如果把 IR LED 傾斜一個角度會變兩點,  兩個 LED 就是四點


大致上就是這樣
至於這個能幹嘛...我也不知道耶XD
就懷念以前學生時代做的東西而買來玩
最多就加個 USB-serial 可以做有線的電子白板, 這樣就不用用 Wii Remote, 不用裝電池
不過因為不是藍牙所以軟體都要自己寫......
有興趣的用戶可以試試, 當個大學畢業專題應該還行XD


2017.02.26更新

重整資料時重新嘗試連結日文網站, 有一個能連了, 趕快截下來做紀念~
小ネタ 2008-009
日文內容, 能看得懂的就看吧XD

3 則留言:

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

    回覆刪除
  2. 您好請問這顆模組在哪裡可以買到呢?

    回覆刪除
    回覆
    1. 我是在露天拍賣買的, 不過我買的賣家已經不賣了
      可能只能買成品來拆了, 或是去掏寶網撈看看

      刪除

注意:只有此網誌的成員可以留言。