2013/01/27

Arduino練習:RTC即時時鐘DS1307

Arduino的millis(),每次重開機就會從0開始計數,單位是千分之一秒,型別為unsigned long,大概50天便會溢位(2^32-1 / 1000 / 60 / 60 / 24 = 49.71),對某些情況而言已足夠,但若我們想要在Arduino沒電不運作時、仍然繼續計數,那麼就需要另一個晶片與額外的電池了。

所謂RTC(Real-Time Clock、即時時鐘),其功能就好像手錶一樣,由電池供應電力,持續地跳動計數,當電子電路其他部分斷電不運作時,RTC還是能繼續跑,記錄著正確的時間日期。個人電腦主機板也會有個RTC,當電腦關機時,還是會由一顆獨立的電池供應RTC電力,維持時間日期。

本篇以RTC晶片型號DS1307為範例,便宜不貴,精確度算普通。(若想要更好更精準的,可改用DS3231。)

我的板子是Arduino Uno R3,軟體開發環境為1.0.5 Windows版,電路圖(Fritzing格式)與原始碼可到這裡下載

關於RTC,有很多已經組合好的「模組」 產品,譬如底下這三個:

Adafruit Industries的DS1307 Real Time Clock breakout board kit。此產品必須自己焊接組裝,底下是完成後的樣子,看起來很迷你精緻。


藝科資訊 Aroboto Studio的RTC時間模組


在某拍賣網站找到的【秋葉原電腦周邊-旗艦店】㊣ mini_RTC DS1307時鐘模組 24C32記憶體 arduino 帶電池


不過我是一個一個零件單獨購買,如下(依序是下圖中的從左到右,從上到下):

  • RTC晶片,型號DS1307
  • 鋰電池CR1220,3V
  • 鋰電池座
  • 電阻2.2K ohm(色環:紅紅紅金),1/4W,2個
  • 陶瓷電容0.1uF(104)
  • 石英晶體32.768 KHz,12.5 pF


首先是硬體線路,翻閱DS1307的規格資料表,有8支腳。



線路如下:
首先將Arduino的5V與GND接到麵包板。

DS1307的Vcc接5V。
DS1307的Vcc另接陶瓷電容0.1uF再接地。

DS1307的SQW/OUT,可輸出四種頻率的方波,此篇不用,不接任何東西。

DS1307的SCL,接到Arduino的SCL(Uno的類比腳位5)。
DS1307的SCL另接上拉電阻2.2K ohm接5V。

DS1307的SDA,接到Arduino的SDA(Uno的類比腳位4)。
DS1307的SDA另接上拉電阻2.2K ohm接5V。

DS1307的X1與X2,接石英晶體32.768 KHz的兩支腳,不分極性。

DS1307的GND,接地。

DS1307的Vbat與GND,接到鋰電池CR1220的正極與負極。

注意,在下圖中,因為我在Fritzing裡找不到鋰電池的元件與圖案,所以用2xAA電池代替。


實際情況如下:


特寫DS1307的部份。


DS1307以I2C作資料傳輸的介面,而我已經將SDA、SCL分別接上Arduino的類比腳位4、5了。

以上是硬體線路的部份,接下來軟體程式的部份。

我使用Arduino的Time程式庫,可到這裡下載。下載解壓縮後,裡頭有Time目錄與DS1307RTC目錄,搬移到sketchbook/libraries底下。還有個TimeAlarms目錄,不使用。

程式碼如下,程式碼能經由序列埠設定時間日期(年、月、日、時、分、秒),每隔一秒就輸出時間日期到序列埠。

// 匯入需要的程式庫標頭檔
// Wire是I2C傳輸,最低階
// DS1307RTC,讀取即時時鐘DS1307
// Time,較高階的程式庫,可令它從DS1307取得時間
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>

// 簡便的工具函式,格式化輸出字串
void pf(const char *fmt, ... ){
    char tmp[128]; // resulting string limited to 128 chars
    va_list args;
    va_start (args, fmt );
    vsnprintf(tmp, 128, fmt, args);
    va_end (args);
    Serial.print(tmp);
}

