顯示具有 PPM 標籤的文章。 顯示所有文章
顯示具有 PPM 標籤的文章。 顯示所有文章

2016年8月8日 星期一

自製四軸直升機飛控板

基本上這個架構是自己陸續看一些東西後整理出來的一個大致的架構
目前input 跟output 部分都有經驗了,會等姿態的部分研究差不多後,就可以全部都整合都起來...




考慮到成本與實際上飛行時的載重,應該會採用這台450來當作載具測試
用普通的2212馬達/電變加上紅白機架兩千塊即可打發,撞壞比較不傷荷包



2016年8月7日 星期日

arduino 解析PPM 訊號


這是在弄X9D+ 搖控器控制jj1000四軸時,因為發現四軸飛在空中時偶爾會抖一下,debug後發現問題的紀錄
http://ddddiy.blogspot.tw/2016/08/x9d-nrf24l01-v2x2-protocoljj1000.html


PPM(Pulse code Modulation mode) 訊號格式可以參考這邊
http://diydrones.com/profiles/blogs/705844:BlogPost:38393

基本上就是把PWM 訊號全部編碼整合在一個pin 上
在遙控模型的領域內,PWM 格式"一般"定義如下

  • 每個clock周期總長20ms
  • 拉high 
    • 1ms: 通道最小值
    • 1.5ms: 通道最小值
    • 2ms: 通到最大值

而PPM 內每個通道用的時間相同,只是改成時間到時瞬間拉一下high(送interrupt)
可參考網路上這張圖
https://www.google.com.tw/search?biw=1280&bih=614&tbm=isch&sa=1&q=PPM+&oq=PPM+&gs_l=img.3..0i19l10.7835.7835.0.8134.1.1.0.0.0.0.54.54.1.1.0....0...1c.1.64.img..0.1.53.DsrA7tEbXa8#imgrc=68KP1G0WoL6ovM%3A

一開始先來個脈波,之後依各通道的值對應的時間到了送出一個脈波,最後low的時間夠長,可以用來判斷一個大週期的結束

舉個例子來說,假設共四通道,各通道的值為

  • CH1: 最小值
  • CH2: 中立點
  • CH3: 中立點
  • CH4: 最大值

實際上送出的訊號如下
|上一個週期| ↑↓(1ms)↑↓(1.5ms)↑↓(1.5ms)↑↓(2ms)↑↓(明顯大於2ms的時間) |下一個週期|
所以只要用中斷抓rising edge並計算間隔後,即可知道各通道對應的值,最後剩下來的時間,長度明顯大於2ms, 當作sync 訊號來判斷此次周期已結束
照這個設計來看,20ms 可放入8通道的訊號(9通道無法分辨sync)




來看一下之前控制jj1000四軸的程式,這個project一開始是clone網路上其他玩家的project
原本的設計有一些問題
https://github.com/goebish/nrf24_multipro/

原本的code做法如下

  • setup
  • loop
    • 確認protocol, 對RF 模組做初始化與對頻
    • 從Servo_data[chan]取出目前各通道的值
  • ISR
    1. 讀出目前timer值<==可得知經過多少us
    2. reset timer
    3. 小於510us 當作雜訊,紀錄長度
    4. 大於1910當作sync
    5. 其他則是將讀出的數據加上雜訊依序填入Servo_data[chan]
這個做法沒有判斷目前PPM 訊號的high/low,每次狀態改變都會觸發中斷,會造成中斷數量增加,且以PPM設計來說拉high時間短,很有可能掉中斷(level trigger的狀況,如果轉換過快,沒有在high or low停留一段時間,比較可能會漏掉),使得干擾等因速會影響到該大週期內,每個channel 的對應
以工作的經驗來說,這類型的訊號適合用edge trigger, 搭配PPM 的設計,使用rising edge trigger較合適
實際遇到問題,通常下一個大週期就會回復正常,但飛行時就會導致四軸在空中會突然抖一下

修正成下面的做法後調整PPM判斷參數與interrupt,中斷數量可以也少一半,且實際飛行也穩定多了
  • initial
    • PPM_IN_MIN=510
    • PPM_IN_MAX=2200
  • setup
    • PPM pin 設為input
    • 註冊ISR(rising)
    • 設定timer1 每1us增加1
  • loop
    • 確認protocol, 對RF 模組做初始化與對頻
    • 從Servo_data[chan]取出目前各通道的值
  • ISR
    1. 讀出目前timer值<==可得知經過多少us
    2. reset timer
    3. 目前timer小於PPM_IN_MIN當作雜訊,紀錄長度
    4. 目前timer大於PPM_IN_MAX當作sync
    5. 其他則是將讀出的數據加上雜訊依序填入Servo_data[chan]