項目結構
(1)setup():
Arduino控制器通電或復位后,即會開始執行setup() 函數中的程序,該部分只會執行一次。
通常我們會在setup() 函數中完成Arduino的初始化設置,如配置I/O口狀態,初始化串口等操作。
(2)loop():
在setup() 函數中的程序執行完后,Arduino會接着執行loop() 函數中的程序。而loop()函數是一個死循環,其中的程序會不斷的重復運行。通常我們會在loop() 函數中完成程序的主要功能,如驅動各種模塊,采集數據等。
輸入和輸出
(1)數字信號與模擬信號的區別

(2) 區分電路板子中的“數字”與“模擬”接口
板子上會印有“D”或者“A”的字樣:
“D”代表“數字”
“A”代表“模擬”
數字口輸入輸出函數
(1)pinMode(pin, mode):
Arduino控制器在使用輸入或輸出功能前,你需要先通過pinMode() 函數配置引腳的模式為輸入模式或輸出模式。
函數參數
參數pin為指定配置的引腳編號:0~13
參數mode為指定的配置模式:
INPUT 輸入模式
OUTPUT 輸出模式
INPUT_PULLUP 輸入上拉模式
(2) digitalWrite(pin, value):
Arduino控制器使用到了pinMode(),引腳配置為輸出模式。
配置成輸出模式后,還需要使用digitalWrite() 讓其輸出高電平或者是低電平
函數參數
參數pin為指定輸出的引腳編號(0~13);
參數value為你要指定輸出的電平
使用HIGH指定輸出高電平,或是使用LOW指定輸出低電平
(3)digitalRead(pin):
Arduino控制器使用到了pinMode(),引腳配置為輸入模式。
配置成輸入模式后,還需要使用digitalRead() 讀取端口狀態
函數參數
參數pin為指定輸出的引腳編號;
參數返回值為獲取到的信號狀態,1為高電平,0為低電平
延時函數
(1) delay( ms):
Arduino提供了毫秒級和微秒級兩種延時函數。運行延時函數時,會等待指定的時間,再運行此后的程序。你可以通過參數設定延時時間。
此函數為毫秒級延時。
參數為時長,類型unsigned long。
(2) delayMicroseconds( us ):
此函數為毫秒級延時。
參數為時長,類型unsigned long。
注: Arduino Uno上的延時操作精度為+-0.5 微秒
數字口輸出案例
/*
**功能:I3和I2口閃爍
*/
//兩者定義方式選一
//int led1 = 3; //全局變量定義,存儲於RAM
//int led2 = 2; //全局變量定義,存儲於RAM
#define led1 3 //宏定義,預處理,存儲於FLASH
#define led2 2 //宏定義,預處理,存儲於FLASH
void setup() {
pinMode(led1, OUTPUT); //設定數字端口模式為輸出
pinMode(led2, OUTPUT); //設定數字端口模式為輸出
}
void loop(){
digitalWrite(led1, HIGH); // 點亮LED
digitalWrite(led2, LOW); // 點亮LED
delay(1000); // 等待一秒鍾
digitalWrite(led1, LOW); // 通過將引腳電平拉低,關閉LED
digitalWrite(led2, HIGH); // 點亮LED
delay(1000); // 等待一秒鍾
}
數字口輸入案例
/*
**功能:I4口輸入,確定I3口輸出燈
*/
#define Key1 4 //宏定義,預處理,存儲於FLASH
#define led1 3 //宏定義,預處理,存儲於FLASH
int val; //定義變量val
void setup(){
pinMode(led1,OUTPUT); //定義小燈接口為輸出接口
pinMode(Key1,INPUT); //定義按鍵接口為輸入接口
}
void loop(){
val=digitalRead(Key1); //讀取數字4口電平值賦給val
if(val==LOW){ //檢測按鍵是否按下,按鍵按下時小燈亮起
digitalWrite(led1,LOW);
}
else{
digitalWrite(led1,HIGH);
}
}
串口輸出”Hello world ”案例的函數
(1)Serial.begin(speed):
參數speed是指串口通信波特率:300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600、115200
(2)Serial.begin(speed,config):
初始化串口,可配置串口的各項參數。
參數speed是指串口通信波特率。
參數config是指串口通訊的數據位、校驗位、停止位配置。
(3)Serial.available():
函數功能:獲取串口接收到的數據個數,即獲取串口接收緩沖區中的字節數。接受緩沖區最多可保存64 bytes的數據。
函數返回值:可讀取的數據字節數。
配置成輸入模式后,還需要使用digitalRead() 讀取端口狀態
函數功能:判斷緩沖器狀態,如果對法發送來數據過來,這個狀態會變成 1,如果沒有收到數據,就是 0。當數據被讀取完,也會重新變成 0
(4)Serial.read() :
函數功能:調用該語句,每次都會返回一個字節的數據,這個返回值便是當前串口讀取到的數據獲取。
(5)Serial.print(val) :
函數功能:將數據輸出到串口,數據會以ASCII形式輸出。如果要以字節形式輸出數據,你需要使用write() 函數。
函數參數val: 需要輸出的數據,各種類型數據均可。
函數返回值:輸出的字節數。
(6)Serial.println(val) :
與Serial.print相比就是,將數據輸出到串口后,回車換行。
串口輸出”Hello word ”案例的代碼
int val; //定義變量val
int ledpin=2; //定義數字接口2
void setup(){
Serial.begin(9600); //設置波特率為9600,這里要跟軟件設置相一致。
pinMode(ledpin,OUTPUT); //設置數字2 口為輸出接。
}
void loop(){
val=Serial.read(); //讀取PC 機發送給Arduino 的指令或字符,並將該指令或字符賦給val
if (val=='R'){ //判斷接收到的指令或字符是否是“R”。
//如果接收到的是“R”字符
digitalWrite(ledpin,HIGH); //點亮數字13 口LED。
delay(500);
digitalWrite(ledpin,LOW); //熄滅數字13 口LED
delay(500);
Serial.println("Hello World!"); //顯示“Hello World!”字符串
}
}
模擬口輸入函數
analogRead(pin):
參數pin為指定模擬值輸入的引腳編號:A0~A5
參數返回值:
Arduino Uno模擬輸入功能有10位精度,即可以將0~5V的電壓信號轉換為0~1023的整數形式表示。
注意:
analogRead() 函數內部,已經完成了引腳的初始化。
模擬量輸入案例的代碼
int potpin=0; //定義模擬接口0
int ledpin=13; //定義數字接口13
int val=0; //將定義變量val,並賦初值0
void setup(){
pinMode(ledpin,OUTPUT); //定義數字接口為輸出接口
Serial.begin(9600); //設置波特率為9600
}
void loop(){
digitalWrite(ledpin,HIGH); //點亮數字接口13 的LED
delay(50); //延時0.05 秒
digitalWrite(ledpin,LOW); //熄滅數字接口13 的LED
delay(50); //延時0.05 秒
val=analogRead(potpin); //讀取模擬接口0的值,並將其賦給val
Serial.println(val); //顯示出val的值
}
PWM的介紹
PWM為脈沖寬度調制,簡稱脈寬調制。脈沖寬度調制(PWM)是一種對模擬信號電平進行數字編碼的方法,由於計算機不能輸出模擬電壓,只能輸出0或5V的數字電壓值,我們就通過使用高分辨率計數器,利用方波的占空比被調制的方法來對一個具體模擬信號的電平進行編碼。PWM 信號仍然是數字的,因為在給定的任何時刻,滿幅值的直流供電要么是5V(ON),要么是0V(OFF)。
電壓或電流源是以一種通(ON)或斷(OFF)的重復脈沖序列被加到模擬負載上去的。通的時候即是直流供電被加到負載上的時候,斷的時候即是供電被斷開的時候。只要帶寬足夠,任何模擬值都可以使用PWM 進行編碼。輸出的電壓值是通過通和斷的時間進行計算的。
輸出電壓=(接通時間/脈沖時間)*最大電壓值