void setup()  {
  Serial.begin(115200);
 
  // 設定從哪裡取得時間,由DS1307RTC程式庫的RTC.get負責
  // 這也是此程式碼裡唯一使用DS1307RTC程式庫的地方
  // 其餘皆使用較高階的Time程式庫的介面
  setSyncProvider(RTC.get);

  // 判斷能否從DS1307取得時間
  if(timeStatus() != timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");     
}

void loop()
{
  // 每隔一秒就輸出時間日期
   pf("%d/%d/%d %02d:%02d:%02d\n", year(), month(), day(), hour(), minute(), second());
   delay(1000);
}

// 聆聽序列埠,從這裡設定時間日期,格式如下:
// 「y2013」設定為2013年
// 「M1」設定為1月,注意是大寫的「M」
// 「d27」設定為26日
// 「h2」設定為2時
// 「m34」設定為34分
// 「s56」設定為56秒
void serialEvent()
{
  int t = Serial.read();
  int v = 0;
  int temp;
  while((temp = Serial.read()) != -1){
    v = v * 10 + (temp - '0');
  }
 
  int y = year();
  int M = month();
  int d = day();
  int h = hour();
  int m = minute();
  int s = second();
 
  switch(t){
    case 'y':
      y = v;
      break;
    case 'M':
      M = v;
      break;
    case 'd':
      d = v;
      break;
    case 'h':
      h = v;
      break;
    case 'm':
      m = v;
      break;
    case 's':
      s = v;
      break;
    default:
      pf("Wrong\n");
      break;
  }

  tmElements_t tm;
  tm.Year = y - 1970; // 從1970年開始算
  tm.Month = M;
  tm.Day = d;
  tm.Hour = h;
  tm.Minute = m;
  tm.Second = s;

  // Time程式庫會有一段延遲時間,過後才會與RTC晶片同步
  // 所以在此強制把日期時間寫入RTC晶片
  setTime(makeTime(tm));
  RTC.set(makeTime(tm));

}

開啟序列埠監控視窗後,可看到如下訊息。請記得把右下角的換行設定成「沒有行結尾(no line ending)」。


輸入y2014,便可更改年份,依此類推。


因為有鋰電池供應DS1307,即使拔掉USB線(板子的電源),DS1307仍會繼續運作,下次再讀取時間日期,仍會是正確的。

另外,若無外接鋰電池,DS1307也可運作,將Vbat接地即可,其餘不變,如下圖。只不過這麼一來,拔掉板子的電力來源後,時間就會錯掉了。



參考資料:

2013/01/21

Arduino與AVR微控制器相關詞彙

簡單介紹解釋一些名詞,這篇只是把找到的資料整理之後扼要記錄,主要是寫給我自己看的。若有錯誤,尚請不吝指教。

microcontroller(微控制器)
微控制器、MCU(MicroController Unit)、μC,似乎有些人暱稱為「micro」。將CPU、RAM、ROM、Flash、I/O、A/D等功能通通整合在一塊晶片上,形成一個微型的電腦,所以也稱為單晶片(single-chip)、單晶片微電腦、單晶片控制器,大陸稱為单片机、单片微型计算机。最廣為人知的是8051。

單板電腦(Single Board Computer)、單板機
沒有絕對的定義,只要將整部電腦放進一塊板子裡應該都算,譬如使用TI OMAP系統單晶片的Beagleboard、BeagleBone、Pandaboard,譬如Raspberry Pi。一般來說可運行作業系統,例如Linux。

8051
Intel於1980年代推出的MCS-51微控制器,通常稱呼為8051,型號很多,但基本核心與指令皆相同,差別在於記憶體容量、型式、其他擴充功能,Intel於2007年3月終止此產品線,但仍有其他廠商的相容產品。8051發展的早,幾乎可說是單晶片的代名詞,學校課程大都以8051為教材,中英文參考書籍非常多,網路資源豐富,在台灣尤為流行,單晶片幾乎都是8051的天下,也因為如此,其開發環境與周邊非常豐富,諸如整合編輯器、編譯器、模擬器、等等。

此系列廣受歡迎,相容產品非常多,如Atmel的AT89C51/AT89S51,其他廠商還有Winbond、Philips、NXP、STC、Infineon、等等,相繼改進推出相容產品,譬如提高時脈、減少接腳數與晶片體積、PWM、計時器、等等。

在台灣,其他比較常見、資料比較多的單晶片,應該是Microchip的PIC系列與Atmel的AVR系列,機器人領域則有Parallax的BASIC Stamp,當然啦,除此之外還有很多其他廠商的產品。

各種廠牌的8051相容單晶片。


Keil C
Keil公司為8051實做的C語言編譯器,以ANSI C語言標準為基礎,因應8051微控制器而增減一些功能特色。Keil公司在2005年被ARM公司收購。

Processing
2001年由Ben Fry和Casey Reas在MIT媒體實驗室所發展,提供簡單易用的程式語言與開發環境,著重於繪圖、動畫、互動設計,以視覺化的方式,供視覺設計藝術家進行創作。寫出來的程式碼稱為sketch(素描、草稿)。

Wiring
繼承Processing的概念,但是將對象改為電子創作者,起初由Hernando Barragán在2003年於義大利Ivrea互動設計學院開始發展,提供一套程式語言、軟體開發環境(Java跨平台IDE)、硬體電路板、等等。可視為Arduino的前輩、姊妹平台。

Arduino
Arduino計畫於2005年正式啟動,在那個年代,發起人Massimo Banzi與David Cuartielles覺得市面上可用的電子素材與零件太過昂貴,學生負擔不起,於是動念打造更便宜好用的電子創作原型平台。

Arduino的起源地是義大利西北方的一個小鎮Ivrea,這個小鎮有個知名歷史人物Arduin of Ivrea(955~1015),於是便以他取名為Arduino。Arduino也是個義大利男性名,其意為「strong friend」。

Arduino繼承Wiring並使用Processing的IDE,簡化後的C/C++程式語言,便利且豐富的程式庫,以及Atmel 8-bit AVR微控制器為核心的硬體電路板,提供一套開放原始碼電子創作原型平台。

Arduino官方推出的開發板,諸如Diecimila、Duemilanove、Uno、Leonardo、Esplora,Mega 2560、LilyPad、Micro、等等。主要使用megaAVR(ATmega)系列的晶片,但也有人移植了tinyAVR(ATtiny)系列。

Arduino Uno板,2010年9月推出,uno在義大利文裡是「1」的意思,代表進入1.0里程碑。後來在2011年11月,Arduino軟體部分的編號也從00xx改成1.0。


2015年Arduino推出新板子Zero,晶片為Atmel ATSAMD21,採用32位元ARM處理器核心(ARM Cortex-M0)。

Arduino相容板
譬如Seeeduino、Japanino、Roboduino、Raspduino,非常多。

Arduino Software
Arduino官方的軟體開發環境,有Windows、Mac OS X、Linux版,內含整合式編輯器、Arduino核心、內建程式庫、範例sketch、編譯器、燒錄程式、等等。

Arduino軟體開發環境。


sketch
素描、草稿、草稿碼、程式碼,在Arduino世界裡,就是「程式」的意思啦。而sketchbook指的是存放sketch的地方(目錄)。

Verify
在Arduino軟體開發環境裡,其真正的意義是「編譯、建置程式碼,產生二進位執行檔」。

Upload
Arduino軟體開發環境裡,其真正的意義是「燒錄,將二進位執行檔傳進微控制器晶片裡」,當然啦,若尚未編譯建置或原始碼檔案更新了,便會先執行Verify。

shield
擴充板、周邊擴充板、daughterboard、add-on module、擴展板、轉接板、子板。Arduino擁有非常多的shield,一插上便可使用,非常方便。

breakout、breakout board
分線板。通常是一塊小小的印刷電路板,作用是將某晶片的腳位接出來,因為現在很多元件都是SMD,平常開發時用起來不太方便,以分線板接出接腳、排針、端子,便可輕易地插上麵包板、或接到其他電路;有些晶片使用時可能還需要一些其他元件(譬如電容、石英晶體、電池、電阻),也可整合在板子上變成模組,用起來更方便;板子上可能印有文字說明,用起來較清楚。

Atmel ATmega32U4晶片的分線板。


即時時鐘DS1307晶片的分線板,也是易於使用的模組,該有的電子元件都在上面了。


Harvard architecture、von Newmann architecture
簡單地說,Harvard架構把指令與資料分開,von Newmann架構則放在一起。一般CPU大都是von Newmann架構,但也加入了Harvard的特色,譬如將cache分成指令快取與資料快取。Harvard也隨著時間演進有所修改。

RISC、CISC
CISC的代表有x86、68000,RISC的代表有ARM、MIPS、Power,因為處理器架構逐漸複雜,但其實常用的指令只佔一小部分,便提出RISC型的架構,精簡指令。但經過多年發展後,RISC處理器的指令集也越來越大。

Atmel
半導體公司,產品包括微控制器、快閃記憶體、觸控技術、車用電子、等等。台灣地區分公司為台灣愛特梅爾股份有限公司。其AVR產品為Arduino的核心。於2016年被Microchip公司收購。

AVR
Alf (Egil Bogen) and Vegard (Wollan)'s RISC processor的縮寫,也有人說是Advanced Virtual RISC的縮寫,不過官方說法為「AVR就是AVR,不是縮寫」。修改過的Harvard架構、8-bit、RISC、單晶片微控制器。最先以Flash memory作為程式儲存區,而不是以PROM、EPROM、EEPROM。將Flash、EEPROM、SRAM通通整合在一塊晶片裡,還包含了其他功能,諸如輸出入腳位、計時器、序列傳輸埠、數位類比轉換。

大致上可分為6個群組,tinyAVR(ATtiny)、megaAVR(ATmega)、XMEGA(ATxmega)、特製AVR、FPSLIC(含有FPGA的AVR)、32-bit AVR。Arduino官方主要用的是ATmega系列,也有人移植了ATtiny。

ATmega328
Arduino Uno採用的微控制器晶片,後來有ATmega328P,P代表Picopower,意思是製程更好更省電,但功能是一樣的。ATmega168除了有ATmega168P還有ATmega168A與ATmega168PA,多了個A,差異處必須查datasheet才知道,但功能應該是一樣的。若晶片編號後面有-PN或-PU,其中P代表封裝技術PDIP(Plastic Dual Inline Package),而N與U代表溫度容忍範圍,N比U好,另有-AN或-AU,其中A代表封裝技術TQFP(Thin Profile Plastic Quad Flat Pack),另有-MN或-MU,其中M代表封裝技術MLF(Micro Lead Frame Package)。

ATmega328P-PU。


ATtiny45、ATtiny85、ATtiny44、ATtiny84
有人修改Arduino軟體開發環境的程式,使其可運作在這些微控制器上,比起ATmega系列晶片,體積較小、腳位較少、價格較低,若你的作品不需要那麼多腳位,可改用ATtiny系列,降低成本,縮小體積。ATtiny45與ATtiny85有8支腳,功能幾乎一樣,主要差別在於ATtiny85的記憶體(Flash、EEPROM、SRAM)是ATtiny45的兩倍。ATtiny44與ATtiny84有14支腳,輸出入腳位較多。

ATtiny85-20PU。


chip  signature、signature bytes
Atmel的微控制器晶片都有個識別碼,譬如ATmega328是0x1E 0x95 0x14,ATmega328P是0x1E 0x95 0x0F。

fuse
Atmel AVR微控制器,裡頭有非揮發性的設定值,其名稱很嚇人,叫做fuse(保險絲),會讓人聯想到保險絲燒壞後必須更換新的,但事實上,fuse就是設定值而已。不過有些設定值很重要,若亂搞,單晶片可能會變得難以燒錄。

16MHz
雖然ATmega328最高可跑到20MHz,但先前的ATmega8最高只能跑到16MHz,所以Arduino繼續使用頻率16MHz,維持相容性。

STK500 starter kit、STK600 starter kit
Atmel公司的AVR開發套件,包括板子、ISP、軟體開發環境、等等。一直以來是AVR的標準開發平台,但有些人改投Arduino懷抱。

STK500開發板。


AVR Studio、Atmel Studio
Atmel公司官方的AVR整合開發環境,支援8-bit AVR與32-bit AVR,新版本(Atmel Studio 6)開始支援ARM Cortex-M。非開放原始碼、可免費下載,只有Windows版。

AVR Studio 5。


Atmel Studio 6。


PIC
Peripheral Interface Controller。Microchip公司的微控制器產品,其整合開發環境叫做MPLAB,只能在Windows上跑,但新版本叫MPLAB X,跨平台可在Windows、Mac OS X、Linux上跑。PIC在中國大陸似乎很流行。


datasheet
資料表、規格文件、規格資料。詳細列出電子元件的規格、功能、特性、腳位、溫度容忍範圍、等等。

data book
將許多電子零件晶片的datasheet收集在一本紙書裡,厚厚一本,以前電子工程師的書架上通常會有一整排data book,但有了網際網路後,datasheet都變成電子檔囉(通常是pdf格式)。

pinout、pin-out
電子元件或接頭插座之腳位功能對照表(圖)。

ATmega328晶片各腳位功能、以及與Arduino板子針腳的對照圖。


programmer燒錄器
chip programmer、device programmer、晶片燒錄器。意思是一台裝置,有能力將資料燒錄進非揮發性記憶體,諸如EPROM、EEPROM、Flash、PAL、FPGA、可程式化邏輯等等。以前學習單晶片時,並沒有像現在這麼方便 ,開發韌體時額外需要一台燒錄器,將單晶片放進去,然後燒錄,再拔起來插回電路裡,非常麻煩。我在網路找到以前的文章,常抱怨燒錄器很貴,而且有些燒錄器只能燒錄幾個型號的晶片,後來才有萬用型燒錄器。

ISP(In-System Programming)、ICSP(In-Circuit Serial Programming)
線上燒錄、線上即時燒錄。不須把要被燒錄的單晶片從線路裡拔出來。微控制器內建燒錄功能介面,接出來後(型式可能不同,如RJ-11、6腳位、10腳位),連到燒錄連接線(又稱為下載線、ISP下載線、燒錄線、線上燒錄器)、再到電腦主機(的某軟體,例如avrdude、PonyProg、UISP),便可進行燒錄。AVR、PIC、Parallax Propeller皆支援此功能。

ISP應該是個泛稱,指線上燒錄的技術,而ICSP似乎是Microchip公司增強ISP之後所開發並定義的技術,並且擁有商標權,所以Atmel的AVR文件裡,用的是ISP這個字眼。(不知為何,Arduino板子上的ISP接腳旁印的字樣是"ICSP"。)

各家ISP的介面不同,例如SPI、UART、JTAG、等等。

AVR的ISP產品有AVR ISP與AVRISP mkII(Atmel官方產品)、USBaspUSBtinyISP(由ladyada開發)、Parallel Port Programmer、等等。

ladyada開發的USBtinyISP。


Arduino as ISP、ArduinoISP
將某份程式碼燒進Arduino之後,它就搖身一變化身成為一台ISP,可用來燒錄別的單晶片(燒錄bootloader與燒錄sketch)。

self-programming、IAP(In-Application Programming)
自己寫入自己的記憶體。以Arduino的AVR晶片為例,其Flash可分為兩區,一區放bootloader,另一區放一般程式碼,Arduino板子與電腦主機連接後,主機端的某軟體(例如avrdude),可與bootloader溝通進行燒錄動作,因bootloader(燒錄者)與程式碼(被燒錄者)皆位於同一塊Flash裡,所以稱為self-progrmming。這麼一來,就不需要額外的燒錄器或下載線了。但若直接購買未含有bootloader的AVR單晶片,那就形成先有雞還是先有蛋的問題,還是必須準備一台燒錄器或下載線。

self-programming是Atmel採用的詞彙,IAP則是NXP與STMicroelectronics,技術細節或有不同,但概念應該相同。

bootloader
Arduino官方開發板的微控制器晶片皆預先已燒錄bootloader,開機時,bootloader先等個幾秒看看是否要進行燒錄,若不是就將控制權交給一般程式區裡的程式碼。燒錄(上傳)sketch時,就是由Arduino軟體開發環境裡的avrdude與Arduino板子裡的bootloader通力合作,燒錄sketch,非常方便,不需要額外的燒錄器或下載線。缺點是flash有部分會被bootloader佔據。

avrdude(AVR Downloader/UploaDEr)
位於電腦主機端的AVR燒錄軟體,支援多種燒錄器與ISP下載線、各種燒錄協定(譬如stk500、stk500v2、avr109、等等)。Arduino官方軟體開發環境使用此軟體進行燒錄。

Intel HEX FORMAT
檔案格式,通常用於燒錄時。程式產生機械碼後,再轉成這種適合燒錄的HEX格式,交由燒錄器進行燒錄。

DFU(Device Firmware Upgrade)
USB Device Firmware Upgrade是USB裝置韌體更新介面的標準,定義如何燒錄韌體到USB裝置。理論上,因為有此標準介面,在個人電腦端便可使用同一套工具,燒錄(更新)韌體到各種USB裝置裡(譬如智慧型手機)。

PWM
Pulse-Width Modulation脈波寬度調變,常用於電子式電壓調整,例如燈光亮度、馬達控制、螢幕亮度、等等。 其原理是藉由調整脈波的工作週期(Duty cycle)並影響平均值來控制電壓。

FTDI
Future Technology Devices International公司,專精於USB技術,譬如USB與RS-232或TTL邏輯訊號的轉換。

早期Arduino板子使用RS-232序列埠與主機電腦連接,但那種連接埠已經快消失了,後來改用USB,需要在USB與TTL序列介面之間作轉換,採用的是FTDI的產品,譬如FT232RL。對Arduino這邊來說並沒變,它仍然是TTL序列介面,但中間經過轉換晶片後,便能經由USB線與主機電腦(虛擬COM埠)溝通。Arduino Uno改用Atmel的產品ATmega8U2/16U2。Arduino Leonardo更進一步,其單晶片ATmega32U4已經內建了USB通訊功能,也就是說,Leonardo還可變成一個USB裝置,例如鍵盤或滑鼠。

TTL:數位電路家族之一,由雙極接面電晶體(BJT,bipolar junction transistor)與電阻器組合而成,因為邏輯閘功能與放大功能皆由電晶體負責,所以稱為TTL(Transistor-Transistor Logic)。最常見的積體電路IC為74系列,編號命名通常以德州儀器的為準。原與CMOS分庭抗禮,以前,TTL速度較快,CMOS則較省電、成本較低,不過CMOS越來越進步,反應速度已超越TTL,且製作較容易;TTL幾乎沒有發展,目前主要應用在簡單的數位電路。

TTL一詞也被拿來指稱「TTL邏輯電壓準位」,但並不一定使用TTL積體電路,而是指哪個電壓範圍代表HIGH,哪個電壓範圍代表LOW,譬如,若驅動電壓(Vcc)為5V,那麼LOW範圍會是0V~0.8V,而HIGH範圍則是2V到Vcc。常見驅動電壓還有3.3V。

Serial(序列傳輸):顧名思義,一次只傳1個位元的傳輸介面,與之相對的是一次傳送好幾個位元的並列傳輸。最少需要兩條連線,通常標示為負責傳送的TX(或TXD)以及接收的RX(RXD),雙方的接線需交叉連接方為正確。在一般個人電腦中被稱為序列埠或通訊埠(COM port),並以RS-232實體介面的連接埠出現,而在電腦裡負責將資料在序列形式與並列形式之間作轉換的硬體稱為UART(Universal Asynchronous Receiver/Transmitter)。現今的個人電腦幾乎看不見序列埠的身影,已被更高速的傳輸介面所取代,譬如USB與FireWire,但若插上藍牙轉序列埠或USB轉序列埠的轉接介面,就會以虛擬序列埠的姿態出現。

TTL Serial:符合TTL邏輯電壓準位的序列傳輸介面。

UART(Universal Asynchronous Receiver/Transmitter):實作序列傳輸介面的硬體積體電路,將資料在序列與並列形式之間做轉換。早期知名的晶片有8250、16550。個人電腦以之實作出序列埠,在DOS/Windows下被標示為COM port,至於其外接線路與連接埠,通常採用RS-232與後繼標準。若具備同步功能則稱為USART(Universal Synchronous/Asynchronous Receiver/Transmitter)。

I²C(I2C、Inter-Integrated Circuit):由Philips設計的一種序列通訊匯流排標準,屬於多主從架構,匯流排上可有多個主方(master)與多個從方(slave),主方多半是微控制器或單板電腦,從方則是各種I2C裝置,透過兩條雙向連線進行傳輸,SDA(Serial Data Line)傳輸資料,SCL(Serial Clock)則為時脈,每個I2C從方裝置各需擁有一個獨一無二的位址,以資區別。自2006年10月後,其他廠商不需權利金也能實作I2C協定,但若要取得I2C從方裝置的位址,還是要付出費用向NXP公司(其前身為Philips半導體部門)註冊。

TWI(Two-Wire Interface):與I2C完全相容,當初似乎是為了避免商標爭議,所以改用TWI名稱。在極少數狀況下,宣稱符合TWI的電子裝置可能不相容於I2C協定。

SMBus:由Intel於1995年定義的標準,以I2C為基礎但更嚴格的子集合,期許能讓電子電路與裝置能夠更加穩定可靠,並且提昇互通性;新近的I2C裝置多半也符合SMBus的規定,與之相容。

SPI(Serial Peripheral Interface Bus):一種全雙工同步序列資料傳輸協定,在SPI匯流排上的裝置有一個為主方,其餘為從方,連接線有MOSI(Master Out Slave In)、MISO(Master In Slave Out)、SCLK(Serial Clock)、SS(Slave Select),主方便是透過SS指定欲與哪一個從方溝通,並不像I2C使用位址的方式指定,主方以SCLK發出時脈,以MOSI傳送資料給從方,而從方以MISO傳送資料給主方。SPI也常被稱為SSI(Synchronous Serial Interface)。

1-Wire
Dallas半導體公司(2001年成為Maxim的子公司)的專利技術,只有一條線,卻可傳輸時脈與資料(雙向),甚至也可提供電源,這麼一來總共就只需兩條線(再加一條接地)。傳輸速率比I2C低,通常是用來溝通小型裝置,如數位溫度計。有兩種速率,標準模式16kbps,驅動模式142kbps。

Bit bang:以軟體而非專屬硬體線路來實作底層傳輸的方式,必須在程式碼裡直接設定與取樣腳位的狀態,負責訊號所有需要的參數,包括時脈、電壓準位、同步等等。優點是不需要專屬硬體,可實作出不同的傳輸協定,缺點是耗用處理器的運算時間,產生出來的訊號可能不夠精確。

USB(Universal Serial Bus):通用型序列傳輸匯流排,具備隨插即用的特性,已成為主流傳輸介面,逐漸取代各種老舊的系統。

USB class
所謂USB device class,可想像成不同的class定義了不同的電腦硬體。HID(Human Interface Device)便是鍵盤、滑鼠、遊戲搖桿,CDC(Communications Device Class)這就所謂的Virtual COM(虛擬COM埠),MSC(Mass storage Class)就是隨身碟。

Physical Computing:可翻譯為體感運算或實體互動運算,著重於透過各種硬體與軟體,讓主機電腦(數位)能與周圍環境(類比)溝通與互動,一般指手工設計與製作的藝術裝置或電子機械專案,以微控制器為中心,使用感測器偵測外界(譬如溫度、燈光、壓力、等等),使用致動器(譬如馬達、喇叭、機器手臂)影響外界。

Android Open Accessory
Android 3.1開始支援Android Open Accessory標準(回溯支援到Android 2.3.4),定義了溝通協定與API,讓外部USB周邊硬體能與Android裝置(手機或平板)溝通,讓大家遵循標準開發Android裝置的周邊配件。開發套件叫做ADK(Android Open Accessory Development Kit)。根據這套標準的開發板,有Arduino ADK、Microchip的PIC24F Accessory Development Starter Kit for Android、SparkFun的IOIO for Android、Modern Device的Freeduino USB Host Board、等等。

0.1吋(0.1")
等於2.54mm(公釐、毫米),排針排母與麵包板最常見的孔距。

AWG(American Wire Gauge)
美國線規,定義導線直徑的標準。數字越小表示線材直徑越粗,所能承載的電流就越大。以太區域網路使用Cat-5非屏蔽雙絞線一般使用AWG 24的線材,而SATA線一般是AWG 26線材。連接電子電路與麵包板時,通常使用20、22、24的線材。

Netduino
使用32-bit ARM為核心的微控制器,軟體部分為.NET Micro Framework,語言是C#,整合開發環境是Visual Studio,開源硬體平台。其腳位與Arduino相容,所以可插Arduino的shield。

.NET Gadgeteer
軟體是.NET Micro Framework,整合開發環境是Visual Studio。使用時須有一塊主板加一堆附加模組,其連接介面有一套標準,所以非常「模組化」。

Parallax BASIC Stamp、Basic Stamp 2(BS-2)
特色是採用PBASIC語言(特製後的BASIC)。

Parallax Propeller、Parallax P8X32A Propeller
多核心平行運算架構的微控制器,有8顆32位元的RISC CPU。

Basic Micro的BasicATOM
相容Basic Stamp 2,號稱更快。

Revolution Education(Rev-Ed)的PICAXE
以各種Microchip PIC晶片為基礎。

mbed
採用ARM Cortex-M。

LaunchPad
TI的產品,採用MSP430的開發板。

STM32
採用32位元ARM處理器核心的微控制器系列,STMicroelectronics公司的產品。

MaKey MaKey
一塊控制電路板,透過這個控制面板連接電腦,運用電阻感應原理,能夠將任何物體轉換成觸控介面,讓操作這件事情變得更加有趣.。

用香蕉、粘土、水、鉛筆的碳當做觸控媒介。


Uzebox
復古型電視遊樂器開發平台,以Atmel 8位元AVR微控制器為核心,開放硬體。到這裡看看眾人開發出來的遊戲

Uzebox入門開發套件組。



參考資料:

2013/01/17

Arduino撰寫自己的程式庫

不論是哪套軟體開發平台,一定會有程式庫(也可能以元件庫、類別庫、軟體開發框架的形式出現)的概念,其功用就是把某功能寫好包裝起來,隱藏細節,方便大家運用。

Arduino軟體開發環境內建了一些常用程式庫,諸如LiquidCrystal、Servo、SoftwareSerial、SPI、等等,有了它們,便只需在較抽象較上層的階級對該功能有所了解即可,不必完全知曉底層複雜的技術。

另外也有很多人將開發出來的Arduino程式包裝成程式庫開放給大家使用,譬如Dr. Monk的Timer、存取1-Wire匯流排協定的OneWire、讀取Dallas溫度感測器的DallasTemperature、解決按鈕訊號在高低電位之間彈跳Bounce、等等,

這篇的主題是撰寫自己的Arduino程式庫,將功能包裝後變成程式庫,隱藏底層細節、提供較簡易的介面,供別的專案使用,甚至供其他人使用。

首先以底下這份草稿碼,以PWM讓LED漸亮、漸暗、不斷循環,我稱之為呼吸燈。

詳情就不解說了,請參考我寫的Arduino練習:呼吸燈

int brightness = 0;
int fadeAmount = 5;
int delayDuration = 30;

void setup()  {
  pinMode(9, OUTPUT);
}

void loop()  {
  analogWrite(9, brightness);
  brightness = brightness + fadeAmount;
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount ;
  }  

  delay(delayDuration);                          
}

好,那如果想要有三個呼吸燈呢,程式會變得很複雜吧。當然啦,其實可使用計時器的程式庫,譬如Dr. Monk的Timer,就能寫出簡單易懂的程式碼,不過這篇要介紹的是自行撰寫Arduino程式庫,所以讓我寫個程式庫,將以上的程式碼包起來,方便使用。

Arduino程式庫有兩個地方,一個是內建的,我們不動它,另一個是自己安裝的,這個程式庫的目錄在sketchbook底下的libraries(若無請自行建立)。

在libraries底下新增目錄,命名為PwmLed,這就是我將撰寫的程式庫的位置,裡面放進PwmLed.cpp與PwmLed.h,這是程式庫的主體,內容如下。

(咳咳,我就不解釋C++程式語言了。)

首先是PwmLed.h:

#ifndef PwmLed_h
#define PwmLed_h

#include <inttypes.h>

class PwmLed
{

public:
  unsigned long m_lastTime;
  uint8_t m_pin;
  int m_brightness;
  int m_fadeAmount;
  unsigned long m_delayDuration;
 
  PwmLed(void);
  void set(uint8_t pin, int initBrightness, int fadeAmount, unsigned long delayDuration);
  void update(void);
};

#endif

內容很普通,就是一般的C++標頭檔。接下來是PwmLed.cpp:

// For Arduino 1.0 and earlier
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "PwmLed.h"

PwmLed::PwmLed(void)
{
}

void PwmLed::set(uint8_t pin, int initBrightness, int fadeAmount, unsigned long delayDuration)
{
    m_pin = pin;
    m_brightness = initBrightness;
    m_fadeAmount = fadeAmount;
    m_delayDuration = delayDuration;
   
    pinMode(m_pin, OUTPUT);
    analogWrite(m_pin, m_brightness);
    m_lastTime = millis();
}


void PwmLed::update(void)
{
    unsigned long t = millis();
    if(t > m_lastTime + m_delayDuration){
        m_lastTime += m_delayDuration;
       
        analogWrite(m_pin, m_brightness);
        m_brightness = m_brightness + m_fadeAmount;
   
        if (m_brightness <= 0 || m_brightness >= 255) {
            m_fadeAmount = -m_fadeAmount;
        }
    }
}

還可以再加入keywords.txt,指定程式庫的關鍵字,這麼一來,Arduino軟體開發環境的編輯器就能以不同顏色顯示。如下:

#######################################
# Syntax Coloring Map For Timer Library
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

PwmLed    KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

set    KEYWORD2
update    KEYWORD2

#######################################
# Instances (KEYWORD2)
#######################################

#######################################
# Constants (LITERAL1)
#######################################

libraries/PwmLed底下還可以放個examples目錄,存放範例,我就不管了。

程式庫至此已經準備完畢,請重新開啟Arduino軟體開發環境,應該就能在Sketch-Import Library...下看到PwmLed。

接下來就是使用了。

電路圖如下:

Arduino腳位9、10、11(具有PWM功能),各自接到220 ohm電阻、再接到LED長腳,LED短腳接地。


然後,使用PwmLed程式庫,讓三個LED變成呼吸燈的草稿碼如下:

#include <PwmLed.h>

#define LED0 9
#define LED1 10
#define LED2 11

PwmLed led0;
PwmLed led1;
PwmLed led2;

void setup()  {
  led0.set(LED0, 0, 5, 30);
  led1.set(LED1, 0, 10, 60);
  led2.set(LED2, 0, 30, 300);
}

void loop()  {
  led0.update();  
  led1.update();  
  led2.update();
}

先以set設定,參數第一個是PWM腳位,第二個是初始亮度,0不亮、255全亮,第三個是每次更新亮度時的更新幅度,越小代表變化會越平順,第四個代表更新頻率,單位是千分之一秒,越小代表越快更新。聽起來很複雜,但換換數字看看結果就清楚了。

然後在loop()裡以update更新亮度。

很簡單吧!

原始碼可到這裡下載。


參考資料: