總網頁瀏覽量

2019年1月21日 星期一

【你所不知道的Arduino】Arduino到底是什麼? MCU又是什麼?

【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

歡迎透過合法的方式分享此文內容,若要轉載/轉貼,請明確貼出此原始連結並標示作者基本資訊請勿抄襲及非法轉貼(例如擷取內文但並未註明出處)


基於看過很多學校同學、老師甚至是從業工程師對於Arduino及MCU都有著不少誤解,所以分享此篇文章

Q:  Arduino到底是什麼?

  •  Arduino是現今在學生或maker界之間很流行的一種搭載微控制器(單晶片微電腦)的電路板(專業一點來說其實是一種開發板,也就是開發階段所用的平台,所以許多腳位都拉出來,也因為這樣就有相對應的PCB面積)的系列的名稱(包含其軟體,函數庫與工具),因其應用軟體介面之完整度與其搭配的硬體之整合度極高,可讓開發者在不必深入了解底層硬體驅動步驟原理的情況下,而直接透過比較直觀的方式操控微電腦,所以相當盛行。即便是非電機電子資工背景的人,在大多數的狀況下,只要受過基礎教學訓練,亦可利用Arduino做出一些簡單的微電腦應用
  • Arduino是很方便的工具,但背後的原理仍然很重要,需要注意,很多人會忽略這點,以為東西會動就代表自己會MCU韌體開發了,但其實可能完全不瞭解較深入的背後原理,其實若多理解背後原理,再來使用Arduino,那麼在使用上將會如虎添翼
  • 此外,Arduino的軟硬體都是開源(Open Source),其實很值得鑽研應用層底下的這些library和硬體電路設計,可以學到很多東西,只可惜很多人都只拿它來做簡單的應用,沒有看到更深入、更有價值的學習及探討層面,也因為Arduino有著簡單易用的外表,所以很多學校老師都誤以為Arduino只能讓學生做雛形,其實不然,事實上Arduino上面的ATMEGA328 MCU從很早期(至少十幾年前)就已經被使用在許多產品的開發上,只是當時這款MCU還沒有Arduino這層外衣
  • 板子上面是以 MCU(微控制器)為主要核心元件,下面會針對MCU做說明
  • 承上,因為微控制器(MCU)本來主要就是要被用在硬體控制領域(例如控步進馬達、驅動電路等等),所以它的規格(位元數、時脈等)本來就不用太強,但也常因此而被許多不了解的人所誤會(以為MCU很慢所以就很LOW很簡單,其實這完全是錯誤的認知)


Q:  MCU到底是什麼?
  • 微控制器(Microcontroller Unit, MCU),等同一顆小電腦(麻雀雖小五臟俱全),內含CPU、記憶體以及基本周邊單元(當然也有很多不僅有基本周邊的較高級MCU)
  • 早期大多負責做少量資料運算處理的應用(如對外部硬體電路驅動)。但近十幾年來也有可用在網路/多媒體應用、相對較接近大型SoC規模的微控制器出現(這類MCU的CPU大多有MMU,可跑Linux之類的較大型OS)。
  • MCU在早期又常被稱為 單晶片微電腦 (Single-Chip Microcomputer),因為已經具備被稱為電腦的條件。
  • 許多人會將微控制器混淆微處理機/微處理器嚴格來說,這說法是的,為什麼呢? 因為傳統的general微處理機(或微處理器)主要指的其實是針對CPU單元封裝而成的chip(如8086或Z80),並沒有包含各式週邊單元與記憶體單元,可以參考Wikipedia的內容microprocessor is a computer processor that incorporates the functions of a central processing unit on a single integrated circuit (IC)

    微控制器(Microcontroller)則是除了CPU (Central Processing Unit)之外,還有包含周邊、記憶體單元等,都整合在一顆chip上,所以才叫做單晶片微電腦,早期因為大多被用在硬體控制領域 (而不是處理例如網路多媒體這種進行大量資料運算處理的領域。讀者可自行對照樹莓派那類的硬體狀況去思考一下),所以也稱為微控制器

    此外也要注意一下: MCU與SoC這類的平台有時也被稱之為「嵌入式微處理器」,英文是Embedded Microprocessor,例如Atmel/Microchip公司的SAM9G20或者ST公司的STM32MP1(ST的MPU系列是屬於這裡所說的Embedded Microprocessor),但這些並不是傳統的「微處理器」或「微處理機」。因為時代的演進促進平台的多元化,容易使人混淆,導致這些名詞之間不論是在許多書籍或網路資料中都常被混淆解釋,當然這些名詞的定義也有過少數爭議)。
  • 很多款Arduino板子上面的MCU款式名稱為ATMEGA328(如Uno、Fio、Nano、Mini...等等),當然後來Arduino系列也有出上面搭載別款MCU的板子(如Arduino DUE是搭載Atmel SAM3X8E的MCU)

