arduino學習筆記1 - 什么是arduino?
要了解arduino就先要了解什么是單片機,arduino平台的基礎就是AVR指令集的單片機。
1、什么是單片機?它與個人計算機有什么不同?
一台能夠工作的計算機要有這樣幾個部份構成:中央處理單元CPU(進行運算、控制)、隨機存儲器RAM(數據存儲)、存儲器ROM(程序存儲)、輸入/輸出設備I/O(串行口、並行輸出口等)。在個人計算機(PC)上這些部份被分成若干塊芯片,安裝在一個被稱之為主板的印刷線路板上。而在單片機中,這些部份全部被做到一塊集成電路芯片中了,所以就稱為單片(單芯片)機,而且有一些單片機中除了上述部份外,還集成了其它部份如模擬量/數字量轉換(A/D)和數字量/模擬量轉換(D/A)等。
2、單片機有什么用?
實際工作中並不是任何需要計算機的場合都要求計算機有很高的性能,一個控制電冰箱溫度的計算機難道要用酷睿處理器嗎?應用的關鍵是看是否夠用,是否有很好的性能價格比。如果一台冰箱都需要用酷睿處理起來進行溫度控制,那價格就是天價了。
單片機通常用於工業生產的控制、生活中與程序和控制有關(如:電子琴、冰箱、智能空調等)的場合。
下圖就是一個Atmega328P-PU單片機,基於AVR指令集的8位處理器,頻率20MHz,存儲器空間32KB。
什么是Arduino?
Arduino是一個能夠用來感應和控制現實物理世界的一套工具。 它由一個基於單片機並且開放源碼的硬件平台,和一套為Arduino板編寫程序 的開發環境組成。
Arduino可以用來開發交互產品,比如它可以讀取大量的開關和傳感器信號,並且可以控制各式各樣的電燈、電機和其他物理設備。Arduino項目可以是單獨的,也可以在運行時和你電腦中運行的程序(例如:Flash,Processing,MaxMSP)進行通訊。Arduino板你可以選擇自己去手動組裝或是購買已經組裝好的;Arduino開源的IDE可以免費下載得到。
Arduino的編程語言就像似在對一個類似於物理的計算平台進行相應的連線,它基於處理多媒體的編程環境。
為什么要使用Arduino?
有很多的單片機和單片機平台都適合用做交互式系統的設計。例如:Parallax Basic Stamp, Netmedia’s BX-24,Phidgets,MIT’s Handyboard 和其它等等提供類似功能的。 所有這些工具,你都不需要去關心單片機編程繁瑣的細節,提供給你的是一套容易使用的工具包。 Arduino同樣也簡化了同單片機工作的流程,但同其它系統相比Arduino在很多地方更具有優越性,特別適合老師,學生和一些業余愛好者們使用:
-
便宜 - 和其它平台相比,Arduino板算是相當便宜了。最便宜的Arduino版本可以自己動手制作,即使是組裝好的成品,其價格也不會超過200元。
-
跨平台 - Arduino軟件可以運行在Windows,Macintosh OSX,和Linux操作系統。大部分其它的單片機系統都只能運行在Windows上。
-
簡易的編程環境 - 初學者很容易就能學會使用Arduino編程環境,同時它又能為高級用戶提供足夠多的高級應用。對於老師們來說,一般都能很方便的使用Processing 編程環境,所以如果學生學習過使用Processing 編程環境的話,那他們在使用Arduino開發環境的時候就會覺得很相似很熟悉。
-
軟件開源並可擴展 - Arduino軟件是開源的,對於有經驗的程序員可以對其進行擴展。Arduino編程語言可以通過C++庫進行擴展,如果有人想去了解技術上的細節,可以跳過Arduino語言而直接使用AVR C 編程語言(因為Arduino語言實際上是基於AVR C的)。類似的,如果你需要的話,你也可以直接往你的Arduino程序中添加AVR-C 代碼。
-
硬件開源並可擴展 - Arduino板基於 Atmel 的ATMEGA8 和ATMEGA168/328 單片機。Arduino基於Creative Commons 許可協議,所以有經驗的電路設計師能夠根據需求設計自己的模塊,可以對其擴展或改進。甚至是對於一些相對沒有什么經驗的用戶,也可以通過制作試驗板來理解Arduino是怎么工作的,省錢又省事。
Arduino基於AVR平台,對AVR庫進行了二次編譯封裝,把端口都打包好了,寄存器啦、地址指針之類的基本不用管。大大降低了軟件開發難度,適宜非專業愛好者使用。優點和缺點並存,因為是二次編譯封裝,代碼不如直接使用AVR代碼編寫精練,代碼執行效率與代碼體積都弱於AVR直接編譯。
性能:
Digital I/O 數字輸入/輸出端口0—13。
Analog I/O 模擬輸入/輸出端口0-5。
支持ICSP下載,支持TX/RX。
輸入電壓:USB接口供電或者5V-12V外部電源供電。
輸出電壓:支持3.3V級5V DC輸出。
處理器:使用Atmel Atmega168 328處理器,因其支持者眾多,已有公司開發出來32位的MCU平台支持arduino。
目前arduino的控制板最新的為Arduino Uno,如下圖:
國內使用比較多的為Arduino Duemilanove 2009,主要原因是Uno的usb控制芯片封裝方式改變,制造成本上升,其他變化不大,性價比還是Arduino Duemilanove 2009比較好。
因其開源特性,生產arduino控制板的廠商眾多,同樣的Duemilanove 2009就有很多種顏色。
對於一些對電路板大小要求比較嚴格的地方,arduino團隊提供了arduino Nano,此板體積做的非常小。如下圖:
arduino板子上基本端口如圖描述,對幾個比較特殊的端口下面詳細說明下:
VIN端口:VIN是input voltage的縮寫,表示有外部電源時的輸入端口。
AREF:Reference voltage for the analog inputs(模擬輸入的基准電壓)。使用analogReference()命令調用。
ICSP:也有稱為ISP(In System Programmer),就是一種線上即時燒錄,目前比較新的芯片都支持這種燒錄模式,包括大家常聽說的8051系列的芯片,也都慢慢采用這種簡便的燒錄方式。我們都知道傳統的燒錄方式,都是將被燒錄的芯片,從線路板上拔起,有的焊死在線路板上的芯片,還得先把芯片焊接下來才能燒錄。為了解決這種問題,發明了ICSP線上即時燒錄方式。只需要准備一條R232線(連接燒錄器),以及一條連接燒錄器與燒錄芯片針腳的連接線就可以。電源的+5V,GND,兩條負責傳輸燒錄信息的針腳,再加上一個燒錄電壓針腳,這樣就可以燒錄了。
arduino學習筆記2
通過Arduino編譯器查看串口數據
最簡單的例子:
void setup()
{
Serial.begin(9600); // 打開串口,設置波特率為9600 bps
}
void loop()
{
int val;
val=analogRead(5);//傳感器接到模擬口5,數值根據自己的需要可變
Serial.println(val,DEC);//從串口發送字符串並換行
delay(100);
}
如果電路安裝正確,按照示例代碼運行、上傳,然后點擊編譯器的Serial Monitor按鈕,就可以看到從代碼定義的輸入口(這兒是模擬口5)獲取的數據了。
arduino學習筆記3 arduino語言
-
Arduino語言是建立在C/C++基礎上的,其實也就是基礎的C語言,Arduino語言只不過把AVR單片機(微控制器)相關的一些參數設置都函數化,不用我們去了解他的底層,讓我們不了解AVR單片機(微控制器)的朋友也能輕松上手。
在與Arduino DIYER接觸的這段時間里,發現有些朋友對Arduino語言還是比較難入手,那么這里我就簡單的注釋一下Arduino語言(本人也是半罐子水,有錯的地方還請各位指正)。
/*************基礎C語言*************/
關鍵字:
語法符號:
運算符:
數據類型:
數據類型轉換:
常量:
-
HIGH | LOW 表示數字IO口的電平,HIGH 表示高電平(1),LOW 表示低電平(0)。
-
INPUT | OUTPUT 表示數字IO口的方向,INPUT 表示輸入(高阻態),OUTPUT 表示輸出(AVR能提供5V電壓 40mA電流)。
-
true | false true 表示真(1),false表示假(0)。
/******************************************/
以上為基礎c語言的關鍵字和符號,有c語言基礎的都應該了解其含義,這里也不作過多的解釋。
/*************Arduino 語言*************/
結構
功能
數字 I/O
-
pinMode(pin, mode) 數字IO口輸入輸出模式定義函數,pin表示為0~13, mode表示為INPUT或OUTPUT。
-
digitalWrite(pin, value) 數字IO口輸出電平定義函數,pin表示為0~13,value表示為HIGH或LOW。比如定義HIGH可以驅動LED。
-
int digitalRead(pin) 數字IO口讀輸入電平函數,pin表示為0~13,value表示為HIGH或LOW。比如可以讀數字傳感器。
模擬 I/O
-
int analogRead(pin) 模擬IO口讀函數,pin表示為0~5(Arduino Diecimila為0~5,Arduino nano為0~7)。比如可以讀模擬傳感器(10位AD,0~5V表示為0~1023)。
-
analogWrite(pin, value) - PWM 數字IO口PWM輸出函數,Arduino數字IO口標注了PWM的IO口可使用該函數,pin表示3, 5, 6, 9, 10, 11,value表示為0~255。比如可用於電機PWM調速或音樂播放。
擴展 I/O
-
shiftOut(dataPin, clockPin, bitOrder, value) SPI外部IO擴展函數,通常使用帶SPI接口的74HC595做8個IO擴展,dataPin為數據口,clockPin為時鍾口,bitOrder為數據傳輸方向(MSBFIRST高位在前,LSBFIRST低位在前),value表示所要傳送的數據(0~255),另外還需要一個IO口做74HC595的使能控制。
-
unsigned long pulseIn(pin, value) 脈沖長度記錄函數,返回時間參數(us),pin表示為0~13,value為HIGH或LOW。比如value為HIGH,那么當pin輸入為高電平時,開始計時,當pin輸入為低電平時,停止計時,然后返回該時間。
時間函數
-
unsigned long millis() 返回時間函數(單位ms),該函數是指,當程序運行就開始計時並返回記錄的參數,該參數溢出大概需要50天時間。
-
delay(ms) 延時函數(單位ms)。
-
delayMicroseconds(us) 延時函數(單位us)。
數學函數
-
min(x, y) 求最小值
-
max(x, y) 求最大值
-
abs(x) 計算絕對值
-
constrain(x, a, b) 約束函數,下限a,上限b,x必須在ab之間才能返回。
-
map(value, fromLow, fromHigh, toLow, toHigh) 約束函數,value必須在fromLow與toLow之間和fromHigh與toHigh之間。
-
pow(base, exponent) 開方函數,base的exponent次方。
-
sq(x) 平方
-
sqrt(x) 開根號
三角函數
隨機數函數
-
randomSeed(seed) 隨機數端口定義函數,seed表示讀模擬口analogRead(pin)函數 。
-
long random(max) 隨機數函數,返回數據大於等於0,小於max。
-
long random(min, max) 隨機數函數,返回數據大於等於min,小於max。
外部中斷函數
-
attachInterrupt(interrupt, , mode) 外部中斷只能用到數字IO口2和3,interrupt表示中斷口初始0或1,表示一個功能函數,mode:LOW低電平中斷,CHANGE有變化就中斷,RISING上升沿中斷,FALLING 下降沿中斷。
-
detachInterrupt(interrupt) 中斷開關,interrupt=1 開,interrupt=0 關。
中斷使能函數
-
interrupts() 使能中斷
-
noInterrupts() 禁止中斷
串口收發函數
-
Serial.begin(speed) 串口定義波特率函數,speed表示波特率,如9600,19200等。
-
int Serial.available() 判斷緩沖器狀態。
-
int Serial.read() 讀串口並返回收到參數。
-
Serial.flush() 清空緩沖器。
-
Serial.print(data) 串口輸出數據。
-
Serial.println(data) 串口輸出數據並帶回車符。
/**********************************/
/************Arduino語言庫文件*************/
官方庫文件
-
EEPROM - EEPROM讀寫程序庫
-
Ethernet - 以太網控制器程序庫
-
LiquidCrystal - LCD控制程序庫
-
Servo - 舵機控制程序庫
-
SoftwareSerial - 任何數字IO口模擬串口程序庫
-
Stepper - 步進電機控制程序庫
-
Wire - TWI/I2C總線程序庫
-
Matrix - LED矩陣控制程序庫
-
Sprite - LED矩陣圖象處理控制程序庫
非官方庫文件
-
DateTime - a library for keeping track of the current date and time in software.
-
Debounce - for reading noisy digital inputs (e.g. from buttons)
-
Firmata - for communicating with applications on the computer using a standard serial protocol.
-
GLCD - graphics routines for LCD based on the KS0108 or equivalent chipset.
-
LCD - control LCDs (using 8 data lines)
-
LCD 4 Bit - control LCDs (using 4 data lines)
-
LedControl - for controlling LED matrices or seven-segment displays with a MAX7221 or MAX7219.
-
LedControl - an alternative to the Matrix library for driving multiple LEDs with Maxim chips.
-
Messenger - for processing text-based messages from the computer
-
Metro - help you time actions at regular intervals
-
MsTimer2 - uses the timer 2 interrupt to trigger an action every N milliseconds.
-
OneWire - control devices (from Dallas Semiconductor) that use the One Wire protocol.
-
PS2Keyboard - read characters from a PS2 keyboard.
-
Servo - provides software support for Servo motors on any pins.
-
Servotimer1 - provides hardware support for Servo motors on pins 9 and 10
-
Simple Message System - send messages between Arduino and the computer
-
SSerial2Mobile - send text messages or emails using a cell phone (via AT commands over software serial)
-
TextString - handle strings
-
TLC5940 - 16 channel 12 bit PWM controller.
-
X10 - Sending X10 signals over AC power lines
/****************************************/
arduino學習筆記4 數據類型
有多種類型的變量,如下所述
boolean 布爾
char 字符
byte 字節
int 整數
unsigned int 無符號整數
long 長整數
unsigned long 無符號長整數
float 浮點
double 雙字節浮點
string 字符串
array 數組
arduino學習筆記5 Arduuino復合運算符
+= , -= , *= , /=
Description描述
Perform a mathematical operation on a variable with another constant or variable. The += (et al) operators are just a convenient shorthand for the expanded syntax, listed below.
對一個變量和另一個參數或變量完成一個數學運算。+=(以及其他)可以縮短語法長度。
Syntax語法
x += y; // equivalent to the expression x = x + y; // 等價於 x = x + y;
x -= y; // equivalent to the expression x = x - y; // 等價於 x = x - y;
x *= y; // equivalent to the expression x = x * y; // 等價於 x = x * y;
x /= y; // equivalent to the expression x = x / y; // 等價於 x = x / y;
Parameters參數
x: any variable type
x:任何變量類型
y: any variable type or constant
y:任何變量類型或常數
Examples范例
x = 2;
x += 4; // x now contains 6 // x現在為6
x -= 3; // x now contains 3 // x現在為3
x *= 10; // x now contains 30 // x現在為30
x /= 2; // x now contains 15 // x現在為15
Syntax語法
x++; // increment x by one and returns the old value of x
// 將x的值加1並返回原來的x的值。 ++x; // increment x by one and returns the new value of x // 將x的值加1並返回現在的x的值。
x-- ; // decrement x by one and returns the old value of x // 將x的值減1並返回原來的x的值。
--x ; // decrement x by one and returns the new value of x // 將x的值減1並返回現在的x的值。
Parameters參數
x: an integer or long (possibly unsigned)
x:一個整數或長整數(可以無符號)
Returns返回
The original or newly incremented / decremented value of the variable.
返回變量原始值或增加/消耗后的新值。
Examples范例
x = 2;
y = ++x; // x now contains 3, y contains 3 // x現在為3,y為3
y = x--; // x contains 2 again, y still contains 3 // x現在仍然為2,y將為3
arduino學習筆記6 Arduino基礎
在學語言之間,還要做的一個功課就是要明白程序的構架,這個也同樣簡單,大體可分為幾個部分。
1、聲明變量及接口名稱(int val;int ledPin=13;)。
2、setup()——函數在程序開始時使用,可以初始化變量、接口模式、啟用庫等(例如:pinMode(ledPin,OUTUPT);)。
3、loop()——在setup()函數之后,即初始化之后,loop() 讓你的程序循環地被執行。使用它來運轉Arduino。
接下來就開始學習一下幾個基本函數。
1、pinMode(接口名稱,OUTPUT或INPUT)將——接口定義為輸入或輸出接口,用在setup()函數里。
2、digitalWrite(接口名稱, HIGH或LOW)——將數字接口值至高或低。
3、digitalRead(接口名稱)——讀出數字接口的值。
4、analogWrite(接口名稱, 數值)——給一個接口寫入模擬值(PWM波)。對於 ATmega168芯片的Arduino(包括Mini或BT),該函數可以工作於 3, 5, 6, 9, 10和 11號接口。老的 ATmega8芯片的USB和 serial Arduino僅僅支持 9, 10和11號接口。
5、analogRead(接口名稱)——從指定的模擬接口讀取值,Arduino對該模擬值進行10-bit的數字轉換,這個方法將輸入的0-5電壓值轉換為 0到1023間的整數值。
6、delay()——延時一段時間,delay(1000)為一秒。
7、Serial.begin(波特率)——設置串行每秒傳輸數據的速率(波特率)。在同計算機通訊時,使用下面這些值:300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600或 115200。你也可以在任何時候使用其它的值,比如,與0號或1號插口通信就要求特殊的波特率。用在setup()函數里
8、Serial.read()——讀取持續輸入的數據。
9、Serial.print(數據,數據的進制)——從串行端口輸出數據。Serial.print(數據)默認為十進制等於Serial.print(數據,DEC)。
10、Serial.println(數據,數據的進制)——從串行端口輸出數據,跟隨一個回車和一個換行符。這個函數所取得的值與 Serial.print()一樣。
以上幾個函數是常用基本函數,還有很多以后會慢慢學習
arduino學習筆記7函數
輸入輸出函數
Arduino 內含了一些處理輸出與輸入的切換功能,相信已經從書中程式范例略知一二。
pinMode(pin, mode)
將數位腳位(digital pin)指定為輸入或輸出。
范例 :
pinMode(7,INPUT); // 將腳位 7 設定為輸入模式
digitalWrite(pin, value)
將數位腳位指定為開或關。腳位必須先透過pinMode明示為輸入或輸出模式digitalWrite才能生效。
范例 :
digitalWrite(8,HIGH); //將腳位 8設定輸出高電位
int digitalRead(pin)
將輸入腳位的值讀出,當感測到腳位處於高電位時時回傳HIGH,否則回傳LOW。
范例 :
val = digitalRead(7); // 讀出腳位 7 的值並指定給 val
int analogRead(pin)
讀出類比腳位的電壓並回傳一個 0到1023 的數值表示相對應的0到5的電壓值。
范例 :
val = analogRead(0); //讀出類比腳位 0 的值並指定給 val變數
analogWrite(pin, value)
改變PWM腳位的輸出電壓值,腳位通常會在3、5、6、9、10與11。Value變數范圍0-255,例如:輸出電壓2.5伏特(V),該值大約是128。
范例 :
analogWrite(9,128); // 輸出電壓約2.5伏特(V)
unsigned long pulseIn(pin, value)
設定讀取腳位狀態的持續時間,例如使用紅外線、加速度感測器測得某一項數值時,在時間單位內不會改變狀態。
范例 :
time = pulsein(7,HIGH); // 設定腳位7的狀態在時間單位內保持為HIGH
shiftOut(dataPin, clockPin, bitOrder, value)
把資料傳給用來延伸數位輸出的暫存器,函式使用一個腳位表示資料、一個腳位表示時脈。bitOrder用來表示位元間移動的方式(LSBFIRST最低有效位元或是MSBFIRST最高有效位元),最后value會以byte形式輸出。此函式通常使用在延伸數位的輸出。
范例 :
shiftOut(dataPin, clockPin, LSBFIRST, 255);
時間函數
控制與計算晶片執行期間的時間
unsigned long millis()
回傳晶片開始執行到目前的毫秒
范例:
duration = millis()-lastTime; // 表示自"lastTime"至當下的時間
delay(ms)
暫停晶片執行多少毫秒
范例:
delay(500); //暫停半秒(500毫秒)
delay Microseconds(us)
暫停晶片執行多少微秒
范例:
delayMicroseconds(1000); //暫停1豪秒
數學函式
三角函數以及基本的數學運算
min(x, y)
回傳兩數之間較小者
范例:
val = min(10,20); // 回傳10
max(x, y)
回傳兩數之間較大者
范例:
val = max(10,20); // 回傳20
abs(x)
回傳該數的絕對值,可以將負數轉正數。
范例:
val = abs(-5); // 回傳5
constrain(x, a, b)
判斷x變數位於a與b之間的狀態。x若小於a回傳a;介於a與b之間回傳x本身;大於b回傳b
范例:
val = constrain(analogRead(0), 0, 255); // 忽略大於255的數
map(value, fromLow, fromHigh, toLow, toHigh)
將value變數依照fromLow與fromHigh范圍,對等轉換至toLow與toHigh范圍。時常使用於讀取類比訊號,轉換至程式所需要的范圍值。
例如:
val = map(analogRead(0),0,1023,100, 200); // 將analog0 所讀取到的訊號對等轉換至100 – 200之間的數值。
double pow(base, exponent)
回傳一個數(base)的指數(exponent)值。
范例:
double x = pow(y, 32); // 設定x為y的32次方
double sqrt(x)
回傳double型態的取平方根值。
范例:
double a = sqrt(1138); // 回傳1138平方根的近似值 33.73425674438
double sin(rad)
回傳角度(radians)的三角函數sine值。
范例:
double sine = sin(2); // 近似值 0.90929737091
double cos(rad)
回傳角度(radians)的三角函數cosine值。
范例:
double cosine = cos(2); //近似值-0.41614685058
double tan(rad)
回傳角度(radians)的三角函數tangent值。
范例:
double tangent = tan(2); //近似值-2.18503975868
亂數函式
產生亂數
randomSeed(seed)
事實上在Arduino里的亂數是可以被預知的。所以如果需要一個真正的亂數,可以呼叫此函式重新設定產生亂數種子。你可以使用亂數當作亂數的種子,以確保數字以隨機的方式出現,通常會使用類比輸入當作亂數種子,藉此可以產生與環境有關的亂數(例如:無線電波、宇宙雷射線、電話和螢光燈發出的電磁波等)。
范例:
randomSeed(analogRead(5)); // 使用類比輸入當作亂數種子
long random(max)
long random(min, max)
回傳指定區間的亂數,型態為long。如果沒有指定最小值,預設為0。
范例:
long randnum = random(0, 100); // 回傳0 – 99 之間的數字
long randnum = random(11); // 回傳 0 -10之間的數字
序列通訊
你可以在第五章看見一些使用序列埠與電腦交換訊息的范例,以下是函式解釋。
Serial.begin(speed)
你可以指定Arduino從電腦交換訊息的速率,通常我們使用9600 bps。當然也可以使用其他的速度,但是通常不會超過115,200 bps(每秒位元組)。
范例:
Serial.begin(9600);
Serial.print(data)
Serial.print(data, encoding)
經序列埠傳送資料,提供編碼方式的選項。如果沒有指定,預設以一般文字傳送。
范例:
Serial.print(75); // 列印出 "75"
Serial.print(75, DEC); //列印出 "75"
Serial.print(75, HEX); // "4B" (75 的十六進位)
Serial.print(75, OCT); // "113" (75 in的八進位)
Serial.print(75, BIN); // "1001011" (75的二進位)
Serial.print(75, BYTE); // "K" (以byte進行傳送,顯示以ASCII編碼方式)
Serial.println(data)
Serial.println(data, encoding)
與Serial.print()相同,但會在資料尾端加上換行字元( )。意思如同你在鍵盤上打了一些資料后按下Enter。
范例:
Serial.println(75); //列印出"75 "
Serial.println(75, DEC); //列印出"75 "
Serial.println(75, HEX); // "4B "
Serial.println(75, OCT); // "113 "
Serial.println(75, BIN); // "1001011 "
Serial.println(75, BYTE); // "K "
int Serial.available()
回傳有多少位元組(bytes)的資料尚未被read()函式讀取,如果回傳值是0代表所有序列埠上資料都已經被read()函式讀取。
范例:
int count = Serial.available();
int Serial.read()
讀取1byte的序列資料
范例:
int data = Serial.read();
Serial.flush()
有時候因為資料速度太快,超過程式處理資料的速度,你可以使用此函式清除緩沖區內的資料。經過此函式可以確保緩沖區(buffer)內的資料都是最新的。
范例:
Serial.flush();
arduino學習筆記8數字輸入
在數字電路中開關(switch)是一種基本的輸入形式,它的作用是保持電路的連接或者斷開。Arduino從數字I/O管腳上只能讀出高電平(5V)或者低電平(0V),因此我們首先面臨到的一個問題就是如何將開關的開/斷狀態轉變成Arduino能夠讀取的高/低電平。解決的辦法是通過上 /下拉電阻,按照電路的不同通常又可以分為正邏輯(Positive Logic)和負邏輯(Inverted Logic)兩種。
在正邏輯電路中,開關一端接電源,另一端則通過一個10K的下拉電阻接地,輸入信號從開關和電阻間引出。當開關斷開的時候,輸入信號被電阻“拉”向地,形成低電平(0V);當開關接通的時候,輸入信號直接與電源相連,形成高電平。對於經常用到的按壓式開關來講,就是按下為高,抬起為低。
在負邏輯電路中,開關一端接地,另一端則通過一個10K的上拉電阻接電源,輸入信號同樣也是從開關和電阻間引出。當開關斷開時,輸入信號被電阻“拉”向電源,形成高電平(5V);當開關接通的時候,輸入信號直接與地相連,形成低電平。對於經常用到的按壓式開關來講,就是按下為低,抬起為高。
為了驗證Arduino數字I/O的輸入功能,我們可以將開關接在Arduino的任意一個數字I/O管腳上(13除外),並通過讀取它的接通或者斷開狀態,來控制其它數字I/O管腳的高低。本實驗采用的原理圖如下所示,其中開關接在數字I/O的7號管腳上,被控的發光二極管接在數字I/O的13號 管腳上:
相應的代碼為:
int ledPin = 13;
int switchPin = 7;
int value = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(switchPin, INPUT);
}
void loop() {
value = digitalRead(switchPin);
if (HIGH == value) {
// turn LED off
digitalWrite(ledPin, LOW);
} else {
// turn LED on
digitalWrite(ledPin, HIGH);
}
}
由於采用的是負邏輯電路,開關按下時用digitalRead()函數讀取到的值為LOW,此時再用digitalWrite()函數將發光二極管所在的管腳置為高,點亮發光二極管。同理,當開關抬起時,發光二極管將被熄滅,這樣我們就實現了用開關來控制發光二極管的功能。
arduino學習筆記9 Arduino的數字輸出
Arduino的數字I/O被分成兩個部分,其中每個部分都包含有6個可用的I/O管腳,即管腳2 到管腳7和管腳8到管腳13。除了管腳13上接了一個1K的電阻之外,其他各個管腳都直接連接到ATmega上。我們可以利用一個6位的數字跑馬燈,來對 Arduino數字I/O的輸出功能進行驗證。
電路中在每個I/O管腳上加的那個1K電阻被稱為限流電阻,由於發光二極管在電路中沒有等效電阻值,使用限流電阻可以使元件上通過的電流不至於過大,能夠起到保護的作用。
該工程對應的代碼為:
int BASE = 2;
int NUM = 6;
int index = 0;
void setup()
{
for (int i = BASE; i < BASE + NUM; i ++) {
pinMode(i, OUTPUT);
}
}
void loop()
{
for (int i = BASE; i < BASE + NUM; i ++) {
digitalWrite(i, LOW);
}
digitalWrite(BASE + index, HIGH);
index = (index + 1) % NUM;
delay(100);
}
下載並運行該工程,連接在Arduino數字I/O管腳2到管腳7上的發光二極管會依次點亮0.1秒,然后再熄滅:
這個實驗可以用來驗證數字I/O輸出的正確性。Arduino上一共有十二個數字I/O管腳,我們可以用同樣的辦法驗證其他六個管腳的正確性,而這只需要對上述工程的第一行做相應的修改就可以了:
int BASE = 8;
arduino學習筆記10 Arduino的串口輸入
串行通信是在實現在PC機與微控制器進行交互的最簡單的辦法。之前的PC機上一般都配有標准的 RS-232或者RS-422接口來實現串行通信,但現在這種情況已經發生了一些改變,大家更傾向於使用USB這樣一種更快速但同時也更加復雜的方式來實現串行通信。盡管在有些計算機上現在已經找不到RS-232或者RS-422接口了,但我們仍可以通過USB/串口或者PCMCIA/串口這樣的轉換器, 在這些設備上得到傳統的串口。
通過串口連接的Arduino在交互式設計中能夠為PC機提供一種全新的交互方式,比如用PC機控制一些之前看來非常復雜的事情,像聲音和視頻等。很多場合中都要求Arduino能夠通過串口接收來自於PC機的命令,並完成相應的功能,這可以通過Arduino語言中提供的 Serial.read()函數來實現。
在這一實驗中我們同樣不需要任何額外的電路,而只需要用串口線將Arduino和PC機連起來就可以了,相應的Arduino工程代碼為:
int ledPin = 13;
int val;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
val = Serial.read();
if (-1 != val) {
if ('H' == val) {
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
}
}
}
把工程下載到Arduino模塊中之后,在Arduino集成開發環境中打開串口監視器並將波特率設置為9600,然后向Arduino模塊發送字符H,如下圖所示:
該工程運行起來之后會不斷調用Serial.read()函數從串口獲得數據。Arduino語言提供的這個函數是不阻塞的,也就是說不論串口上是否真的有數據到達,該函數都會立即返回。Serial.read()函數每次只讀取一個字節的數據,當串口上有數據到達的時候,該函數的返回值為到達的數 據中第一個字符的ASCII碼;當串口上沒有數據到達的時候,該函數的返回值則為-1。
Arduino語言的參考手冊中沒 有對Serial.read()函數做過多的說明,我的一個疑問是如果PC機一次發送的數據太多,Arduino是否提供相應的串口緩存功能來保證數據不會丟失?Arduino語言中提供的另外一個函數Serial.available()或許能夠幫助我們用實驗來進行驗證:
int ledPin = 13;
int val;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
val = Serial.read();
if (-1 != val) {
if ('H' == val) {
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
Serial.print("Available: ");
Serial.println(Serial.available(), DEC);
}
}
}
函數Serial.available()的功能是返回串口緩沖區中當前剩余的字符個數,按照Arduino提供的該函數的說明,串口緩沖區中最多能緩沖128個字節。我們可以一次給Arduino模塊發送多個字符,來驗證這一功能:
在這一實驗中,每當Arduino成功收到一個字符H,連接在數字I/O端口管腳13上的發光二極管就會閃爍一次:
arduino學習筆記11 Arduino的串口輸出
在許多實際應用場合中我們會要求在Arduino和其它設備之間實現相互通信,而最常見通常也是最簡單的辦法就是使用串行通信。在串行通信中,兩個設備之間一個接一個地來回發送數字脈沖,它們之間必須嚴格遵循相應的協議以保證通信的正確性。
在PC機上上最常見的串行通信協議是RS-232串行協議,而在各種微控制器(單片機)上采用的則是TTL串行協議。由於這兩者的電平有很大的不同,因此在實現PC機和微控制器的通信時,必須進行相應的轉換。完成RS-232電平和TTL電平之間的轉換一般采用專用芯片,如MAX232等,但在 Arduino上是用相應的電平轉換電路來完成的。
根據Arduino的原理圖我們不難看出,ATmega的RX和TX引腳一方面直接接到了數字I/O端口的0號和1號管腳,另一方面又通過電平轉換電路接到了串口的母頭上。因此,當我們需要用Arduino與PC機通信時,可以用串口線將兩者連接起來;當我們需要用 Arduino與微控制器(如另一塊Arduino)通信時,則可以用數字I/O端口的0號和1號管腳。
串行通信的難點在於參數的設置,如波特率、數據位、停止位等,在Arduino語言可以使用Serial.begin()函數來簡化這一任務。為了實現數據的發送,Arduino則提供了Serial.print()和Serial.println()兩個函數,它們的區別在於后者會在請求發送的數 據后面加上換行符,以提高輸出結果的可讀性。
在這一實驗中沒有用到額外的電路, 我們只需要用串口線將Arduino和PC機連起來就可以了,相應的代碼為:
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Hello World!");
delay(1000);
}
在將工程下載到Arduino模塊中之后,在Arduino集成開發環境的工具欄中單擊“Serial Monitor”控制,打開串口監視器:
接着將波特率設置為9600,即保持與工程中的設置相一致:
如果一切正常,此時我們就可以在Arduino集成開發環境的Console窗口中看到串口上輸出的數據了:
為了檢查串口上是否有數據發送,一個比較簡單的辦法是在數字I/O端口的1號管腳(TX)和5V電源之間接一個發光二極管,如下面的原理圖所示:
這樣一旦Arduino在通過串口向PC機發送數據時,相應的發光二極管就會閃爍,實際應用中這是一個非常方便的調試手段;-)
arduino學習筆記17蜂鳴器實驗
本次實驗所用的為下圖所示的這種小型無源蜂鳴器
通過上網查詢參數,得到其工作電壓為5V,和arduino控制板數字端口輸出電壓一致,所以不需要接電阻。可直接接上使用。
先簡單介紹一下這種小型蜂鳴器。
小型蜂鳴器因其體積小(直徑只有6mm)、重量輕、價格低、結構牢靠,而廣泛地應用在各種需要發聲的電器設備、電子制作和單片機等電路中。這種蜂鳴器分有源蜂鳴器與無源蜂鳴器
下圖為有源蜂鳴器
下圖為無源蜂鳴器
從外觀上看,兩種蜂鳴器好像一樣,如果將蜂鳴器引腳朝上時,可以看到,有綠色電路板的是一種無源蜂鳴器,沒有電路板而使用黑膠密封的是一種有源蜂鳴器。從外觀上並不能絕對的區分出有源與無源,最可靠的做法除了查看產品的參數手冊以外,還有就是使用萬用表測試蜂鳴器電阻,只有8Ω或者16Ω的是無源蜂鳴器,電阻在幾百歐以上的是有源蜂鳴器。
有源蜂鳴器直接接上額定電源(新的蜂鳴器在標簽上都有注明)就可以連續發聲,而無源蜂鳴器則和電磁揚聲器一樣,需要接在音頻輸出電路中才能發聲。
簡單介紹完蜂鳴器以后先看一下硬件連接示意圖
把下面的代碼上傳到arduino控制板上,看看實驗結果。
-
int buzzer=7;//設置控制蜂鳴器的數字IO腳
-
void setup()
-
{
-
pinMode(buzzer,OUTPUT);//設置數字IO腳模式,OUTPUT為輸出
-
}
-
void loop()
-
{
-
unsigned char i,j;//定義變量
-
while(1)
-
10. {
-
11. for(i=0;i<80;i++)//輸出一個頻率的聲音
-
12. {
-
13. digitalWrite(buzzer,HIGH);//發聲音
-
14. delay(1);//延時1ms
-
15. digitalWrite(buzzer,LOW);//不發聲音
-
16. delay(1);//延時ms
-
17. }
-
18. for(i=0;i<100;i++)//輸出另一個頻率的聲音
-
19. {
-
20. digitalWrite(buzzer,HIGH);//發聲音
-
21. delay(2);//延時2ms
-
22. digitalWrite(buzzer,LOW);//不發聲音
-
23. delay(2);//延時2ms
-
24. }
-
25. }
26. }
arduino學習筆記19按鍵實驗
按鍵是一種常用的控制電器元件,常用來接通或斷開電路,從而達到控制電機或者其他設備運行的開關。按鍵的外觀多種多樣,本次實驗使用的是這種微型按鍵,6mm的,如下圖。
此種按鍵有4個腳,從背面看是這樣子的。
在按鍵沒有按下去的時候1,2號腳相連,3,4號腳相連。按鍵按下去的時候,1,2,3,4號腳就全部接通。
本次實驗使用按鍵來控制led的亮或者滅。
一般情況是直接把按鍵開關串聯在led的電路中來開關,這種應用情況比較單一。
這次實驗通過間接的方法來控制,按鍵接通后判斷按鍵電路中的輸出電壓,如果電壓大於4.88V,就使給LED電路輸出高電平,反之就輸出低電平。使用邏輯判斷的方法來控制LED亮或者滅,此種控制方法應用范圍較廣。
本次連接方法如下圖。按鍵開關兩段一端連接5V接口,一端連接模擬5號口。LED長針腳串聯220Ω電阻連接數字7號口,短針腳連接GND。
把下面的代碼上傳到arduino控制板上,看看效果。
-
int key=7;//設置LED的數字IO腳
-
void setup()
-
{
-
pinMode(key,OUTPUT);//設置數字IO引腳為輸出模式
-
}
-
void loop()
-
{
-
int i;//定義變量
-
while(1)
-
{
-
i=analogRead(5);//讀取模擬5口電壓值
-
if(i>1000)//如果電壓值大於1000(即4.88V)
-
digitalWrite(key,HIGH);//設置第七引腳為高電平,點亮led燈
-
else
-
digitalWrite(key,LOW);//設置第七引腳為低電平,熄滅led燈
-
}
-
}
本次實驗使用到analogRead()這個新命令。
analogRead()作用是讀取模擬口的數值。默認是把0-5V的輸入電壓分成1024份,每一份大約為0.049V,其數值在0-1023之間。
在本次程序代碼中的讀取數值如果大於512則給LED輸出高電平, 所對應的電壓也就為大於2.5V。
analogRead()命令輸入的范圍與分辨率可以使用analogReference()命令進行改動。
剛開始本實驗選用的判斷標准是512,也就是2.5V。但是有網友按照教程的方法進行試驗發現有問題,有時不需要按按鈕燈就會自己亮。根據多次試驗與分析后,確定其為各種干擾所致。比如感應電流等等不少都是大於2.5V的,所以為了提高准確度,只能提高判斷的電壓,本次實驗就是提高到1000(4.88V)。人體自身也帶電,早中晚還個不一樣。下面的實驗就是把模擬5號口判斷標准定位512,用手去觸摸模擬5號口導線就可以點亮LED。
arduino學習筆記20 PWM控制LED實驗 PWM講解
本次實驗通過PWM來控制一盞LED燈,讓它慢慢變亮再慢慢變暗,如此循環。下面是接線圖:
-
/*
-
本次實驗演示如何通過analogWrite()命令使連接9號端口的LED燈亮度逐漸變化
-
*/
-
int brightness = 0; //定義整數型變量brightness與其初始值,此變量用來表示LED的亮度。
-
int fadeAmount = 5; //定義整數型變量fadeAmount,此變量用來做亮度變化的增減量。
-
-
void setup() {
-
-
pinMode(9, OUTPUT);// 設置9號口為輸出端口:
-
}
-
-
void loop() {
-
-
analogWrite(9, brightness);//把brightness的值寫入9號端口
-
-
brightness = brightness + fadeAmount;//改變brightness值,使亮度在下一次循環發生改變
-
-
if (brightness == 0 || brightness == 255) {
-
fadeAmount = -fadeAmount ; //在亮度最高與最低時進行翻轉
-
}
-
-
delay(30); //延時30毫秒
-
}
analogWrite()
其作用是給端口寫入一個模擬值(PWM波)。可以用來控制LED燈的亮度變化,或者以不同的速度驅動馬達。當執行analogWrite()命令后,端口會輸出一個穩定的占空比的方波。除非有下一個命令來改變它。PWM信號的頻率大約為490Hz.
在使用ATmega168與ATmega328的arduino控制板上,其工作在3,5,6,9,10,11端口。Arduino Mega控制板,可以工作於2-13號端口。在更古老的基於ATmega8的arduino控制板上,analogWrite()命令只能工作於9,10,11號端口。在使用analogWrite()命令前,可以不使用pinMode()命令把端口定義為輸出端口,當然如果定義了更好,這樣利於程序語言規范。
語法
analogWrite(pin, value)
參數
pin:寫入的端口
value:占空比:在0-255之間。
注釋與已知問題
當PWM輸出與5,6號端口的時候,會產生比預期更高的占空比。原因是PWM輸出所使用的內部時鍾,millis()與delay()兩函數也在使用。所以要注意使用5,6號端口時,空占比要設置的稍微低一些,或者會產生5,6號端口無法輸出完全關閉的信號。
PWM(Pulse-width modulation)脈寬調制
PWM是使用數字手段來控制模擬輸出的一種手段。使用數字控制產生占空比不同的方波(一個不停在開與關之間切換的信號)來控制模擬輸出。額~~這個說的太專業了,還是說的通俗點。
以本次實驗來看,端口的輸入電壓只有兩個0V與5V。如我我想要3V的輸出電壓怎么辦。。。有同學說串聯電阻,對滴,這個方法是正確滴。但是如果我想1V,3V,3.5V等等之間來回變動怎么辦呢?不可能不停地切換電阻吧。這種情況下。。。就需要使用PWM了。他是怎么控制的呢,對於arduino的數字端口電壓輸出只有LOW與HIGH兩個開關,對應的就是0V與5V的電壓輸出,咱本把LOW定義為0,HIGH定義為1.一秒內讓arduino輸出500個0或者1的信號。如果這500個全部為1,那就是完整的5V,如果全部為0,那就是0V。如果010101010101這樣輸出,剛好一半一半,輸出端口就感覺是2.5V的電壓輸出了。這個和咱們放映電影是一個道理,咱們所看的電影並不是完全連續的,它其實是每秒輸出25張圖片,在這種情況下人的肉眼是分辨不出來的,看上去就是連續的了。PWM也是同樣的道理,如果想要不同的電壓,就控制0與1的輸出比例控制就ok~當然。。。這和真實的連續輸出還是有差別的,單位時間內輸出的0,1信號越多,控制的就越精確。
在下圖中,綠線之間代表一個周期,其值也是PWM頻率的倒數。換句話說,如果arduino PWM的頻率是500Hz,那么兩綠線之間的周期就是2毫秒。 analogWrite() 命令中可以操控的范圍為0-255, analogWrite(255)表示100%占空比(常開), analogWrite(127)占空比大約為50%(一半的時間)。
傳統方法實現PWM
除了使用analogWrite()命令實現PWM,還可以通過傳統方法來控制電平的開關時間來設置。
請看如下代碼
-
void setup()
-
{
-
pinMode(13, OUTPUT);//設定13號端口為輸出
-
}
-
-
void loop()
-
{
-
digitalWrite(13, HIGH);
-
delayMicroseconds(100); // 大約10%占空比的1KHz方波
-
digitalWrite(13, LOW);
-
delayMicroseconds(900);
-
}
這種方法的的優點是他可以使用任意數字端口做輸出端口。而且可以自己隨意設定占空比與頻率。一個主要的缺點是任何中斷都會影響時鍾,這樣就會導致很大的抖動,除非你禁用中斷。第二個卻就是CPU在處理輸出的時候,就無法做其他事情了。
上面的代碼用到了一個新的命令
delayMicroseconds()
其作用是產生一個延時,計量單位是微秒,1000微秒=1毫秒。目前delayMicroseconds()最大值為16383。如果值大於1000,推薦使用delay() 命令。
arduino學習筆記22光控LED實驗
光敏電阻又稱光導管,常用的制作材料為硫化鎘,另外還有硒、硫化鋁、硫化鉛和硫化鉍等材料。這些制作材料具有在特定波長的光照下,其阻值迅速減小的特性。這是由於光照產生的載流子都參與導電,在外加電場的作用下漂移運動,從而使光敏電阻的阻值迅速下降。
光敏電阻的工作原理基於內光電效應。在半導體光敏材料的兩端裝上電極引線,將其封裝在帶有透明窗的管殼里就構成光敏電阻,為了增加靈敏度,兩電極常做成梳狀。在有光照射時,射入的光強,電阻減小,射入的光弱,電阻增大。
下圖就是一個光敏電阻
本次實驗設計的效果是,當光照正常的時候led燈是滅的,當周圍變暗時led燈變亮。
因為光敏電阻受不同光照影響變化很大,所以本次實驗的參數是在60W三基色節能燈照射下實驗(無日光照射),同樣亮度的日光下光敏電阻的阻值會比日光燈下低不少,估計和不同光的波段有關系。不同環境下實驗使用的參數不同,大家根據原理進行調整。
實驗前先測量一下當前環境下光敏電阻的亮阻值與暗阻值
下圖是測出來的LED亮阻值,為9.1KΩ
下圖是測出來的LED暗阻值,為32.4KΩ
硬件連接圖如下
根據測出來的亮阻9.1KΩ,暗阻32.4歐姆。選定分壓電阻為10KΩ。因為當有遮擋物的后,阻值會變大。假設亮阻為10KΩ(對於光敏電阻來說,與測量出來的9.1KΩ差別不大,計算起來更加方便了),分壓阻值為10K歐姆。模擬2號口所測量的觸發電壓為10KΩ分壓電阻的,在5V電源供電下,亮與暗轉換的觸發電壓為5×10÷(10+10)=2.5V。當光線越暗,光敏電阻的阻值也就越大,分壓兩端電壓也就越小。所以觸發條件就為≤2.5V。(不同光照條件下觸發電壓不同,請根據實驗環境進行調整。)
程序代碼如下
-
int photocellPin = 2; //定義變量photocellsh=2,為電壓讀取端口。
-
int ledPin = 12; //定義變量ledPin=12,為led電平輸出端口
-
int val = 0; //定義val變量的起始值
-
-
-
void setup() {
-
pinMode(ledPin, OUTPUT); //使ledPin為輸出模式
-
}
-
-
void loop() {
-
val = analogRead(photocellPin); //從傳感器讀取值
-
if(val<=512){ //512=2.5V,想讓傳感器敏感一些的時候,把數值調高,想讓傳感器遲鈍的時候把數值調低。
-
digitalWrite(ledPin, HIGH); //當val小於512(2.5V)的時候,led亮。
-
}
-
else{
-
digitalWrite(ledPin, LOW);
-
}
-
}