文章

顯示從 2016 起發佈的文章

[應用] 設計七彩 LED 燈與 MP3 音樂系統

圖片
        近期設計一套七彩 LED 燈與 MP3 音樂播放系統,兼具照明與音樂功能。基本功能是照明,類似壁燈的概念,當光感應偵測到白天或有其他光源時,自動關閉 LED 照明。一旦處於黑暗或低光源的環境,LED 燈便會開啟。此外,遇上停電時,鋰電池會提供一段時間的照明指示。除了照明功能之外,透過模式按鈕的切換,將系統切到 MP3 音樂播放模式,同時開啟 彩色 RGB LED 燈條的控制。         圖一是系統的方塊圖,主要包含一顆控制器晶片和 MP3 晶片,與鋰電池的充電電路,再加上一些 GPIO 的控制電路。在設計中,LED 燈要做到七彩顏色變化與明暗的差別,必須選具有 PWM 功能 的微控制器。這裡,我們採用 NXP LPC1111 控制器,當然啦!用其它控制器也行,只要晶片取得容易且開發環境熟悉,一般人都能實現出上述的系統。另外一點,設計時 LPC1111沒有用外部震盪器,而是使用控制器內部的振盪器,這樣省掉一顆震盪器零件。 圖一:LED燈與音樂系統方塊圖 影片:照明與音樂系統操作過程

[應用] ESP8266 WiFi to RS485 (MODBUS TCP to RS232)

圖片
元件介紹         ESP8266 是由大陸 樂鑫科技公司 所開發的 WiFi 模組,上面有數根 GPIO 接腳和 ADC,另外 Tx/Rx 接腳用來與其他模組通訊之用。由於這塊模組價格便宜,目前吸引很多創客 Maker 使用,更重要的是在 Arduino IDE 環境下就可以開發這 WiFi 模組的程式,下載 IDE 後可找到不少 WiFi 相關的範例程式可以研究,對於初學者來說實在是非常非常的方便。同時在網路上,不少創客 Maker 已經寫下開發的經驗文章[1][2][3],並且也有 YouTube 教學影片可參考 [4]。 設計說明         筆者在規劃 MODBUS 通訊與 RS485 的過程遇到配線牽線的問題,於是上網搜尋有關無線轉 RS485 的設備,搜尋結果出現的是藍芽轉 RS232。BT to RS232 經過 MODBUS 通訊測試後,通訊的反應不是很即時,感覺有點頓頓的,放棄使用藍芽的介面。再次搜尋 WiFi 轉 RS485 的設備,似乎找不到能同時支援 MODBUS 通訊,最後決定使用 ESP8266 模組加上 TTL 轉 RS485模組,如圖一所示,索性自行開發一個 MODBUS TCP (WiFi) to MODBUS 232 (RS485) 的系統。以實體層(physical layer)而言,我用模組兜出一個 WiFi 轉 RS-485 的硬體,在鏈結層(data link layer)方面,設計一個 MODBUS TCP 轉成 MODBUS 232 的系統,讓原本沒有網路接口的控制板多出了一個無線網路的操控介面。         簡單說明系統的運作,將 ESP8266 WiFi 模組設計成一個無線 AP,當筆電連接到這模組後,筆電便從這個無線 AP 取得一組 IP address。這時候,我們可以在筆電上寫個 TCP / UDP socket 程式,與模組建立一個 socket 連線 (筆者是使用 TCP port 502 for MODBUS)。我們在 Arduino IDE 環境開發 ESP8266 模組的程式,將無線網路收到的 MODBUS TCP 封包加工調整後轉換成 MODBUS RS232 封包,再從 RS485 線路傳送出去。同樣地,從 RS485 收到的MODBUS RS232

[筆記] SIP VoIP in Android background 避免被系統殺掉

圖片
        在前面一文 「 SIP Voip 在 Android 系統的開發 」 中,我設計了一個 SIP VoIP APP,但是遇到一個大問題 ---- 就是 APP 會被系統殺掉。為了解決這個問題,在網路上尋找各種方法,首先我們要先把 APP 拆成 Activity 和 Service 兩個部份,如下圖一所示。Service 負責透過 JNI 介面與底層的 SIP 、 Media Codec...等通訊,而 Activity 則負責使用者顯示的介面,一旦 Activity 關閉後,至少還有 Service 可以在後台繼續運行。 圖一:SIP VoIP 系統架構圖 Activity 與 Service 間的通訊         兩者之間的通訊分成 Activity 到 Service 的方向,以及 Service 到 Activity 的方向。先說 A 到 S 的方向,第一步就是 Activity bind Service,如下面的代碼。接著,建立一個與 Service 的連線,取得 mService 之後,便可以在 Activity 呼叫 Service 的函式了。可以參考網路上其他人的文章與範例說明。         Intent intent = new Intent ("com.altigen.siptalk.SipService"); bindService (intent, sc, Context.BIND_AUTO_CREATE); private ServiceConnection sc = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBound = true; LocalBinder binder = (LocalBinder) service; mService = binder.getSe