PWM被用在許多地方,調光燈具、電機調速、聲音的制作等等。
下面介紹一下PWM的三個基本參數:脈沖寬度、脈沖周期(1秒內脈沖頻率個數的倒數)、電壓高度(例如:0V-5V)

PWM輸出函數
analogWrite(pin,value):
參數pin為指定模擬值輸入的引腳編號:3、5、6、9、10、11
參數value指定是PWM的脈沖寬度,范圍為0~255。
注意:
analogWrite() 函數內部,已經完成了引腳的初始化。
PWM調控燈光案例源代碼
int potpin=0; //定義模擬接口0
int ledpin=3; //定義數字接口3(PWM 輸出)
int val=0; // 暫存來自傳感器的變量數值
void setup(){
pinMode(ledpin,OUTPUT); //定義數字接口3 為輸出
Serial.begin(9600); //設置波特率為9600
}
void loop(){
val=analogRead(potpin); // 讀取傳感器的模擬值並賦值給val
Serial.println(val); // 顯示val 變量
analogWrite(ledpin,val/4); // 打開LED 並設置亮度(PWM 輸出最大值255)
delay(10); //延時10ms
}
舵機的介紹
舵機是一種位置伺服的驅動器,主要是由外殼、電路板、無核心馬達、齒輪與位置檢測器所構成。其工作原理是由接收機或者單片機發出信號給舵機,其內部有一個基准電路,產生周期為20ms,寬度為1.5ms的基准信號,將獲得的直流偏置電壓與電位器的電壓比較,獲得電壓差輸出。經由電路板上的IC判斷轉動方向,再驅動無核心馬達開始轉動,透過減速齒輪將動力傳至擺臂,同時由位置檢測器送回信號,判斷是否已經到達定位。適用於那些需要角度不斷變化並可以保持的控制系統。當電機轉速一定時,通過級聯減速齒輪帶動電位器旋轉,使得電壓差為0,電機停止轉動。一般舵機旋轉的角度范圍是0度到180度。
舵機有很多規格,但所有的舵機都有外接三根線,分別用棕、紅、橙三種顏色進行區分,由於舵機品牌不同,顏色也會有所差異,棕色為接地線,紅色為電源正極線,橙色為信號線。

舵機的控制
舵機的轉動的角度是通過調節PWM(脈沖寬度調制)信號的占空比來實現的,標准PWM(脈沖寬度調制)信號的周期固定為20ms(50Hz),理論上脈寬分布應在1ms到2ms 之間,但是,事實上脈寬可由0.5ms 到2.5ms 之間,脈寬和舵機的轉角0°~180°相對應。有一點值得注意的地方,由於舵機牌子不同,對於同一信號,不同牌子的舵機旋轉的角度也會有所不同。

用Arduino 控制舵機的方法有兩種:
第一種是通過Arduino 的普通數字傳感器接口產生占空比不同的方波,模擬產生PWM 信號進行舵機定位。
第二種是直接利用Arduino自帶的Servo函數進行舵機的控制,這種控制方法的優點在於程序編寫,缺點是只能控制2 路舵機,因為Arduino 自帶函數只能利用數字9、10 接口。
Arduino 的驅動能力有限,所以當需要控制1 個以上的舵機時需要外接電源。
第一種舵機控制的案例代碼
int servopin=9; //設置舵機驅動腳到數字口9
int myangle; //定義角度變量
int pulsewidth; //定義脈寬變量
int val;
void servopulse(int servopin,int myangle){ //構建函數
pulsewidth=(myangle*11)+500; //將角度轉化為500-2480 的脈寬值
digitalWrite(servopin,HIGH); //將舵機接口電平置高
delayMicroseconds(pulsewidth); //延時脈寬值的微秒數
digitalWrite(servopin,LOW); //將舵機接口電平置低
delay(20-pulsewidth/1000); //延時周期內剩余時間
}
void setup(){
pinMode(servopin,OUTPUT); //設定舵機接口為輸出接口
Serial.begin(9600); //設置波特率為9600
Serial.println("servo=o_seral_simple ready" ) ;
}
void loop(){ //將0到9的數轉化為0到180角度,並讓
val=Serial.read(); //讀取串口收到的數據
if(val>'0'&&val<='9'){ //判斷收到數據值是否符合范圍
val=val-'0'; //將ASCII碼轉換成數值,例'9'-'0'=0x39-0x30=9
val=val*(180/9); //將數字轉化為角度,例9*(180/9)=180
Serial.print("moving servo to ");
Serial.print(val,DEC);
Serial.println();
for(int i=0;i<=50;i++){ //給予舵機足夠的時間讓它轉到指定角度
servopulse(servopin,val); //引用脈沖函數
}
}
}
Servo庫函數
(1)attach(pin):
參數pin為指定模擬值輸入的引腳編號:9和10
作用:將Servo變量附加到引腳, Servo庫僅支持將舵機連接至第9和第10腳上。
函數形式:
servo.attach(pin)
servo.attach(pin, min, max)
函數參數:
servo,一個類型為servo的變量
pin,連接至舵機的引腳編號
min(可選),舵機為最小角度(0度)時的脈沖寬度,單位為微秒,默認為544 max(可選),舵機為最大角度(180度時)的脈沖寬度,單位為微秒,默認為2400
(2)write(angle):
作用:向舵機寫入一個數值,來直接控制舵機的軸。在一個標准的舵機中,這將設定齒輪的角度,將齒輪轉到對應的位置。在一個連續旋轉的舵機中,這將設置一個舵機的角度(0作為全速向一邊,180為全速向另一邊,在90附近的值為停止)。
函數形式:
servo.write(angle)
函數參數:
servo,一個類型為servo的變量
angle,寫向舵機的角度,從0到180之間
(3)read():
作用:讀取舵機當前的角度(最后一次用write()函數寫入的值)。
函數形式:
servo.read()
函數參數:
servo,一個類型為servo的變量
返回值:舵機的角度,從0至180度
(4)writeMicroseconds():
作用:向舵機寫入一個微秒的值來控制舵機的軸。在一個標准舵機中,這將設置舵機齒輪的角度。在標准舵機中,參數設置為1000為完全逆時針方向,2000完全順時針方向,1500為在中間。
函數形式:
servo.writeMicroseconds(uS)
函數參數:
servo,一個類型為servo的變量
uS,一個代表微秒值的整數參數
注意:
一些生產廠商沒有按照這個標准,以至於,舵機通常響應在700到2300之間的值。自由地增加終點值直到舵機不再增加它的范圍。注意,讓舵機旋轉超過它的終點(通常會發出異常聲響)是一個高電流狀態,應該被避免。
連續旋轉舵機對該函數的響應類似於write()函數
(5)attached():
作用:檢查一個servo變量是否被附加到一個引腳。
函數形式:
servo.attached()
函數參數:
servo,一個類型為servo的變量
返回值:返回true,如果被附加到一個引腳,反之返回false
(6)detach():
作用:將servo變量與引腳脫離,如果所有servo變量均被脫離,第9和第10教將可以用analogWrite()函數進行PWM輸出。
函數形式:
servo.detach()
函數參數:
servo,一個類型為servo的變量
第二種舵機控制的案例代碼
#include <Servo.h>
Servo myservo; //先定義自己的舵機的名稱
void setup() {
myservo.attach(9); //舵機控制腳的定義
}
void loop() {
myservo.write(0); //舵機轉到0度位
delay(2000);
myservo.write(180); //舵機轉到180度位
delay(2000);
}
直流電機(行走電機)的介紹



直流電機控制的案例代碼(不用PWM)
#include <Servo.h>
int motor1_1 =10; //直流電機接口(IN1)
int motor1_2 =11; //直流電機接口(IN2)
void setup(){
pinMode(motor1_1 ,OUTPUT); // PIN 10
pinMode(motor1_2,OUTPUT); // PIN 11
}
void run(int time){ // 前進
digitalWrite(motor1_1 ,HIGH); // 右電機前進
digitalWrite(motor1_2,LOW);
//digitalWrite(motor1_1 , LOW); // 右電機后進
//digitalWrite(motor1_2, HIGH);
}
void loop(){
run(10);
}
直流電機控制的案例代碼(用PWM)
int motor1_1 =10; //直流電機接口(IN1)
int motor1_2 =11; //直流電機接口(IN2)
void setup(){
pinMode(motor1_1,OUTPUT); // PIN 10
pinMode(motor1_2,OUTPUT); // PIN 11
}
void run(int time){ // 前進
analogWrite(motor1_1 ,130); //PWM比例0~255調速,左右輪差異略增減
analogWrite(motor1_2,0);
}
void loop(){
run(10); //前進
}
