2010年4月19日 星期一

一個A/D 的系統應用問題

 

來講一個系統應用的觀念,如果您也是常寫一些MCU 韌體程式的話,或許,會有一些幫助吧。

尤其是作一些機電整合的韌體程式,

寫這種程式,您就不要把那一般寫LED 跑馬燈的程式觀念拿來湊合。

我個人覺得:如果,只是要您寫個簡單的I/O 控制程式,或是一個簡單的步進馬達控制程式,

您可能就是把我們手指頭上的十個手指拿出來湊合的寫。

反正是程式嘛,就是幫我們人腦做事的嘛!

不過呢...說也奇怪,現在因為我國的電子產業發達,會寫韌體程式的工程師滿街都是,

大家也都習以為常,所以啦~也沒有人在乎每個人寫程式的風格或技巧。每個公司裡,

都會把新人當舊人用----意思就是說:您來公司上班,這些寫程式的觀念就應該在上

一家公司時,就要被教導或訓練的...就像我們的中等教育一樣:

喔...國中時,老師說:這個題目以後您們高中老師會教;

高中時,老師說:這個題目您們國中老師就有教了,我不用再教一遍了。

結果,還是靠學生自己自求多福!

今天我們來講一個一般系統輸入參數的處理問題,

譬如說是一個類比輸入參數(A/D Parameter)。

我們都知道:雖然是類比輸入,但是我們在韌體程式的讀取過程,

卻仍然是數位分時處理方式(Discrete)。還是得一個、一個值慢慢讀進來。

難免就會發生所謂多久取一個值?!(連續性)...還有一個很重要的觀念:

軟體濾波處理。(Filter)

硬體電路上的濾波電路是鐵定有的(一般都只是低通濾波),

但您怎麼知道輸入的值會不會有波動峰值呢?瞬間的變化時合理嗎?!

尤其是一些屬於比較機械特性的參數,譬如環境溫度、電瓶電壓等...

這些東西都是屬於自然現象的參數。(廢話...這種東西才需要A/D啊)

所以,在軟體上也必須有一些軟體濾波作法,,,我相信如果您幸運一點的話,

剛好有個老鳥工程師願意帶您,而也願意傾囊相授教您...

您可能就知道這個東西就是:讀個十遍或二十遍,然後取平均就好了!????????

(人家教您的口頭禪:去極值,取均值。)

------------------------
以前我也是這樣子作,因為大家受的教育是一樣的,而且如我所說的:

就是把我們手指頭上的十個手指拿出來湊合的寫!!不是嗎?!

反正這種東西就當小學算術拿出來用吧!所以才有人信誓旦旦的說:

"我國中就開始寫程式了。"

對啊!我國的電腦教育多成功啊,連中小學生都會寫程式啊,

那為什麼全世界有名的軟體公司都沒有在我國呢?!那我們搞的系統東西為何還

那麼不精緻呢?!等您看完我這一篇文章之後,您就知道為什麼了...好~

我們來解釋:什麼是濾波器,所謂濾波器有所謂的一階濾波器(First Order Lag Filter)

那個二階以上的就不要講了!反正,一階的作法都沒有多少人知道,幹嘛講二階的呢?!

其實,這些觀念都是我們在學校的工程數學裡都有教的,只是我們都不會應用。

