模擬示波器通常是什麼樣的架構什麼系統,如何編程(有人在日立V-422上編寫了一款FPS遊戲)?

日立V-422模擬示波器上編寫的FPS遊戲:

Quake running on an oscilloscope is the ultimate demake

當年第一款電子遊戲網球也誕生於示波器。

新的數字示波器大多是嵌入式系統乃至就是獨立的計算機,這個就很容易理解了。


題主的問題描述裡面都已經寫明了「模擬示波器」,先來複習一下模擬示波器的工作原理:

電子示波器的核心部分是電子示波管,它由電子槍、偏轉系統和熒光屏組成。電子槍通過發射高速電子流,經過由兩對金屬板組成的偏轉系統進行偏轉後打在熒光屏上使熒光材料發光,從而顯示特定的圖像。通過向控制偏轉板上加上特定的電壓,就可以把電壓變化的信號以圖像的形式顯示出來,這是電子示波器的基本工作原理。

假如在示波器的X軸偏轉板上加上鋸齒形的掃描電壓,並於Y軸上加上待觀察信號的電壓,那麼熒光屏上面顯示的是兩種信號的合位移,也就是待測信號的時域圖像。通過往Y軸偏轉板上加不同的待測信號,即可觀察到不同待測信號的時域圖像。

為了觀察到穩定的待測信號的波形,示波器工作過程中要求Y軸上待測電壓信號的周期為X軸上掃描信號的周期的整數倍。示波器內部具有同步觸發電路,能夠保證X軸信號與Y軸信號的周期同步,以便觀察到穩定的波形。

(以上文字本人保留版權)

在原理上分析,其實模擬示波器就是個高級點、靈敏點、顯像面積少點的CRT顯示器罷了,根本就沒有什麼架構系統那個高級的東西。。。實現這種效果的關鍵在於如何利用好模擬示波器的顯示功能。(順便說一下,只有比較高級的數字示波器才會帶獨立嵌入式系統,入門級的數字示波器一般就是用一兩片FPGA實現的)

對於新聞中的日立V-422模擬示波器,應該是年代久遠了。google上也難以找出完整的技術參數,但是唯一可以明確的一點是這是一款通用模擬示波器,這種模擬示波器內部是基本不可能存在可以編程的器件的,那就根本不存在編程一說。

現在再來分析如何做出FPS的功能。給出的鏈接中並沒有提供詳細的相關實現,但是我google到了原作者的博文:Quake on an oscilloscope: A technical report,大家可以到博客中詳細參考原作者的技術實現過程(部分內容需要科學瀏覽)。我就只做一個小小搬運工把他的博文的內容簡要翻譯一下。(下面的文字只是意譯,我根據問題描述補充了部分內容)

從網上找到的儀器面板圖是這樣的:

來源網路,侵刪

可以看見上面TIME/DIV旋鈕上面有一個X-Y檔,如果把示波器的旋鈕調到這個檔的話示波器就不會往X軸偏轉板上面輸出鋸齒波的掃描信號了,X軸偏轉板「直接」連上示波器的輸入通道1。這種情況下示波器的兩個輸入通道的輸入電壓直接決定了示波器熒光屏亮點的水平和垂直位置。換句話說,根據視覺停留的原理,如果能夠控制這個亮點移動以極快的速度移動,人眼就可以「看見」亮點移動的軌跡,這個亮點的軌跡是一個二維平面上的時域函數。眾所周知,遊戲畫面中的3D模型是由許多頂點組成的。那麼控制亮點在這些頂點之間移動,就可以畫出模型頂點之間相應的線段了。

如圖所示,軌跡是「連續」而不是離散的。

但是這裡有一個問題:實際顯示的圖像中線段並不一定都是連續(或者說首尾相接)的,而亮點的軌跡必須是連續的。作者為了解決這個問題採用的方法是將繪製圖像實際需要的線段的時間儘可能延長,然後在亮點移動到下一條需要繪製的線段的起點的過程中對當前繪製的frame進行快速縮放,這樣就可以在很大程度上隱藏不希望看到的亮點移動軌跡了。

在解決了繪圖的問題後,接著要解決的問題就是如何把信號從計算機輸出到示波器上面。示波器接收和顯示的都是電壓信號,這就意味著需要一些DAC將控制信號轉化為模擬量來控制示波器上亮點的位置及其移動軌跡。作者在這裡使用的是音效卡(音效卡基本都支持左右兩個聲道的立體聲輸出,正好滿足題中所要求的X-Y兩路信號)。顯示圖像的過程中,顯示設備的刷新率當然是越高越好,這樣遊戲玩起來才爽,所以作者一開始選擇了ASIO作為音頻後端協議,但是折騰了幾天都發不出丁點聲音(ASIO在win上的支持不好),後來換成了PortAudio才解決了問題。