我們以ATMEGA328 MCU內部架構圖為例(如下圖),我們可以看到這顆MCU內部有CPU記憶體單元周邊單元,而連接這之間的排線即為匯流排單元(灰色粗箭頭的部分)





延伸文章: MPU/MCU/Embedded Microprocessor/Embedded Processor名詞定義探討與整理


【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章


2019年1月20日 星期日

應用慣性感測之電子筆記系統



分享一個一年多前帶朋友們參加比賽的作品(本身也有參與一些開發)

功能上來說就是一枝筆,在平板上的APP可顯示使用者握住筆在的揮動軌跡

透過慣性來達成類似電子白板功能(過去在網路上看過紅外線方式的)





Demo影片:



架構簡單來說就是LinkIt7697板子 + 藍牙2.0模組 + 慣性感測器 + Android App

方法主要是Software RC filter做簡易的雜訊濾除 + Android App Inventor 球形精靈

此作品中的LinkIt7697上面的軟韌體的開發是採用Arduino IDE加上LinkIt 7697 的 board support package(BSP)進行(步驟可參考: Mediatek Labs說明網站),透過此方式即可使用Arduino 基礎API來進行LinkIt7697的應用軟體開發。




可能會有朋友感到好奇,LinkIt7697自己本身有內建BLE,為何還要外加藍牙2.0模組呢

原因是當時我們的Android App是使用App Inventor來撰寫,而當時(2017年)App Inventor在BLE 支援的部分似乎有點問題,所以才會自行外加藍芽模組。




【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

2019年1月14日 星期一

用於頸部姿態辨識的慣性感測訊號處理方法


這次要來分享自己於三年多前的碩士論文研究內容了

會想要分享出來主要是因為覺得其內容好像也是和maker們蠻有關的東西(其實當初寫的比較像技術報告, 想要把技術細節盡量完整交代)


因為當時實驗室的一些特殊狀況,所以當時從規劃題目、相關文獻及前人研究成果survey、設計及開發實作、找一堆人來實際測試實驗以及論文撰寫,全部共只花了2個月左右...雖不是什麼很厲害的東西, 但也是心血之作(在做碩論之前並沒有玩過慣性感測), 每字每句完全誠實寫出所有研究過程和細節

而這個東西是做什麼呢? 當初的主要研究動機又為何呢?

簡單來說, 當時有一個在網路上募資的新創公司提出了一個將慣性感測裝置放在後頸部的項鍊式穿戴裝置產品(Fineck). 當然了, 如何處理這慣性感測訊號的方法是他們家的Knowhow, 是不會公開的.

而我的論文就是基於將慣性裝置放在相同身體部位,  去研究並提出一個自己整合設計的用於頸部姿態辨識慣性感測方法,  並將其實作驗證,  看看自己提出(當然也是站在巨人肩膀上, 整合偉大先進的方法後加以延伸組合應用)並實作的方法是否也可以像他們新創公司產品影片呈現的那樣準確.

下方列出有Demo影片和口試的投影片

細節部分請大家可直接參考我的論文全文內容: 全文下載網址連結(NCKU)


方法部分, 簡單來說就是應用了: 位準和振幅的調整 + Software RC filter(也稱是指數平滑法) + 透過經驗法則訂出的姿態訊號擷取門檻機制 + Dynamic Time Warping(動態時間校正) + 簡單的1-NN分類

