2014年3月16日 星期日

用 nRF24L01 自製無線閃光燈

本實驗室花了相當多的時間在搞相機週邊, 而這項計畫終於來到了終點
年初時把所有功能整合上一張板並送廠, 期望二月初能完成測試就結案
結果可惜遇上廠商過年機台維護延遲出貨, 接著又發現設計上的問題, 於是就拖到現在
這次的功能最早可以向前追溯到去年三月的文章  SONY NEX-5N 外接閃光燈
一年前知道閃燈外接的方法以後就想搞無線, 不過當時有其他計畫進行所以就一直延後
料則是前年的遙控音量文章裡有人回覆就決定了 (搬家後回覆消失)
這個想法在我腦袋中存了一年才實現, 不管怎麼說, 至少就是做完了

整套系統功能是這樣的:

控制 EF 鏡頭, 定期檢查當前焦距, 若有改變就查詢最大光圈值, 然後調整當前光圈大小
控制 E-TTL 閃光燈, 這只有按按鈕時才檢查, 因為閃燈觸發無法預測
若定期去探, 遇上剛好觸發就可能會有麻煩
每次設定閃燈或是有觸發時就透過 SPI 發出無線封包, 不論無線模組是否接上
可透過 UART 傳送無線的位址和通道, 供設定閃燈用, 當遇到干擾時可切換通道再試試
位址和通道設定寫入 AVR 內部的 EPROM, 關機後不消失

做的事情蠻多的, 已經用掉我這顆 AVR 的 8K 程式空間的 95%
所以把中文字型刪了節省空間, 想不到會被逼到走這步XD
拜託不要叫我用 assembly 寫最佳化, 我只是業餘搞好玩的, 不要這樣專業XD
或許可以換顆 16K 的 MCU 來測, 我選這顆是有許多接腳相容但硬體配置不同的 MCU
以上技術除了無線部份外統統有前文可參考, 也是一整合所學的板子
可點選 Camera 標籤來列出所有關聯的文章



先說明一下無線部份的內容, 這次採用的是 nRF24L01 的無線晶片
正確說是 datasheet 看 nRF24L01
可是模組上的料是 SI24R01, 一顆疑似由對岸生產的相容版晶片, 或稱複製品
連模組一起賣一片只要 50 台票, 我就買了幾片來當收發器
這種高頻 RF 的東西我完全不想自己畫, 因為哪裡出錯了我根本沒有能力除錯
它和電路板的鋪銅穿孔位置以及被動元件的用料很有關係, 基本上都是抄公板
既然都要抄了我買模組就是了, 我一點也不想改變設計, 那只是自討苦吃的行為

模組買來後就接上 SPI, 四線式, 文末會附電路圖, 就 MOSI, MISO, SCK, CS 統統接上
還要另外兩隻腳, CE 和 IRQ, CE 用來啟動 RF 傳輸, IRQ 則是傳輸上完成或是異常時提醒
CE 用一隻 GPIO 控制即可, IRQ 則要接上外部中斷腳, 我接在 INT1 上
CE 是高電位觸發, 把它拉高才會開始傳輸或接收, 它是用來控制 RF 的開關
因為 RF 是高耗能硬體, 以 WiFi 來說吃到 1W 都是家常便飯
所以無線傳輸晶片多會有這類接腳可以強制 RF 停止以免不預期的持續耗電
而這顆的 CE 除了開關 RF, 還主導傳輸的狀態控制, 只有打開它才會開始傳輸
IRQ 則是當傳輸有結果時提醒 MCU 用, 傳輸完成, 傳輸失敗, 接收完成等時候都會觸發
對於我的應用一定要接上中斷, 這樣我才能在最短時間內觸發閃燈以達到遠端觸發的效果
要是延遲太久, 相機都擷取完影像了閃燈還沒亮就沒用了

對這顆無線晶片傳輸時, SPI 的流程是這樣的:

CS 在高電位, 然後 CS 拉低, 此時傳出的第一個 byte 會被 nRF24L01 當成指令
不管要讀要寫, 第一個 byte 都是指令, 由這個 byte 來判斷要做啥
寫完或讀完後 CS 一定要拉回高電位, 表示完成操作, 所有指令都是如此

若和我一樣採用 AVR 系列 MCU 可以直接抄這段 SPI 初始化程式