(所以您就不要說國中就有教了!要不然,我們幹嘛還要讀到研究所後才去上班寫程式?!

反過來講:如果您念到大學畢業,然後寫程式都沒用到學校教的,那幹嘛念這麼多?!

一般一階濾波的公式就是:

 Value(n) = Value(n-1)+ KF(RawValue - Value(n-1))

其中: Value(n) 就是我們要求的新值, 

 Value(n-1) 就是我們的上一個值,中間有個時間差(t)。

 RawValue 就是我們一般從A/D 裡讀到的原始值,就是未濾波值。

 KF 就是濾波常數。

-----

這樣的公式,大家都會,在學校、補習班老師也拿這個出個一兩百習題給您作,

考研究所時也拿出來考!結果,大家考過之後成績都不錯...

然後出社會要寫程式時,就全忘光了,不知道拿出來用?

(說真的~還真的不知道怎麼用呢!)

還記得以上我提到所謂數位分時取樣(discrete)及一階濾波觀念,他牽涉到一個時間觀念。

所以啦...在新舊值之間,就存在一個很自然的物理特性,

在數學上我們也稱之為自然對數(Exponential)!

(查一下維基百顆的說明吧:這下您就懂了吧!

The exponential function is used to model phenomena when a constant change in the independent variable gives the same proportional change (increase or decrease) in the dependent variable)

而這個自然對數就是有時間觀念在裡面...因為很簡單,我們在工程上無論是機械或是電子,

我們都可以用這個自然對數來描述參數變化的前後關係...而上式中的那個KF 就是這個東西。

 KF = 1-e**(-Looptime/T)  where T = Time Constant of the filter。

這個式子是不是從您學校畢業後,再也沒出現在您的工作領域了?!

更不用說:您在寫韌體程式?!

那您就好奇了...這個東西要怎麼用?!...這跟我用一般A/D 讀電壓有關係嗎?!

那我們來作個簡單的實驗:譬如您一個簡單的電瓶電壓為 30 V。

您該如何即時來處理這個電壓變化呢?!譬如:

您每 15 mSec 讀一次 A/D ,然後讀十遍(150 mSec)之後,您才得到一個新的平均值。

當然啊,老前輩會跟您說:您還要在程式裡,加入一段判斷式:萬一誤差太大的,

就捨棄不納入平均計算。什麼是誤差太大?!基準是什麼?!為什麼要讀十遍?!

讀八遍不行嗎?!讀16 遍不是更好嗎?!直接右移四次不是更好嗎?!...

萬一有一次捨棄了...剩下15 個值時?怎麼辦?!...

----那您跟我說:這樣子的推理觀念的數學依據(科學依據)是什麼?!大家高興就好?!

那做出來的東西,他今天高興就正常...明天他不高興就給您出狀況...那大家幹嘛還學科學?!

所以依據工程數學上的式子解釋:如果您依據一階濾波器的公式,

您只要在每兩個15 mSec 之間就可以取得一個濾波後的新值...

上式中的 Looptime 就是您這個 15 mSec~

而時間常數您可以取 500mSec。在機械上或是許多類比訊號上是綽綽有餘的。

好~我們在依據上述的公式來算:

如果您電瓶電壓的舊值是 30 V...當您讀到新的A/D 值為 40 V時。

好吧 ...這個值算誤差太大呢?還是合理?!...原來十根手指頭的算法,就沒有章法了。

但如果我們把他真正的套到上述的公式裡:我們以一階濾波器原理公式:算出的答案是:

 Value(n) = 30 + (1-e**(-15/500))(40-30)

  = 30 +(0.02955447)*10 = 30.2955447 V。

以一般自然現象的結果來看:瞬間40 V 我們認為是不合理的,

但如果經過 500 mSec 的連續讀到這個值時,這個東西可能是真的值了...

但以我們這個一階濾波器公式來看,,,他 500mSec後的值也差不多這個值了!

不信您可以實際去算一算。

(注意喔,.當您第二次帶公示時,這個Value(n-1) 是30.2955447 而不是30 !!

依此類推...(500 mSec 大概要算34 遍)。

好了...這個答案跟您說:您根本不需要去15 mSec 讀十遍...還在那取其中幾次算?!

...500 mSec 您算三遍,也不一定比較準...程式在判斷式上,還要寫個落落長...

也不知道在算什麼?!也沒工程數學根據?下回寫程式還是心裡虛虛的!

------

好了...本單元的議題講完了。大家都應該知道結果了吧...有那麼簡單嗎?!

但問題來了...您知道這個自然對數的值是多少嗎?! e = 2.718281828(維基百科) !

如果您是用PC 來寫程式,當然沒問題啊...用Double Floating 宣告,給他用力的

往下算就對了!但很不幸的 ,一般這一種應用都是在單晶片微處理器(微控器)上,

如果更不幸是8 Bits 的MCU 的話!(應該幾乎都是吧!)那就更不幸了...

唉~算了...我們還是回到十根手指頭算吧!

所以,您就知道為什麼您寫韌體程式老是沒有成就感的道理了吧!...

當然不行這樣子啊...我們還是得把這個工程數學給套進韌體程式才行啊...

我就先賣個關子,讓大家當作習題練習一下...

先跟各位講個答案:在一個8 Bits 的引擎控制單晶片的韌體程式裡,

這一段稱為First Order Lag Filter,

他的程式大小是(用組合語言寫的...) 32 Bytes,

執行時間是 87~88 Cycles(當KF = 0時是12 Cycles)。

提示:老話題...您還是得用八位元的思維去推導這個運算式...一切就變得很簡單了

所以,下回您要搞什麼引擎控制器(什麼ECU)...就不要拿著手上十個手指頭,

扳一扳~掐指一算,就劈哩啪啦亂搞...因為下回您不知道您要碰到什麼奇怪的自然現象...

而您的工程數學基礎都不在!

-----------------

續篇連結:

2.一個A/D 的系統應用問題(續篇-實驗結果)

3.一個A/D 的系統應用問題(續篇-精進版)

4.一個A/D 的系統應用問題(續篇-範例版)


 

14 則留言:

  1. 完了~我工數都只有60分耶~那樣一定不知道答案的,我就是那種寫了一堆程式,試著讓結果可被接受,但是所有的技巧毫無科學理論可言的工程師...滿失敗的..T_T..

    回覆刪除
    回覆
    1. 不要灰心...我大學的工程數學也是低空略過的。
      因為我那個工程數學教授也不會寫程式!所以,他可能也不知道這個東西怎麼跟
      寫程式搭上關係的...所以,也不會要求學生的!...只要會考試就好了。

      刪除
  2. 可惡...要是早些年搞touch panel有看到您這篇大作就好了,就不用蠢蠢的平均了(不過話說原作者也是台大畢業的高材生...可見能結合理論與實務的人畢竟是少數阿)

    回覆刪除
    回覆
    1. 其實,您也不要怪那個高材生...如果他當初是選擇出國進修,受的訓練與視野就是有一點不一樣~或許結果是不一樣了!
      因為他選擇留在國內比較不長進的企業中,老闆只是希望趕快把東西弄出來,
      所以,那些學校理論就先丟一邊...最後差別的也只是:高材生K 規格與腦筋轉快一點..作法基本上都大同小異了。---唉~近朱者赤啊!

      刪除
  3. 如果我記得沒錯,取平均其實也是一種低通濾波器,是 FIR (Fintie Impulse Response) 的數位低通濾波器,階數大約要十階才能在增益上與您所使用的一階低通濾波器類似。
    您所使用的
    Value(n) = Value(n-1)+ KF(RawValue(n) - Value(n-1))
    是屬於 IIR(Infintie Impulse Response) 的低通濾波器。
    其實
    Value(n) = a*Value(n-1) + (1-a)*RawValue(n-1)

    也是另ㄧ種一階的 IIR(Infintie Impulse Response) 低通濾波器。只是我記不得 a 與頻寬的關係了。
    和您所用的比起來,在增益上沒有太大差別,但相位上就差異頗大了。
    應該還可以有很多種選擇的。 :-B

    回覆刪除
    回覆
    1. 其實這兩個式子是有點類似的...如果您把
       KF = 1-e**(-Looptime/T)  帶入展開...
      您的推論已經很接近我的答案了...因為如果要運用8 bits 的運算式的話,
      就必須先推導式子成您所說的格式 。
      只是一定要弄清楚a 與時間關係(頻寬),因為這就是決定那個 e 值。
      所以,在韌體程式中,到底多久取一次RawValue 就是要決定那個KF (類似您的式子中的那個a),
      我是不知道那個取十個平均的作法,在時間關係上的道理?!每10 mse ?!20 msec ?! 他的道理?!...
      後來我發現:作法或許很多,但要套進程式的寫法,非常簡便也是一種選擇,畢竟單晶片的運算能力是有限的!...
      --------
      不過,非常謝謝您的分享...不錯,高手~受教了!謝謝!

      刪除
  4. 對於您關於 KF 的說明,因為是第一次見到,我很感興趣!有空也會想想如何與自己習慣的認知結合。
    在您的說明中,如果 looptime 代表的是程式取資料的時間間隔,我習慣稱呼它「取樣時間」。它的倒數就是「取樣頻率」,根據理論的說明,被取樣信號中所包含的信號頻率不可以超過取樣頻率的一半,這得靠外部的硬體電路濾波器或提高取樣頻率來達成,否則會發生 Aliasing (不知道中文該怎麼說)。
    因此,在數位濾波器中,取樣頻率的一半,就是我們在討論濾波器時的頻率上限。
    我是一個受科技制約的人,並沒有像您一樣花時間去思考「頻寬」與這一些係數的關係。通常我都是藉助電腦輔助軟體 MATLAB 來幫我分析濾波器的頻寬。
    因此平均值低通濾波器的階數如何決定,我得倚賴電腦輔助軟體來幫我才行。
    拉里拉雜的說了一些想與您交流的想法,或許您早已知道,請別介意!

    回覆刪除
  5. 又學了一個新觀念

    回覆刪除
  6. 可以參考:

    http://www.ieee.li/pdf/viewgraphs/harmonics.pdf

    page 20,21

    是同樣的作法

    回覆刪除
  7. http://www.ieee.li/pdf/viewgraphs/harmonics.pdf 上的說明其實沒有「賈老師的真老公」說的清楚。
    它上面所提到的低通濾波器
    y(n) = (beta/alpha)*y(n-1) + (1/alpha)*x(n)
    的直流增益(諧波分析時頻率為0,或是關於那一些要保留的低頻部份)並不一定是 1。

    Value(n) = Value(n-1)+ KF(RawValue(n) - Value(n-1))
    --> Value(n) = (1-KF)*Value(n-1) + KF*RawValue(n)
    在直流增益上就一定是 1 了。
    而且「賈老師的真老公」也給了我們一些 KF 值與頻寬間關係的線索。
    雖然 p.22 中所提到的一階低通濾波器系統(直流增益是1)
    輸出(s)/輸入(s) = (1/tau)/(s+1/tau)

    回覆刪除
    回覆
    1. Eric 老師 :
          謝謝您提供許多在數學式子與學理上的分析。
      您在此回應中幫我多推導整理式子之後,就點出一個在韌體程式上的結果了:
      因為 Value(n) = (1-KF)*Value(n-1) + KF*RawValue(n) 這個式子,
      就是我們要利用8 Bits 單晶片的無因次化的基礎了,因為KF 會是小於 1 的!
      (http://chamberplus.myweb.hinet.net/misc_1.htm  及

      http://chamberplus.myweb.hinet.net/ems_2.htm )
      所以在8 bits 的運算上 : KF 就是介於 0~255 之間了。
      其實,我之所以提這一個系統應用的想法是想藉由科學(數學)與工程之間關係,來佐證一個我們在寫韌體程式上的重要觀念:寫程式真的不是靠十隻手指頭數的數學~或是只用來敲鍵盤寫程式的!
      所有工程數學上的公式與學理,絕對不是只是拿來考研究所或是拿分數用的。
      更不是畢業後全還給老師,在工作上就全用不上了。那麼如果真的寫程式只是靠十隻手指頭數的數學~或是只用來敲鍵盤寫程式的!----那真的您要等著大陸人與印度人把您幹掉了...(您就會知道為何人家印度人寫程式比較厲害!)
      --- 老師,您們常用MATLAB 建立工程數學上的分析工具,這一點小弟真的很羨慕。我個人也非常期望我們國內工程上是有更多學術界與工程業界雙向交流的機會,否則,我們看到的就會是:外國人定規格,我們國內業者就找學生用十根手指頭看規格敲鍵盤...再來殺價競爭。
          我的經驗是:如果,您能在上機寫程式之前,能多一點數學與學理上的分析推導的話,您的程式技巧與韌體程式效能會很好...要不然,人家老外明明用ARM 搞出越來越好的產品時,...我們國內用ARM 的觀念卻是離這些觀念越來越遠的話,那當然我們工業產品的競爭力就越來越遠了。人家明明在 8 bits 時代就已經把這一套做得很好了,我們卻都還在期望等我有32 bits ARM 才能把事情做好;而人家用32 bits ARM把一些額外的功能作得更好時,我們卻就要燃燒工程師來彌補這一點落差...
            這一個簡單的數學系統應用的例子,我改天會用一個簡單的範例來說明的!
      不過,還是非常感謝老師您的留言討論,也希望您們在學術界上的努力,與學校教育培養上,能對我們國內業界有更好基礎...這一點我是已經做不到了。
       

      刪除
  8. 賈老師的真老公2010年4月24日 下午3:58

    補充說明一下:
      Eric 老師所提的那個
    關於常數信號 E 輸出響應的數學式
    S(t) = E*(1-exp(-t/tau)),tau 代表一階系統的時間常數。
    ----- 這一個式子應該就是我上述的那個 KF 的觀念吧?!Eric 老師~對不對?!
    因為我們如果把類比信號用數位取樣方式來處理化...就像我們把 Time Domain 轉到
    S Domain 來處理複雜的運算道理是一樣的...是不是?!老師!
    我說過:我以前工程數學也不好...真的是看了別人的韌體程式技巧後,才會有這樣子的領悟!
    因為我們在程式上要讀取類比信號,也只能每隔一個固定時間來讀...但我們在資料處理上,
    又得把他視為是一個工程上的類比結果來分析...所以,才會有這兩者之間數學與分析原理。
    好玩吧!...這應該比我寫那個USB 還有學問喔?! :P

    回覆刪除
  9. 謝謝您的分享我才有機會重新檢視一下這一個問題。我之所以對於這一個問題感興趣,是因為我的學生們也都是利用取平均值來做低通濾波的愛好者。如今有您這樣的討論,要求學生改用另一種方式、並且學學背後比較「難啃」的相關數學,似乎就容易多了!
    我在網路上找到這一篇討論一階數位低通濾波器不錯的文章
    1. 在您的文章中 KF = 1-e**(-Looptime/T)  where T = Time Constant of the filter
        如果我把它稍作修改,KF = 1-e**(-Ts/T) = 1-e**((2*pi*Ts)/(2*pi*T)) = 1-e**(2*pi*f/fs)
        其中 2*pi*time constant 以類比系統的觀點來討論就是以 Hz 為單位的頻寬 f 的倒數,Looptime(Ts)的倒數就是取樣頻率 fs。
     繼續修正
        KF = 1-e**(2*pi*f/fs) = 1-e**(pi*f/(fs/2)) = 1-e**(pi*f/fn)
        fn 就是取樣頻率 fs 的一半,也是討論數位低通濾波器時的上限頻率。
    2. 對於像我這種習慣討論頻寬的人而言,這樣的數學是更容易接受,f 是想要的低通濾波器頻寬,fs 是取樣頻率,這樣就可以算出所需要的係數 KF 了!
    3. 我做了一些驗證,當 f/fn < 0.4 時,這樣的說法還算準,但當 f/fn 越接近 1 ,誤差就越大。
    4. 我會再找時間驗證 Value(n) = a*Value(n-1) + (1-a)*RawValue(n-1) 這一個低通濾波器在相位上,與您文章上低通濾波器的差異所造成的影響。在我印象中,是將類比系統數位化的方法做出來的,是我比較有感覺的數學式。

    5. 花了一些時間總算是吸收了您的想法,接下來除了回過頭驗證其它自己以前的想法外,也會介紹給學生知道,謝謝您!
    :-B

    回覆刪除
    回覆
    1. 因為這篇文章太有名了。

      連我自己也反覆地看了好幾遍,當初這篇文章是在舊版Yahoo Blog 發表的,

      回復的Eric 老師是龍華科大的老師。也不知道Eric 老師現在的網頁在哪了?

      其實還是非常感謝 Eric 老師的協助探討研究,我想許多工程數學的分析式子都有一些

      條件限制的。我文中也有提到:這一種簡易的濾波程式技巧是用在一些機電系統所使用,

      代表他在系統的頻寬要求是比較低,像是機械動作或是溫度、電瓶電壓等物理參數。

      當然如果硬要套在所有AD 功能上,也未必全部適用。

      畢竟科學、數學分析方法是日積月累的。早期電子電機能處理的東西是比較一般性的工程事務,

      如果世界是走得越快,要求越高,自然就必須要有另一套新的理論分析才行。

      提出這一篇方法是我自己本身在許多系統應用上慣用的手法與技巧,不管MCU 是 八位元或

      32 bits ,道理是一樣的好用,大家就不妨的參考看看吧。謝謝。

      刪除