實作平台的部分就是Arduino Fio + 六軸慣性感測器 + 藍牙模組 + Android APP

相信這方法應也可用於其他類似情境下的訊號辨識分類

請大家盡量參考, 但若是想做成論文或文章也請勿抄襲, 並請注意合法引用  ^.<   (之前真的看過很誇張的案例...身為原作者真的會不太開心), 感謝大家了!


Demo影片(這影片是畢業之後把東西又架起來拍的,  影片有點長...):





口試投影片 (若因上傳導致部分格式稍微跑掉請見諒):

 

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

2021/05/10更新:

很多人看我常講台灣學術界的問題,可能會以為我這個人只會一昧覺得產業相關的實作技術才有價值,而以為忽略學術研究,其實我認為什麼學術研究(或理論)和實作是兩回事的這種觀念其實是假議題(專業就是專業、學問就是學問、工程就是工程,特別是在應用科學領域,哪裡有什麼理論實作之分,也沒有什麼學術研究和產業技術之分,只有嚴謹和不嚴謹、熱愛不熱愛、掌握程度深淺、是否具備遠見之分,很多人總是很喜歡拿 理論和實作是兩回事 或者說 學術和產業是兩回事 來當作不用重視實作/懶得去碰實作的藉口),

而且我個人相當熱愛真正紮實的工程領域學術研究,正因為如此所以我個人認為台灣學術界整體風氣實在沒有很踏實(國外聽說也開始有這些現象,我不清楚),因為真正熱愛專業領域和研究的人相對實在比較少,多數人在意的是現實面而不是熱愛研究。

以前曾經分享過,自己的碩士論文當年從頭到尾共做了不到2個月(因為在這之前在忙著舉辦教育部競賽的計劃,在此之前幾乎沒時間想碩士論文的事,所以短時間內將碩士論文完成其實是真的非常累,在拚碩士論文內容的期間幾乎每天只睡三到四小時,而且還好在之前就已經有許多嵌入式系統應用設計的基礎和經驗,以及在大學時期已有累積不少與訊號處理演算相關的數學觀念),內容絕對紮實嚴謹,而在碩士班畢業離校當天(2015/8/26)就完全公開。而其中的程式原始碼和頸部姿態穿戴偵測裝置還保留至今,去年指導成大碩士生學弟們將此程式碼拿出來提供給學弟們整合後續應用程式之後去參加競賽得獎(經濟部與教育部合辦的2021第26屆大專校院資訊應用服務創新競賽[4],請看該網頁第2頁的資訊應用組九的第二名)。

台灣人很愛拿學術這兩字出來講,所以今天提一下我的碩士論文[5][6][7]當時在學術的方面的狀況(絕對不是什麼偉大成果,畢竟只是我自己1人做了共2個月不到,但當時也是做得相當用心而且絕對有考慮學術貢獻的方面),當時比較了一些論文文獻,最相關相似的文獻是和美國名校大學University of Washington(華盛頓大學)當時的Ke-yu Chen博士研究生 等人的研究團隊(共五人)在2014年的一項class project專案成果NecX [1][2]進行比較。我覺得NecX是一項很棒的專案(雖是class project,但是內行人都知道,許多歐美名校頂尖大學的class project就已經很有程度,且這是五人的共同研究成果),也很感謝他們願意公開這些研究成果資訊。

University of Washington(華盛頓大學)這間學校出過15位諾貝爾獎得主,在電腦科學和醫學領域的學術名望是世界頂尖。

NecX論文的第一作者Ke-yu Chen博士[3]畢業於東吳大學、台灣大學資訊工程碩士班 與 美國University of Florida(佛羅里達大學)電機與電腦碩士班,並且在2016年獲得美國University of Washington(華盛頓大學)的電機工程博士學位,他後來在Intel擔任過研究員和Google當過研究工程師,目前任職於Apple公司擔任研究員[3]。

