本篇介紹Arduino模擬輸入功能,通過讀取電位器輸入的電壓值來控制LED燈的亮度。另外補充通過純軟件編程的方式再做同樣的操作,旨在提高讀者對AnalogRead和AanlogWrite函數這兩個函數的理解,并了解使用電位器調光的原理。
實驗要求
3.1 Arduino 模數轉換函數 AnalogRead的用法
(在哪些引腳上可用,給出一個以可變電阻分壓為輸入,從串口輸出模數轉換數值的例程)
3.2 用電位器實現調光LED燈(使用AanlogWrite函數,即項目2中的2.2方式)
(Fritzing繪制的電路圖、工作原理的說明,包含完整注釋的源代碼)
3.3 用電位器實現調光LED燈(使用軟件編程的方法,即項目2中的2.1方式)
(工作原理的說明,包含完整注釋的源代碼,與2.1代碼的比較)
實驗的基本原理
- 模擬輸入引腳是帶有ADC(Analog-to-Digital Converter,模數轉換器)功能的引腳。它可以將外部輸入的模擬信號轉換為芯片運算時可以識別的數字信號,從而實現讀入模擬值的功能。
- Arduino 模擬輸入功能有10位精度,即可以將0~5V的電壓信號轉換為0~1023的整數形式表示。
- 我們通過使用analogRead() 函數讀取電位器輸入的電壓值,然后通過analogWrite()函數來控制LED燈亮度。
- 最后使用純軟件編程的方法(使用delay函數控制占空比和時間)實現電位器調光,突破了模擬輸入端口個數的限制,走向了更普遍化的引腳。
(一)模數轉換函數 AnalogRead的用法與電位器的工作原理介紹
函數介紹
-
AnalogRead:模擬引腳( IO口)讀取函數
1.說明:用于從Arduino的輸入引腳讀取數值。Arduino 模擬輸入功能有10位數模轉換通道,意味著可以將0~5V的電壓信號轉換為0~1023的整數形式表示。
注意:在模擬輸入引腳沒有任何連接的情況下,用analogRead指令讀取該引腳,這時獲得的返回值為不固定的數值。這個數值可能受多種因素的影響,如將手靠近引腳也可能會引起返回值的變化。
2.語法:AnalogRead(pin)
3.參數:1個 。例如AnalogRead(pin),pin表示被讀取的模擬引腳號,也就是A0~A5引腳,因為能輸入模擬信號的只有這6個引腳,所以不用指定第二個參數。
4.返回值:0~1023之間的整數
元器件介紹——電位器
電位器是一個可調的電阻,具有三個引出端、阻值可按某種變化規律調節的電阻元件。電位器通常由電阻體和可移動的電刷組成。當電刷沿電阻體移動時,在輸出端即獲得與位移量成一定關系的電阻值或電壓。
電位器既可作三端元件使用也可作二端元件使用。后者可視作一可變電阻器,由于它在電路中的作用是獲得與輸入電壓(外加電壓)成一定關系的輸出電壓,因此稱之為電位器。
其原理如下圖所示:
通過旋轉旋鈕改變2號腳位置,從而改變2號腳到兩端的阻值。實驗中將1腳和3腳分別接到開發板的5V和GND,再通過模擬輸入引腳A0(A0~A5都可以)來讀取電位器2號腳分得的電壓,其范圍在0V和5V之間。
示例程序
在本示例中,我們將電位器的3個引腳分別接在5V、A0引腳和GND,通過調節電位器,A0模擬引腳的輸入電壓在0-5V之間,在Arduino內置的模擬數字功能轉化下,將該輸入電壓映射到數值0~1023。這一數值將通過串口監視器顯示。至于串口監視器,你現在只需要知道它是Arduino板與其他設備相互通信的方式就可以了,如果你感興趣的話,http://www.lxweimin.com/p/a102ebeb1f1f里有詳細的關于串口監視器的介紹。
下面是實物連接圖:
由于沒有直接可觀察的輸出,所以我們調節電位器并不能知道Arduino內部的工作機制,所以下一步就是通過寫代碼,利用軟件的方式解決我們的疑惑,正所謂軟硬兼施嘛!(代碼可直接復制使用)
int pin=A0;//定義變量pin,為模擬輸入接口
int val=0;//暫存來自電位器的變量數值
void setup() {
//Arduino串口通訊初始化
Serial.begin(9600);//設置波特率為9600
}
void loop() {
//讀取引腳A0輸入信號
val = analogRead(pin);//讀取傳感器的模擬值并賦值給val,也就是將A0輸入的值轉化為0~1023之間的數值
Serial.println(val);//通過串口顯示變量val的值
}
下一步就是在我們的編譯環境中運行代碼,首先確保你的硬件連接已經準確無誤的完成(如示例連接圖),然后點擊上傳。
上傳成功后,旋轉你的電位器,咦?怎么沒什么變化?因為我們現在沒有接任何輸出設備,當然是看不到外在的變化的。不過我們可以通過Arduino IDE的串口監視器查看旋轉電位器之后究竟發生了什么。
好了,現在你可以打開你的串口監視器了,也就是右上角的搜索放大鏡,打開后旋轉電位器你就會發現一串從小到大(或從大到小)的數字飛速從你的眼前流過,從0到1023。如下圖:
如果你能看到的話,那么恭喜你已經成功完成串口輸出模數轉換并掌握了analogRead函數的用法!
(二)使用AanlogWrite函數和電位器實現調光LED
我們已經學會了用電位器調節輸出0~5V的電壓,下一步就是用LED燈將最終的結果顯示出來。
實驗材料:
- Arduino Nano開發板
- 配套USB數據線
- 面包板及配套連接線
- 1個LED燈
- 1個470Ω限流電阻
- 1個電位器
搭建電路圖:
Arduino板5v和GND分別用跳線連接到面包板的上下兩排對應的位置。直插LED燈正極連接限流電阻,電阻另一端連接開發板第10引腳,LED燈負極接開發板GND(也就是藍色排)。電位器1號腳和3號腳分別連接開發板5V(紅排)和GND(藍排),2號腳連接開發板A0(模擬輸入)引腳。
Fritzing繪制連接圖:
實物連接圖如下:
編寫代碼:
下一步就是通過代碼將程序上傳到你的Arduino開發板上,你可以復制下面的代碼到IDE中,連接你的開發板,選擇好端口,保存并上傳。
int potpin = 0; //定義模擬輸入接口0
int ledPin = 10;//定義數字輸出接口10
int val = 0; //暫存來自電位器的變量數值
void setup() {
pinMode(ledPin, OUTPUT);//定義數字接口10為輸出
Serial.begin(9600);//設置波特率為9600,可以省略
//注意:模擬接口自動設置為輸入
}
void loop() {
val = analogRead(potpin);//讀取傳感器的模擬值并賦值給val
Serial.println(val);//顯示變量val的值,可以省略
analogWrite(ledPin, val/4); //打開LED并設置亮度(PWM 輸出最大255)
}
(注意:為什么這里定義的端口要用potpin?)
因為電位器的英文名是Potentiometer,這里取自它的前幾個字母,以便與其他引腳區分開。
實際操作圖:
實驗現象
通過旋轉電位器旋鈕,LED燈亮度改變。如果用串口監視的話,就會在監視器顯示相應的數值。
函數介紹
-
AnalogWrite
1.說明:將一個模擬數值寫進Arduino引腳。這個操作可以用來控制LED的亮度,或者控制電機的轉速。Arduino每一次對引腳執行AnalogWrite命令,都會給該引腳一個固定頻率的PWM信號。
AnalogWrite()函數支持以下引腳:3,5,6,9,10,11。
在調用AnalogWrite函數前,您無需使用pinMode()函數來設置該引腳。
2.語法:analogWrite(pin,value)
3.參數:
pin:被讀取的模擬引腳號碼
value:0到255之間的PWM頻率值,0對應off,255對應on
4.返回值:無
程序分析
程序中通過analogRead()函數來讀取模擬輸入值,這個輸入值的范圍是0到1023之間,然后通過analogWrite()函數來改變LED燈占空比,范圍是0到255之間,從而改變亮度。
*占空比
所謂占空比就是調整led通過電流和不通過電流的時間比來控制的,由于人眼有視覺暫留特性,所以只要頻率比較高是看不出來閃爍的,當然通過電流比不通過電流的時間比例越大,led做的功就越多,這樣也就越亮,需要注意的是led芯片的溫升和最大電流值不要超標,不然會影響其壽命。
低占空比意味著輸出的能量低,因為在一個周期內大部分時間信號處于關閉狀態,如果pwm控制的負載為led,則具體表現例如led燈很暗。
高占空比意味著輸出的能量高,在一個周期內,大部分時間信號處于on狀態,具體表現為Led比較亮。
當占空比為100%時,表示 fully on,也就是在一個周期內,信號都處于on狀態,具體表現為led亮度到達100%。
為0%時則表示 totally off,在一個周期內,一直處于off狀態,具體表現為led熄滅。
現在一切都已明了:脈沖寬度調制,這個寬,不是物體的寬度,而是高電平信號在一個調制周期中持續時間長短,它可以用占空比去衡量,占空比越大,脈沖寬度越寬。
(三)使用純軟件編程和電位器實現調光LED(不使用analogwrite函數,引腳更通用)
基本原理
通過調整PWM的占空比,來調節通過LED燈的電流時間長度,改變LED燈的做功大小,從而實現調光LED燈的亮度。
在此代碼中,手動設置一個PWM信號,其信號中高低電壓的時間長短是根據輸入端口的值 val 來改變的。val的值是運用analogRead()函數讀取的模擬輸入端口的值,范圍為0~1023,當我們調節電位器時,val就會發生改變,這時LED燈的亮度就會隨val的值變化。
電路連接
電路圖與3.2相同,只將輸出端口改為13號。由于我們使用的是13號引腳,在arduino開發板上直接連接者一個LED燈,所以我們可以單獨使用一個LED燈,也可以直接用開發板上的。具體如圖所示:
使用單獨的LED燈:
不使用單獨的LED燈:
Fritzing繪制連接圖:
編寫代碼
int ledpin = 13; //定義端口13
int potpin=0; //定義端口0
int val=0; //定義變量val,初始值為0
void setup() {
pinMode(ledpin, OUTPUT); //定義端口13為輸出
Serial.begin(9600); //設置波特率為9600
}
void loop(){
val=analogRead(potpin); //讀取傳感器的模擬值并賦值給val
Serial.println(val); //顯示變量val的值
digitalWrite(ledpin, HIGH); //設置輸出端口輸入高電壓
delayMicroseconds(val); //延遲val長度的時間
digitalWrite(ledpin, LOW); //設置輸出端口為低電壓
delayMicroseconds(1000 - val); //延遲1000-val長度的時間
}
所用函數
analogRead () 函數
1.說明:從指定的模擬引腳讀取值。
2.語法:?analogRead(pin)
3.參數:
pin:要讀取的模擬輸入引腳的名稱(大多數板上的A0到A5,
Mini和Nano上的A0到A7)。
4.返回值:? 引腳上的模擬讀數(int)。
digitalWrite () 函數
1.說明:將數字HIGH或LOW值寫入數字引腳。
2.句法:
digitalWrite(pin, value)
3.參數:
pin:引腳號
value:HIGH或LOW
4.返回值:無
delayMicroseconds () 函數
1.說明:暫停程序指定為參數的時間量(以微秒為單位)。
2句法:
delayMicroseconds(us)
3.參數:
us:暫停的微秒數(unsigned int)
4.返回值:無
(四)比較兩種方式的區別與聯系
(五)實踐過程中遇到的問題
1. 找不到哪個是電位器?
由于剛剛接觸arduino,所以很多小零件都沒見過,就只認識個LED燈和Nano開發板,而且很多部件都標著英文,也看不懂。所以對于這個陌生的名詞,只好猜吧,看看憑感覺哪個像,亦或者問問老師。
但是這種方法是行不通的,既耗時又耗力,還不利于個人自主學習與探究。經過反思,后來我們的解決辦法是:先到網上搜集有關電位器的信息,從百度百科上看到電位器的圖片和基本介紹,對照著信息,我們終于在一堆亂七八糟的零件中找到了它!
2. 不知道純軟件編程的含義是啥?
聽起來覺得可能很高大上,讓人難懂,但是說得通俗點就是不使用analogwrite函數,而是使用更通用的方式(digitalwrite與delay函數結合),使得引腳更通用更靈活的一種方法。通過手動控制占空比,利用電位器可以使LED燈實現調光。
經過在網上搜集資料并研究,我們終于還是實現了手動調光,并且比較了二者的區別與聯系。
3.編譯時出現錯誤
在進行純軟件編程的時候,在代碼編譯時出現了錯誤,提示缺少定義輸出端口的代碼:
我們翻譯了一下錯誤消息,然后找到紅色提示的一行,發現缺少定義的變量,往上找代碼,原因是在復制代碼的時候漏了一行,導致在編譯時找不到ledpin這個變量。所以在以后一定要注意仔細檢查代碼是否完整,學會看各種提示錯誤,不斷積累經驗。
4.恍然大悟——手動調光原來還可以這樣
在使用純軟件編程的時候,我們只是單純地將引腳由10號改成13號,然后旋轉電位器調光。但是細心的小園同學發現arduino開發板上的另一個紅燈亮了,之前是不亮的。所以我們恍然大悟,原來13號引腳就直接連著一個LED燈,我們可以不用再外接一個LED燈了(但是電阻還是要接的)。不過有追求完美可觀的同學可以外接一個,更容易觀察。
5.還有一個未解之疑:手動調光LED燈為什么不能完全熄滅?
我們在進行純軟件編程的時候,發現無論如何旋轉電位器,都不能使LED燈完全熄滅,總是會帶有一點紅光:
截至目前為止,我們已經使用了很多方法,比如修改代碼(delay函數的參數)、檢查電路、更換電阻等等。但是由于知識有限,還不能解決這一問題,哪位大佬可以幫忙解答一下啊~
(六)總結與體會
經過本次有關Arduino項目的實踐,我們對Arduino開發板、各種元件以及函數的使用又有了更深刻的認識,使得知識不僅僅停留在書面上,更多是表現在外面的技能以及思維的活躍方面。
主要包括:1.Arduino軟件安裝以及與電腦連通方式;2.程序編譯、上傳等基本方式;3.面包板的使用方式,Fritzing的使用;4.學會了控制LED的亮滅;5.區分數字端口中的模擬端口并學會使用;6.完成電位器調光LED燈等等。在后續的學習中也在不斷積累有關Arduino更深入的知識,不斷提高能力。
通過小組的合作學習,使得我們在學習上總會產生思維的碰撞,大家相互爭論,相互幫助,共同完成項目。盡管在完成的過程中遇到了各種問題,當時確實是很頭疼,但是通過各種途徑解決之后,再回過頭來看就發現每個人真的成長了很多。
只有想不到的,沒有做不到的。創意的思維總是千奇百怪,各有不同,因此也就顯得特別珍貴,所以對于每個人的創新思維,都值得我們去保護。未來的人工智能領域是如此,教育亦是如此,創新和實踐總是貫穿其中,總讓人不由自主的接近和了解它。
現在,讓我們積極思維與實踐,一起打開Arduino世界的大門!