[應用] SIP Voip 在 Android 系統的開發

圖片
        大約二十年前,VoIP 網路電話技術如火如荼地發展,隨著 Ethernet 網路越來越成熟,網路品質也越來越穩定,辦公室的桌上話機逐漸被網路電話所取代,當時的思科 (Cisco) 就是網路界的霸主。當時我們開發網路話機是以 embedded system 為架構 的設計,如圖四所示,搭配 CTI 伺服器組成一套辦公室的電話系統解決方案。        近年來,隨著智慧型手機逐漸普及化,無線網路 (WiFi) 和行動數據的頻寬與通訊品質大幅提升,出現了許多軟體電話 (Soft Phone) 的 APP 。其實,這些軟體電話也是網路電話的一種,從過去的桌上型網路電話,進化成行動型網路電話。軟體電話也存在很久了,過去主要安裝在 PC 上,但因為使用者操作起來並不像網路話機的方便,早些年這種安裝在 PC 上的軟體電話多半不流行。拜智慧型手機的快速發展之賜,軟體電話找到發展的空間,像 LINE 、微信...等社群軟體都內建網路或視訊電話。本文最後有桌上型的網路電路與手機上的軟體網路電話之影片操作。         最近我開始研究 Android 系統與程式開發,並且打算把過去在 embedded system 的網路電話代碼移植到手機系統上。過去開發網路電話的程式代碼都是以 C/C++ 語言為主,然而 Android APP 卻多以 Java 語法為主,在本人的 「 Android NDK 開發的初體驗 」一文中,我找到如何將 C/C++ 程式碼移植到 Android 系統的方法。一般 Android 開發以 Java 為主,只需安裝 JDK 編譯環境,但為了整合 C/C++ 的代碼,我們 也 必須安裝 NDK 的編譯環境。下圖一所示是 JDK 與 NDK 在系統開發的架構圖,Java 與 C/C++ 之間存在一個溝通的介面,稱為 JNI (Java Native Interface)。         為何使用 NDK?在 [1] 有段文章提到,「如果應用領域是系統底層的硬件管理,圖像處理或者遊戲開發,這些更加注重實時性和程序效率的應用,將會考慮使用 Native 編程 」。另外一點,多數的 open source 都以 C/C++ 語法所開發而且幾乎相容於 Linux 環境,若想要移植到 Android 系統的話,則必須用 ND

[應用] STM32F373 控制板之自我測試程式

圖片
        這次為了某個控制器的案子,製作 120片STM32F373控制板,如圖一所示。從 PCB 製版到打件的過程,最終製作好的板子可能會出現不良,可能是元件不良,可能是打件不良,可能是 PCB 銅線斷了....等等。這些不良品如果要單靠手工一步一步挑出來,花費的時間將會很長,所以最好能靠板子本身的一些功能,設計一套自我測試的方法。 圖一:STM32F373控制板         STM32F373控制板上有 Flash 晶片、各有13組 DI / DO、兩組 AI 和一組 AO、包含 RS-232 和  RS485,如圖三右半圖所示。自我測試的概念,可參考圖三的方塊圖。要達到自我測試的功能,我先設計一塊測試電路板 (如圖二所示),這塊板子上面將 13組 DI 和 DO 對應自環起來 (loopback),再把 AI / AO 也自環。而 RS-232 和 RS-485 也可以對接,只要將 TX接對方的 RX,RX 接對方的 TX。剩下一個 AI,則設計一個可變電阻來測試它。         除了設計測試板之外,STM32上面也要寫一套自我測試的韌體。DI / DO 的跑馬燈,韌體先對第一個 DO 輸出,當第一個 DI 偵測到後,韌體再對第二個 DO 輸出。以此類推,DI / DO 就會如跑馬燈一樣一路往下走。假設有 DO 元件壞了,那麼 DI 就偵測不到變化,跑馬燈就跑不下去了,同理 DI 線路有問題的話,跑馬燈也會停止。         AI / AO 的自我測試,韌體會對 AO 輸出固定數值,每隔一段時間便增加數值,直到最大值。再從最大值往下遞減,直到最低值,以此反覆。因為 AO 的輸出,我們可以從 AI 偵測到數值的變化,藉這個方式驗證 AI / AO 元件與線路是否正常。如果 AO 元件有問題,AI 將偵測不到數值的變化,同理 AI 元件有問題,則數值將無法穩定遞增或遞減。         RS-232 / RS-485 的自我測試,韌體對 RS-232 送出一組字串,再檢查 RS-485 這邊有沒有收到。同樣地,RS-485 送出另一組字串,再觀察 RS-232 這邊有沒有收到。如果相關元件壞掉或者電路斷線的話,我們就能很快挑出有問題的板子。 圖二:測試電路板與待測的控制板 圖三