他們當時就讀於University of Washington的這項NecX專案,有寫成一篇論文[1][2](這篇paper[1]有五位作者: Ke-Yu Chen, Aniket Handa, Chaoyu Yang, Shuowei Li, Shwetak Patel),也有專案網站,主要是透過EMG sensors貼在人體頸部的兩側,並進行後續的演算處理辨識,主要辨識2位受測者的5種頸部動作,並且他們的實驗數據主要是離線運算分析(offline analysis)的方式輸入WEKA資料探勘軟體以訓練出model並對其動作進行分類(所以應該是在電腦上分析),準確度是94.1%(但是是離線運算分析,他們的論文中有提到他們在做即時辨識時有遭遇到一些困難,後來他們也有做即時辨識但似乎沒有提出實驗數據,只有提到如Demo影片的效果)。

而我的碩士論文研究內容[5][6][7]是我一人自行完成,沒有共同作者,在sensor種類(選擇IMU感測器)和穿戴/放置部位是參考一項當時在網路上募資專案Fineck,而這碩士論文的核心在於自行整合應用設計一套演算法機制來做訊號處理辨識以辨識頸部動作,最後成果是做到online即時(Real time)分析演算辨識(辨識演算法的主要部分實作自行整合撰寫的手機APP應用程式達進行即時辨識運算)辨識18種頸部姿態動作(整合應用了一些open source 專案的source code加以修改整合設計),實驗的受測者人數為10位,實驗辨識率每次都在九成多以上(大約都在92%~96%),後來覺得我這樣一人獨力在2個月內所完成的成果應該明顯不輸給University of Washington的NecX專案成果,和其他文獻相比也有獨特性,所以認為這應該可算是令自己滿意的成果。當時因為已在前一年和產業公司簽約媒合(同時服研發替代役的工程師職務合約),一心想在碩士畢業後趕快去聯發科集團(晨星)上班(而工作內容性質其實和我碩士論文方向性質差異很大),而且也認為有用的研究成果最主要就是要能貢獻台灣社會(所以論文完全公開且寫出很多實作和實驗方面的細節以及演算法選擇/應用/搭配/整合的原則及整合方面的細節),所以從來就沒有想將此成果發表去什麼學術期刊(個人當時也已開始不太認同台灣學術界的某些文化),但畢業後一直覺得這東西沒用到很可惜,所以就把東西拿出來再次實驗並且拍攝Demo影片放在Youtube上面並且寫成blog文章分享,並且在離開產業界回成大協助指導碩士生時又將成果拿出來讓學弟們延伸應用參加競賽。

  
感謝我碩士班的指導教授讓我在挑選題目和研究方面有極大的自由和發揮空間,指導教授對於許多事情的務實看法,我至今仍非常認同和敬佩,也給了我不少認知和啟發,也很高興畢業後都有在和黃教授維持聯繫交流。

現在回頭想想,碩士論文口試也已經是好幾年前的事了,時間過得真快。



當年口試(學位考試)成績: 94.25 (共四位口試委員,其中一位委員打95分 而另外三位委員打94分)


【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章


適合學習Embedded Linux及RTOS的開發板


【目前正尋求技術輔導教學工作, 若有需嵌入式或物聯網相關專業技術輔導者可洽談】


有朋友來詢問學習Embedded Linux及RTOS應該要從哪個開發板開始學習會比較好

我認為這是蠻多初學者可能會有的疑惑

下面列出一些小弟我的個人經驗及看法 


未必敢說是最正確, 或適合任何人

關於Embedded Linux的學習部分, 我想可以分為兩個層面

一是環境建置的學習, 就是例如了解什麼是bootloader、filesystem、kernel、device driver、applications 並有能力去建置這些東西

讓這些部分能被執行於板子上, 除了熟悉這些部分單元, 也熟悉Linux開發環境的使用

我認為這些的重點不在於哪款板子, 只要能提供這些單元可學習空間的板子都可以(因為這邊是討論板子, 所以用qemu進行模擬的狀況就暫時先不提)

例如早期的PXA270(現在已經買不太到, 而且價格較高)、devkit8000、Pandaboard、Beaglebone Black等等(可能有些是我不知道的)