void spi_init(void)
{
  /* port B in-out */
  DDRB |= (1<<4) | (1<<5) | (1<<7); /* CS, MOSI, SCK, as master */
  PORTB |= (1<<4) | (1<<5) | (1<<7); /* CS, MOSI, SCK, output high */
  /* Enable SPI, As master */
  SPCR = (1<<SPE) | (1<<MSTR);
  /* clear interrupt flag, set to 2X speed (Fosc/2) */
  SPSR = (1<<SPIF) | (1<<SPI2X);
}

由於 AVR 系列大多最快只有 16MHz, 而加上 SPI2X 這旗標 SPI 的 clock 也只能跑 8MHz
nRF24L01 可接受到 10MHz 的 SPI 時脈, 所以直接設定為最快不會有問題
然後 SPI 傳輸時就這樣

void spi_xfer(U8 *buf, U16 len)
{
  U16 i;
  U8 t = 20;
  SPSR |= (1<<SPIF);
  for(i=0; i<len; i++){
    SPDR = buf[i];
    t = 20;
    while((SPSR & (1<<SPIF)) == 0){
      if(--t == 0){
        // timeout, may error, exit
        return;
      }
    }
    buf[i] = SPDR;
    SPSR |= (1<<SPIF); // clear flag!
  }
}

也不用靠中斷了, 系統時脈的 1/2 傳送, 用 loop 確認一下就是了, 那不會太久
接著在寫成 nRF24L01 傳輸函數

void nrf2401_xfer(unsigned char cmd, 
                  unsigned char *arg,
                  unsigned char arglen){
  NRF_CS_0;  // 拉低 CS
  spi_xfer(&cmd, 1);  // 第一個 byte 一定是指令
  spi_xfer(arg, arglen);  // 剩下的是資料
  NRF_CS_1;  // 拉高 CS
}

剩下的程式丟這裡 nrf2401.c
TX 和 RX 初始化只差一行

nrf2401_set_reg(CONFIG, 0x0F); // enable 2byte crc, power up, PRX

這是 RX 要設的值, 以上這些參考程式僅供測試, 上面程式只有 TX 部份的中斷處理
如果要設計符合自己的應用請務必看完 datasheet
那個沒幾頁, 要有耐性, 不然會遇上一些奇怪的問題
這顆晶片看來是設計成多對一的無線傳輸
如果要一對多可能要不斷的重寫入裝置位址 (3-5 bytes 那個)
這對於一對多的閃燈可能不太有利, 因為每顆閃燈將不會是同時觸發, 而是依序觸發
發一個封包觸發, 然後改地址, 再發一個封包觸發第二顆, 以此類推

接著我測試時間延遲, 做兩張板, 一發一送, 都是相同電路只是上不同料
方塊圖大概就像這樣 :

以 11.0592MHz 的晶振接上 AVR, 然後從 NEX-5N 收外部中斷觸發閃燈
我的相機端 AVR 收到外部中斷後建立並發送觸發閃燈的封包
遠端 AVR 收到無線晶片的中斷後檢視封包內容, 確認要開閃燈後拉高 GPIO
我把收發兩端的這兩張板子同時接上示波器檢視時間差
量測 NEX-5N 端的 AVR 拉高閃燈 GPIO 和閃燈端 AVR 拉高閃燈 GPIO 的時間差
結果如下圖 :


大約是 325 uS, 即 0.000325 秒, 我不知道這是否算快
但至少跟得上我的 1/250 秒快門, 也就是和有線時拍出的相同

閃燈控制除了無線外, 這次還有一個小小的改進
那就是前篇 用 AVR 控制 Canon E-TTL 閃光燈 裡的 E-TTL 波型問題
這次加上 NE5532 這顆 OP 放大器

於是波型變成...

雖然還是不匹配, 但是從軟弱無力變成強硬 ! 贏了 ! XD



接著 demo


可以注意四周都沒有線, 這是無線觸發的

板子正面

之後 OLED 會往上折


本實驗室第 10 號板


左側兩張為外出版, 右側兩張為開發版
外出版偷掉 11.0592MHz 晶振, 反正也能正常觸發, 拔掉省空間XD

之後又購入了另一種模組

帶天線和強波晶片的模組, 信號更強可以打更遠
號稱最低傳輸速度下可發射一公里


加上天線後看起來非常具攻擊性(?)XD
哪有人閃光燈要加天線的啊臥槽

這裡附上 WT-10 的線路圖供參考

WT-10.pdf