[筆記] Android NDK 開發的初體驗

圖片
        Android SDK 開發程式都以 JAVA 語法為主,不過有些以 C/C++ 語言編寫的程式碼想要用 JAVA 來重寫,恐怕花的時間將很長。由於 Android 平台是從 C/C++ 所開發而成,因此 Android 提供一套 NDK (Native Development Kit) 讓原本 C/C++ 開發人員也能將 C++ 語言移植到 Android 環境裡。之前我們在 Linux 環境下編譯成功的 C++ 檔案,打算移植到 Android 平台上,初次使用 NDK 編譯遇上不少問題,過程中我們將這些問題記下來並找到解決辦法,希望對後進者提供幫助,縮短開發時間。 <遇上 NDK 編譯的問題> 問題一: NDK compiler 對於資料強制型態較嚴格,底下有兩個案例          void *TimerManThread( void *arg )          {               printf("TimerManThread=%x\n", (unsigned int)arg);   /* 錯誤訊息 error: cast from 'void*' to 'unsigned int' loses precision [-fpermissive] */               printf("TimerManThread=%x\n", (unsigned int*) arg);   /* 解決辦法 */            }          void AChkPtr_(void *ptr)          {                unsigned ptrx = (unsigned) ptr;  /* 錯誤訊息 */                 unsigned *ptrx = (unsigned *) ptr;   /* 解決辦法 */            } 問題二: 與資料轉換或數字檢查相關,NDK 編譯所產生的錯誤訊息,如下。        error: 'toupper' was not declared in t

[筆記] Microsoft WDK 遇上 Intel Parallel Studio XE 2016 的問題

圖片
開發緣由        開發語音處理和加解密的產品,公司打算在 kernel mode 使用  Intel® Integrated Performance Primitives (Intel® IPP)  9.0 和 Cryptography 的函式庫。因此,分別安裝微軟的 WDK (Windows Driver Kits),以及英特爾的 Parallel Studio XE 2016。雖然 Parallel Studio 本身有自帶編譯器,不過我們最終要用在 OS kernel,所以必須以 WDK 為編譯器,再將 IPP 函式庫連結進來。 遇上問題        在 WDK 編譯代碼的過程遇上了問題,錯誤訊息如下。從訊息來看,連結時找不到 _byteswap_ulong 函式的定義,而 ComputeDigestSHA1.obj 這部分來自英特爾的 Cryptography 函式庫。       (pcpsha1ca_n0---ComputeDigestSHA1.obj) : error LNK2001: unresolved external symbol _byteswap_ulong       (pcpsha1ca_e9---ComputeDigestSHA1.obj) : error LNK2001: unresolved external symbol _byteswap_uint64        我在 WDK 目錄下找到 wdm.h 有定義 _byteswap_ulong 函式,屬於內建函式,而且在 WDK 裡面已經用 RtlUlongByteSwap 來代替上述的函式,難怪我從 WDK 裡面的所有 library 中始終找不到 _byteswap_ulong symbol。基本上,要解決這個問題只要將 Cryptography 重新用 WDK 編譯一次應該就能搞定了,可惜我沒有 Crypto 代碼,必須想其他方式解決。圖一所是為函式的完整定義。 圖一:函式在 wdm.h 原始的定義 解決方式        解決方式就是我重新定義這個函式,如下。利用 #pragma function 這個預處理指令,可參考  https://msdn.microsoft.com/zh-tw/librar

2016 金融危機四伏