我個人較推薦的是Beaglebone Black板子, 因為它的價格相較於上述其他板子來說不算太高(大約兩千元左右)

而且上面是搭載TI的SoC chip, 而TI這類chip有一個特性是, 它的硬體規格資料公開的很詳盡(可參考他們官網: http://www.ti.com/product/AM3358/technicaldocuments), 所以很適合做為嵌入式系統軟體研究上所使用的硬體平台

也因為如此, 所以很多國外的Embedded linux書籍很愛將 Beaglebone Black做為實驗目標的板子

例如下面這兩本(剛好是近年來看到):

(1) 精通嵌入式Linux程式設計 Mastering Embedded Linux Programming(作者: Chris Simmonds, 譯者: 錢亞宏, 出版社:博碩)

(2) Embedded Linux 嵌入式系統開發實務 第二版(作者:Christopher Hallinan, 譯者: 江良志, 出版社:旗標)


而我沒有推薦樹莓派的原因是我認為樹莓派相對較適合做應用.

舉例來說, 用樹莓派可能比較沒辦法自己編譯或trace bootloader , 也似乎比較沒辦法看到上面bcm283x Soc的詳細資料 (如果我認知沒錯的話, 因為我自己也在SoC產業待過, 大概可以想像到是什麼狀況)

從他們給出的資料可以看出: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf  其內容大多是一些較通用的周邊操作資料

如果是做應用專案為主要目的, 我會直接推薦樹莓派(很方便又快速, 應用案例又多)

但如果是從頭到尾的Embedded Linux的學習, 我比較建議能從bootloader就開始建置的板子,
可以搭配網路上各路高手網友的資料學習

第二個層面就是關於較深入的各單元內容的學習, 例如trace各單元原始碼(bootloader、device driver等單元的設計開發學習), 這部分就比較屬於需要較長期學習累積經驗的方向了


而RTOS的部分, 其實RTOS的種類繁多, 我覺得對初學來說可以先選用直接有支援open source RTOS專案的MCU開發板, 例如STM32系列相關的開發板(有支援FreeRTOS)

或者其他符合這些條件的MCU開發板也都OK 


我認為學習這些的重點其實不在於哪一款板子, 只要是符合條件的就可以了

希望我的見解能幫助到大家


【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

2019年1月13日 星期日

簡易無線藍牙遙控插座實作教學(2020/09/11更新)


Hi 大家好


這是一個簡易無線藍牙遙控插座實作的製作教學文件


如下方投影片(Demo影片的下方)


請讀者注意所有用電安全事項後再行實驗

功能Demo影片如下:



 


 

【若需要基礎C語言 與 嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

2019年1月11日 星期五

【C語言觀念複習筆記】指標陣列(Array of pointer) 相關觀念之範例解析說明


此篇文章將記錄一下關於C語言中的指標陣列的相關簡單觀念

因為是針對初學者或已將相關觀念淡忘的人作為複習參考, 可能有些地方的用詞不會太過於精確,  因此盡量以觀念上的理解為主要目標

範例程式如下:

#include "stdio.h"

int main()
{
 /*--- part 1 ---*/
 char *name[]={"jim", "harry", "ken"};


 /*--- part 2 ---*/
 printf("%s \n", *(name)); // result: jim


 /*--- part 3 ---*/
 printf("%c \n", **(name)); // result: j


 /*--- part 4 ---*/
 printf("%s \n", *(name)+1); // result: im


 /*--- part 5 ---*/
 printf("%s \n", *(name+1)); // result: harry


 /*--- part 6 ---*/
 printf("%s \n", *(name+1)+2); // result: rry
 printf("%c \n", *(*(name+1)+2)); // result: r

  return 0;

}


執行結果如下圖:




以下將按照code裡面各個部分進行講解(若有筆誤請告知)

---

part 1:
char *name[]={"jim", "harry", "ken"};
上面這段C code的char *name[]={"jim", "harry", "ken"}

即宣告了三個位於連續位址的字串指標陣列元素(name[0], name[1], name[2]),

並分別令其指向三筆字串資料:"jim", "harry", "ken" (也就是將這些字串資料的address放到陣列元素內)


---

part 2:
printf("%s \n", *(name)); // result: jim
在C語言中, 陣列名稱代表該陣列的第一個陣列元素的address (也就是該串陣列的起始位址)

所以name就是name[0]的address

所以*(name)就是name[0]元素的內容資料, 這個內容資料就是"jim"字串的第一個字元資料的address

而由於printf function裡面的%s吃的是字串資料的address, 並且會印出包含該address開始直到遇到字串結束字元(\0)為止的所有字元

所以printf("%s \n", *(name))會直接印出jim

---

part 3:
printf("%c \n", **(name)); // result: j
承接part 2舉一反三可得知

**(name)就是"jim"字串資料中起始的字元資料('j')的address上面的資料(好像在繞口令...其實就是'j'啦)
而由於printf function裡面的%c是直接吃該address上面那個byte的資料(而非像%s那樣是吃字串資料的address並印出結束字元前的所有字元)

所以printf("%c \n", **(name)) 會印出j

---

part 4:
printf("%s \n", *(name)+1); // result: im
已經由part 2知道*(name)就是"jim"字串資料的起始address (也就是j這個字元資料的address)

而因為name[0]裡面的這個內容是char資料型態的address, 所以當對這address做加法時, 該address的值會以字元資料長度(byte)為單位增加

(稍微題外話, 粗略來說, 電腦系統是一個byte對應一個address(此方式稱為byte addressing), 所以在對指向字元資料型態的位址值+1時, 實際位址值也是增加1。如果是32位元的整數型態資料位址, 其位址值加1時, 就會增加4, 因為32除以8等於4)

所以當我們把*(name)+1,就等同指向了j之後的下一個字元, 也就是i  (註:運算子優先權順序是先*(name)然後才是+1)

printf function裡面的%s如同前面的解釋

所以printf("%s \n", *(name)+1); 會印出im

---

part 5:
printf("%s \n", *(name+1)); // result: harry
name是name[0]的address

name+1相當於name[1]的address (對字串陣列元素address加1, 就變成下一個字串陣列元素的address)

所以*(name+1)即是name[1]的內容資料,也就是harry字串資料的起始字元資料(h)的address

故printf("%s \n", *(name+1)) 會印出harry

---

part 6:
printf("%s \n", *(name+1)+2); // result: rry
printf("%c \n", *(*(name+1)+2)); // result: r
由part 5可知*(name+1)就是第二陣列元素(name[1])中的字串資料harry的起始字元資料(h)的address (有點繞口令...)

而對這個address進行加法,就會讓這個address變成是後面的字元資料的address

所以*(name+1)+2就代表著harry字串資料的第三個字元資料(r)的address,也就是h之後的第2個byte資料的address

所以printf("%s \n", *(name+1)+2)會印出rry


再舉一反三思考後可得知  *(*(name+1)+2)就是harry字串資料的第三個字元資料(r)的address的資料內容, 也就是r啦

所以printf("%c \n", *(*(name+1)+2))會印出r (如前面解釋過的, %c是直接吃資料本身, 而不是資料的address)

---

再來探討用指標陣列來儲存字串的一個好處

由範例程式可看出

我們是用 char *name[] = {"jim", "harry", "ken"}; 的方式來配置儲存這些字串的空間

這種作法,compiler會針對我們宣告的字串的字元數,自動配置出足夠容納這些字元的記憶體空間


但如果是純粹使用陣列來放置這些資料

必須用最大的字串數作為統一標準來配置出給每個字串的空間,但並非每個字串都像最大字串有這樣多的資料 (除非現在的compiler是否已聰明到可以自己優化這部分...)

char name[3][6] = {"jim", "harry", "ken"};

其中[6]是因為harry加上結數字元\0共須要有6個byte,但是jim和ken則只須要4個byte就可完整儲存,但是固定宣告了[6]給這兩個字串資料,有可能總共就多浪費了4個byte(各浪費2個)
除非現在的compiler已聰明到可以自己優化這部分

終於打完這篇啦!

【若需要基礎C語言 與 嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章