然後就是音效卡硬體上的問題了,作者手頭上的所有音效卡硬體上都是配備了低通濾波器的,這樣通頻帶會下降,對應每一幀圖像上所能夠畫出來的線段數就會減少。作者設想調高音效卡DAC的轉換速率來解決這個問題,但是後來發現96k和44.1k輸出的畫面基本沒區別,就略過這個問題了。

到這裡,硬體上面的問題就基本解決了,接下來解決軟體的問題。簡單點說,作者改造了原遊戲中的3D引擎,利用了一些WinAPI實現了3D引擎和音頻合成器之間的通信管道。遊戲引擎的具體工作細節原文中有提到,這裡不再贅述。

在遊戲引擎中渲染出來的3D模型不能在示波器上直接顯示,因為其中有一些透明的幾何圖形(示波器只能顯示單色的線框,透明的幾何物體是不應該繪製出來的),並且渲染深度和實際希望的有些許出入(太大)。音效卡的輸出信號的速率有限,於是作者用C++寫了一個程序在管道的buffer上面對遊戲引擎輸出的圖像進行處理(主要是刪減不必要的線框),然後再輸出到合成器上。目前發現的最大的Bug是這個處理程序不能正確處理房間的「角落」,有時候顯示不出來牆角。

這樣一來,合成器上面每frame需要繪製的線段數控制在了1800條左右,合成器在沒有收到新數據的時候能夠自動讀取buffer裡面暫存的數據,自動刷新畫面。由於「亮點」是連續移動的,因此畫面刷新是以幾何物體的線段為單位進行的,每條線段的刷新率在5-20Hz/frame左右。並且由於音效卡上面有LPF,在一些線段的末端會有莫名其妙的抖動。作者在這個作品上面用了一塊廉價的USB音效卡,因此圖像上面也有一些莫名其妙的低頻雜訊。音效卡96k的最大輸出速率也極大地限制了每frame中能夠顯示的線段的最大數量。因此實際遊戲玩起來體驗不是很好。

以上大概就是technical report的內容概括了。實現這種功能的關鍵並不是「對模擬示波器進行編程」,而是巧妙利用模擬示波器的X-Y檔,將其改造為一個簡易的CRT顯示器。實際的計算操作,還是得交給電腦來完成的。


這個我本科的時候做過,用模擬示波器、單片機和一些標準器件完成。示波器設置成XY模式後可以接受X、Y、Z三路模擬信號輸入,(X,Y)控制坐標,Z控制亮度。只要分別產生周期同步的鋸齒波和階梯波作為X和Y輸入,就實現了在示波器屏幕上逐行掃描的效果,然後在單片機的內存里弄一塊區域作為輸出緩衝區,把它的內容逐點同步輸出到Z,也就通過控制亮度實現了圖形輸出。

如上圖,所有的同步信號都由單片機輸出,我是用硬體電路對行同步信號整形產生的鋸齒波,階梯波比較麻煩,所以直接拿單片機的DAC輸出了。

這樣弄好之後就能在示波器屏幕上顯示單片機輸出緩衝區里的點陣數據了,剩下的怎麼操作點陣數據都是軟體問題,是做個記事本還是做個刺客信條就隨你了。我做的時候就只是在屏幕上顯示了幾個漢字,然後用外接的4x4鍵盤實現了A~F這幾個字母的輸入還有移動游標、換行、刪除、複製粘貼等功能,都是用彙編寫的,就這麼點東西快寫吐了。

注意一下解析度的限制,為了讓圖像不閃爍,屏幕掃描的幀率至少得50Hz吧,在20ms內能掃描幾行就看單片機系統的時鐘周期了,我用的時鐘周期0.5us,1/4分頻後送到移位寄存器的,所以一屏最多10000個「像素」,最後設置的90行x96列。

鋸齒波發生器:

移位寄存器:

因為74LS166輸出的高低電平是5V和0V,示波器Z軸的接受範圍是-5V~+5V,所以用運放做了個電壓比較器放大了一下,讓屏幕上亮暗更分明一點。程序流程圖:

最後,珍愛生命,遠離彙編。


人家那是把遊戲圖像實時轉換成模擬波形信號再輸出到示波器上的。你都知道模擬示波器是個模擬設備了,模擬設備怎麼能編程。至於圖形怎麼轉成波形信號,就是另一個問題了。


示波器有個模式叫做XY模式,就和電視一樣。


我的大概思路是:通過matlab可以把圖片二值化,然後通過二值圖把圖像的邊界確定,再通過轉換變成電壓波形圖,在輸出給示波器


推薦閱讀:

有什麼好方法能把高數和編程聯繫起來么?
Android 應用中半透明狀態欄的原理是什麼?(有分歧故來提問)
碼農需要的基本款電腦是怎樣的配置?
C語言標準中為什麼不規定int類型的具體長度?
MATLAB面向對象編程是什麼樣的體驗?

TAG:編程 | 計算機 | 硬體 | 電子 |