這張板子完全不用跳線, 都是正確可用的, 只是有些電阻不上而有些要短路, 使它可以多用途
但是 layout 有問題, 我發現如果我手去碰到電路板它就有相當高的機率會掛
會不斷的 reset, 進入主迴圈 while(1) 後不會停下來, 就是一直重複執行 reset
我一開始以為是程式問題, 但是它有時就算開機什麼也沒做也是會掛, 只要我去碰它就會掛
後來隔離手和板子就能正常操作了, 非常奇怪, 只能往 layout 方向去查

加掛強波模組後實際測 200M 內保證可觸發, 再往外就沒測了
目前我這地區地狹人稠, 要找空曠空間不易, 後來有找到直線距離 300M 以上的地方
但我發現離到 300M 以後要找到我閃燈放哪還真有點難度, 我大概知道它在哪, 但很模糊
這讓我回想起當兵時 300M 迷彩靶和一粒米一般小, 隨便就脫靶了
當我在 300M 外尋找我的閃燈架設點時, 突然覺得這麼遠的觸發其實還蠻蠢的XD
自己都找不太到了是要閃給誰用啊 ! 不過既然都買了就要測, 這是規矩
改天我會跑到遠一點的空曠地區測試, 務求測到極限值為止
雖然我目前還不知道觸發距離達 300M 以上的閃燈可以拿來幹麻, 但我想有一天我會懂的(?)




更新
後來又做了些實驗, 像是分離接地, 電源重拉之類的

依然找不出問題, 於是回去看程式, 發現...
UART 中斷忘了關又沒拉高導致拼命觸發阻斷, 修掉以後一切正常
可能是因為工作關係, 養成有問題先怪硬體的好習慣 (被巴) XD
看來硬體是沒問題的, 不過料要改, 電源那裡給的電容太少, 加大就沒什麼問題了

接著拿 3D 印表機印個殼給它, 鋰電池用 Nokia 手機在用的, 升壓電源板也都放進去
NEX-5N 端安裝 WT-10 全上料版, 閃燈端 WT-10 為砍料版, 只夠點閃燈, 沒有 OLED
完整版 WT-10 收到 NEX-5N 閃燈觸發後以無線發送給下圖閃燈端砍料版 WT-10


然後就可以帶出去測, 戶外架環境 !


架好後開始跑 ! 跑到 500 公尺外拍一張 (焦距 55mm)


上圖中央區 100% 裁切:


500 公尺測試通過, 不過發現要在開闊區
在別的地方測過 300 公尺, 稍微有點阻擋就收不到了
500 公尺基本上就符合該模組的 spec 了 (低速一公里, 而我是最高速, 500 公尺差不多)
本來想測到極限, 看看能不上一公里, 但是 !! 看看上圖
500 公尺就只剩一個小點啦, 真是他X的沒意義啊XD

這裡提供閃燈效果測試, FF 會場上不需要大天線, 採用小型 PCB 天線版
可無線控制閃燈強度, 然後無線觸發閃燈, 全程都是無線通信

FF24 Cosplay  Day 1  Day 2


RELEASE NOTE:
============================
使用機身: SONY NEX-5N
使用鏡頭: SONY E Mount 18-55mm f/3.5-5.6 OSS
閃光燈: Metz 28AF-3C, WT-10無線接收器
延伸組件: 閃光燈濾色片, WT-10整合控制器
對焦形式: 自動對焦 + 人體校正 (DMF)
曝光策略: 人體控制 (M模式)
轉載須知:
盡量避免直連圖以免被視為違規使用, 其餘無限制, 可上傳至別的相簿, 亦不須註明出處

照片全部有調整, 調整方式 : 色彩平衡, 顏色重對應, 亮度, 對比, 銳利化, 貼除眼睛閃光, 調整時依據人體感覺, 如不精確純屬正常現象

4 則留言:

  1. 你好,請問一下這個無線傳輸模組能夠直接與智慧型手機對連嗎?

    回覆刪除
    回覆
    1. 我還沒聽過有誰家手機內建此款晶片
      所以應該是沒辦法直接對連
      要加裝硬體接到手機才可通信

      刪除
  2. 近段研究閃光燈,看到有這便宜的2.4g模組,但不知道延時誤差是否達到要求。沒想到對岸有人做了測試。有時間也去弄兩片回來試試。

    回覆刪除
    回覆
    1. 一發一收是沒問題, 但一發多個收時就難說了
      閃燈一對多的應用還蠻常見的 (雖然我目前還用不到)

      刪除

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