圖片
        2016年開始出現一些金融風暴二部曲的言論,2008年當時因為次債危機造成雷曼兄弟投資銀行破產。因此,我們來觀察 2008年九月之前債券市場的變化。當年的背景環境是美國大選年,各國的股票市場漲到相對高點,早在 2008年年初債市的價格已經往下跌了,表示市場大資金不再追逐風險資產,造成債券價格下跌殖利率上漲的現象,應該說有些資金已經聞到不尋常的風險,逐漸撤離資金往安全資產流入。最終因為雷曼宣布破產,市場資金的流動性瞬間凍結,產生金融海嘯。         今年債券市場不斷地向下探底,資金不願追逐風險資產,似乎有金融風暴的 feel。雖然目前氣氛不像當年瞬間急凍,但是金融環境有感覺到越來越冷的趨勢。下面看幾檔熱門的債券基金,圖一是在台灣相當有知名度的聯博全高收基金,這檔基金專門投資世界各國高風險的垃圾債券,正所謂高風險高報酬 (配息率滿不錯的)。不過,在雷曼風暴前一年,基金淨值就見高點了,然後持續跌了一年,直到風暴發生才瞬間爆跌。這檔基金最近一年多也持續下跌,目前還沒見到底部現象。 圖一:聯博全高收債券基金         圖二是鋒裕策略收益基金,這檔基金比較偏重投資美國的債券,優質債券比例相對圖一的基金高。在雷曼風暴前,基金淨值相對維持區間,穩定配息。不過,雷曼風暴前幾個月,基金淨值出現快速往下,然後瞬間爆跌。由於當時流動性風險驟升,這檔基金肯定被大量贖回,價格猶如自由落體。最近一年來,這檔基金也被逐漸贖回,價格慢慢滑落,顯然有什麼不尋常的危機在醞釀中。 圖二:鋒裕策略收益基金         圖三是富蘭克林公司債基金,這檔基金主要投資美國公司的債券。由於美國升息以及油價大跌,頁岩油產業的經營越來越困難,造成公司債的價格大跌,距離 2008年金融風暴的低點已經不到兩成了。顯然美國公司的發債利率越來越高,對於體質不佳的公司,經營壓力大增,這可能會連帶影響美國金融業 (如果吃了太多不良資產)。 圖三:富蘭克林公司債基金         第四張圖是瑞銀新興市場債券基金,這檔基金主要投資新興市場的債券。不用想,自從美國 QE 退場後,新興市場的資金被大量抽離後,貨幣貶值引發發債的利率越來越高,價格越來越差。這檔基金淨值已經跌破金融海嘯的低點,應該說新興市場的經濟情況比 2008年還要慘。新興市場在當年只是遇上

[模組] 德州儀器 ADC 24-bit 類比訊號擷取模組 (資料擷取)

圖片
前言         這次接到一個任務,內容是類比訊號的資料擷取,CNC 加工機上面有不少感測器,其中震動感測和電流感測是我這次所要擷取的資料。原本連接在加工機上已有兩個 ADC 資料擷取裝置:研華 USB-4716 和國家儀器 NI-9234,這兩個設備將收集到的資料透過 USB 傳到 PC 端。這次,我必須想辦法將其取代掉,再以 PLC 控制器取代 PC。         首先,這兩個設備的主要功能是類比訊號擷取器,用來收集加工機上面的震動訊號和電流訊號。加工機上面安裝了一個震動感測器 (Dytran 3055B3),將震動訊號轉成電壓,再由 NI-9234 將電壓轉成數位資料。另外,加工機上面也安裝一個電流感測器 (Topstek TU12P10A),將電流轉成電壓訊號,再由研華 USB-4716 將電壓轉成數位資料。首先,我先查詢了 NI-9234 和 USB-4716 資料解析度,分別是 24-bit 和 16-bit,於是從淘寶網站上找到一個 ADC 16-bit 的模組,而且具有八個通道,正好能滿足需求,所以買來研究看看,如圖一所示。這模組上的 ADC 晶片是由德州儀器 TI ADS1256 所構成的核心。另外,我發現這塊模組被用於 Arduino 平台上,官網有提供其 library。 圖一:德州儀器 TI ADS1256 類比訊號模組         之前,曾設計開發過一個控制器 (Windshear),系統底 板的插槽可以提供 5V 電源和 SPI 通訊介面。於是, 我將這塊類比訊號模組加工改造後,接到控制器的底板上,如圖二所示。大功告成後,修修改改一下控制器的 STM32F207 韌體程式,啟用 SPI 介面和 GPIO 中斷,便能開始測試模組了。 圖二:Windshear 控制器加上 ADS1256 模組 元件規格         ADS1256 晶片是一顆具有 24-bit 解析度和八個通道的類比數位轉換器 ADC,根據 datasheet 來看,其內容提到取樣頻率可達 30k SPS (每秒 30k 個取樣點),每個取樣點具有 24-bit 解析度。解析度影響資料的精準度,解析度的位元越高,資料則可以精準到小數點以下更多位。除了要留意解析度之外,取樣頻率則影響資料的頻寬,如果擷取的資料屬於