從零開始學Arduino編程

2021-01-10 智東西

關於Arduino的歷史、定位、功能等等的介紹,維基百科已有很詳細的闡述,建議初學者都去看看,能對Arduino有更深入了解。本文基於Getting Started With Arduino(建議初學者購買),重點連載從零開始學習Arduino的基礎編程知識和詳細程序實現,只針對剛拿到Arduino但基本無編程經驗的同學,高手請繞行。

NO.1:點亮你的第一個LED燈

打開Arduino IDE,新建Sketch,參考以下代碼,重點請看注釋部分:

#define LED 13 //定義D13為LED正極口,將LED燈連接到板子上D12引腳void setup() //此函數代碼只會在程序剛開始時執行一次{  pinMode(LED, OUTPUT); //定義LED也就是D13引腳模式為輸出}void loop() //此程序在會Arduino通電後反覆執行{  digitalWrite(LED, HIGH); //輸出13引腳信號為HIGH即高電平,開  delay(1000); //持續1S  digitalWrite(LED, LOW); //輸出13引腳信號為LOW即低電平,關  delay(1000); //持續1S}

將此代碼上傳至Arduino並連接好LED燈,你就可以看到LED在閃爍。

NO.2 添加開關來控制LED(GND端串聯10K歐姆電阻,+5V)

#define LED 13 //定義LED引腳為D13#define BUTTON 7 //定義開關BUTTON引腳為D7int val = 0; //變量val,並賦值0,用來存儲按鈕狀態void setup(){  pinMode(LED, OUTPUT); //LED引腳設置為輸出模式  pinMode(BUTTON, INPUT); //BUTTON引腳設置為輸入模式}void loop(){  val = digitalRead(BUTTON); //讀取BUTTON數值  if (val == HIGH)//當val為HIGH的情況下  {    digitalWrite(LED,HIGH); //點亮LED  }else{    digitalWrite(LED, LOW); //關閉LED  }}

上傳看看效果。

NO.3:打開按鈕後LED常亮

#define LED 13 //定義LED引腳為D13#define BUTTON 7 //定義開關BUTTON引腳為D7int val = 0; //變量val,並賦值0,用來存儲按鈕狀態int state = 0; //變量state,定義0表示關閉,1表示打開void setup(){  pinMode(LED, OUTPUT); //LED引腳設置為輸出模式  pinMode(BUTTON, INPUT); //BUTTON引腳設置為輸入模式}void loop(){  val = digitalRead(BUTTON); //讀取BUTTON數值  if (val == HIGH) //當val為HIGH的情況下  {    state = 1 - state;  }  if(state == 1)  {    digitalWrite(LED, HIGH); //打開LED  }else{    digitalWrite(LED, LOW); //LED關閉狀態  }}

上傳看效果,你會發現會出現當你按開關LED燈關閉的問題,原因是程序中使用變量state儲存0或者1來記憶燈的狀態,當按下按鈕時,state已被賦值為1,所以當Arduino再去讀取開關狀態時,當開關狀態為HIGH,此時state被再次賦值為0,為關閉狀態。

這其實是程序設計缺陷,如果來解決?繼續往下:

#define LED 13 //定義LED引腳為D13#define BUTTON 7 //定義開關BUTTON引腳為D7int val = 0; //變量val,並賦值0,用來存儲按鈕狀態int old_val = 0; //存儲變量val的上一個值int state = 0; //變量state,定義0表示關閉,1表示打開void setup(){  pinMode(LED, OUTPUT); //LED引腳設置為輸出模式  pinMode(BUTTON, INPUT); //BUTTON引腳設置為輸入模式}void loop(){  val = digitalRead(BUTTON); //讀取BUTTON數值  if ((val == HIGH) &&(old_val == LOW)) //當val為HIGH並且old_val為LOW的情況下  {    state = 1 - state;  }  old_val = val; //val此時已經是舊的了,讓數值賦給old_var  if(state == 1)  {  digitalWrite(LED, HIGH); //打開LED  }else{  digitalWrite(LED, LOW); //LED關閉狀態  }}

寫到此時,我已完全被LED燈閃瞎了眼。程序依然沒有正常工作!現在的問題是由於按鈕的機械構造造成的,按鈕由兩片金屬的接觸實現電路的導通,在現實中,金屬之間的接觸並不是完全密合,尤其是金屬尚未到底的瞬間和按鈕彈回的時候,會產生雜波。

當雜波出現的時候,Arduino會接受到一連串開關交錯的信號。要克服這個雜波,有幾種不通方式,對上邊的簡單程序來講,只需要在程序中加入10~50毫秒的延遲指令就可以改善。參考以下代碼:

#define LED 13 //定義LED引腳為D13#define BUTTON 7 //定義開關BUTTON引腳為D7int val = 0; //變量val,並賦值0,用來存儲按鈕狀態int old_val = 0; //存儲變量val的上一個值int state = 0; //變量state,定義0表示關閉,1表示打開void setup(){  pinMode(LED, OUTPUT); //LED引腳設置為輸出模式  pinMode(BUTTON, INPUT); //BUTTON引腳設置為輸入模式}void loop(){  val = digitalRead(BUTTON); //讀取BUTTON數值  if ((val == HIGH) &&(old_val == LOW)) //當val為HIGH並且old_val為LOW的情況下  {    state = 1 - state;    delay(50);  }  old_val = val; //val此時已經是舊的了,讓數值賦給old_var  if(state == 1)  {    digitalWrite(LED, HIGH); //打開LED  }else{    digitalWrite(LED, LOW); //LED關閉狀態  }}

NO.4:使用PWM的方式來控制LED燈亮度

PWM被成為脈衝寬度調製,如果我們改變延遲函數的數值,直到你看不出LED燈亮和滅的時間間隔為止,你會發現LED燈亮度只有原來的50%,如果繼續改變時間間隔,你會發現燈的亮度只有原來的25%。這就是PWM。

Arduino電路板上使用的處理器可以在處理其他事情的同時點亮3各LED使其閃爍,這部分PWM輸出接口為D9、D10、D11,這3個輸出接口可以由analogWrite()函數控制。analogwrite()指令中PWM參數的可設範圍為0~255,255代表最亮,0代表最暗,如果你使用analogwrite(9, 128)則代表D9引腳接的LED燈亮度為50%。

逐漸改變亮度的LED燈(使用LED等串聯一個470~1K歐姆的電阻,並接到D9引腳,負極接GND):

#define LED 9 //定義LED為D9引腳int i = 0; //定義變量i,用來從上到下計數void setup(){  pinMode(LED,OUTPUT); //LED為輸出}void loop(){  for(i = 0; i < 255 ; i++){ //循環255次,從小到大    analogWrite(LED, i); //PWM參數,亮度從小到大    delay(10); //延遲10毫秒,因為anaWrite()參數執行瞬間完成  }  for(i = 255; i > 0; i--){ //循環255次,從大到小    analogWrite(LED, i); //PWM參數,兩大從大到小    delay(10); //延遲10毫秒  }}

上傳看看,是不是很神奇?

NO.5:按下松下按鈕開關LED,長按開關調節LED燈亮度(NO.2+NO.4兩個小電路積木結合)

#define LED 9 // 定義LED為D9引腳#define BUTTON 7 //定義按鈕為D7引腳int val = 0; //變量val存儲按鈕數值狀態int old_val = 0; //存儲val的上一個數值int state = 0; //0為關閉LED,1為打開LEDint brightness = 128; //存儲亮度值unsigned long startTime = 0; //存儲按下按鈕的開始時間void setup() {  pinMode(LED, OUTPUT); //LED引腳為輸出  pinMode(BUTTON, INPUT); //BUTTON引腳為輸入}void loop() {  val = digitalRead(BUTTON); //讀取按鈕數值並存儲到val變量  if ((val == HIGH) && (old_val == LOW)) {    state = 1 - state;    startTime = millis(); // millis()是Arduino的時鐘,存儲最後一次按下按鈕的時間,單位毫秒    delay(10);  }  if ((val == HIGH) && (old_val == HIGH)) {    if (state == 1 && (millis() - startTime) > 500) { //如果按鈕被按了超過500毫秒      brightness++; // 亮度值遞增      delay(10);    if (brightness > 255) { //如果亮度值超出255      brightness = 0; //重置亮度為0      }    }  }old_val = val; //執行了一次之後,val已變成舊值,存儲到old_valif (state == 1) {  analogWrite(LED, brightness); //以當前亮度值打開LED  }else{  analogWrite(LED, 0); //關閉LED  }}

是不是很酷?當然,你可以嘗試把開關換成其他敏感元件,如光敏電阻、熱敏電阻等其他傳感器,來製作更有趣的場景。

以上我們進行的都是基於數字I/O引腳的試驗,接下來開始嘗試模擬I/O引腳(模擬引腳默認為輸入狀態)。模擬輸入引腳analog in不僅可以讀出是否有電壓輸入(數字引腳只能讀出有或無),還能讀出電壓值的大小。我們使用analogRead()函數來讀取輸入電壓值,該參數的返回值範圍為0~1023,分別對應0~5V間的電壓。如,在模擬口輸入2.5V電壓,analogRead()返回的值為512。以下開始模擬口的嘗試:

NO.6:根據模擬輸入值大小來設定LED閃爍頻率

硬體環境需要先使用光敏電阻串聯10K歐姆電阻,串聯電阻一端接GND,一端接5V引腳,同時,在10K歐姆電阻的並聯方向引出A0引腳接口。LED燈正極接D13,負極串聯1K歐姆電阻接GND。

#define LED 13 //定義D13引腳為LEDint val = 0; //變量val,存儲模擬口讀取的數值void setup(){  pinMode(LED,OUTPUT); //LED為輸出}void loop(){  val = analogRead(0); //讀取A0並賦值給val  digitalWrite(LED,HIGH); //點亮LED  delay(val); //延遲時間為val的數值  digitalWrite(LED,LOW); //關閉LED  delay(val); //延遲時間為val的數值}

一閃一閃亮晶晶!

NO.7:根據模擬輸入值來調整LED燈亮度

#define LED 9 //定義D9引腳為LED,D9為PWM引腳int val = 0; //變量val,存儲模擬口讀取的數值void setup(){  pinMode(LED,OUTPUT); //LED為輸出}void loop(){  val = analogRead(0); //讀取A0並賦值給val  analogWrite(LED, val/4); //PWM輸出最大值為255  delay(10); //延遲10毫秒}

有了上邊的編程基礎,你可以變換出任意的積木式組合、擴展性場景。

接下來看下Arduino的串口通信,通過串口通信,我們可以讓Arduino和計算機或其他控制機之間互相通信,讓Arduino把數據傳回計算機,並能接收來自計算機的指令。要實現這一功能,可以在Arduino程序中通過Serail()函數,此函數包含了串口通信所需的所有程序代碼。

NO.8:從計算機串口讀取Arduino模擬傳感器輸入數據

硬體環境依照NO.7的光敏電阻電路,程序如下:

#define SERSOR 0 //定義傳感器輸入口為A0int val = 0; //變量val來存儲讀取的數值void setup(){  Serial.begin(9600); //打開串口並設置通信波特率為9600}void loop(){  val = analogRead(0); //從A0讀取傳感器反饋值並賦值給val  Serial.println(val); //串口監視窗口顯示傳感器的反饋值  delay(100); //每100毫秒發送一次數據}

上傳至Arduino,在Arduino工具菜單的串口監視窗口打開看看,你所看到的值可以通過0~5V換算成電壓,根據各傳感器的Datasheet,可以得出你想要的現實環境中的某項數值。

相關焦點

  • 從零開始怎麼學計算機編程?
    於是很多人想投身其中,而且很大一部分都是零基礎非科班的狀態。在學習者中有大學生,也初高中生,他們都有一個共性,沒什麼基礎。從零基礎開始學習編程成為了一種常態,可是,也正是因為我們在編程方面是零基礎,很容易導致我們選錯專業和行業。從零開始學習電腦如何才能保證學好呢?以下為大家做一個簡單的總結,希望我們能在學習時有所參考。
  • arduino從零開始(4)PWM與呼吸燈
    你將學到什麼?
  • 萬能超的arduino學習日記(一)
    本科時候有接觸過arduino,但是由於導師方向原因,轉做了3D列印和動力學分析,所以這裡是啥都會一點點的萬能超,希望能夠和大家一起學習討論。最近由於興趣原因,決定重新撿起arduino,所以決定寫這個萬能超的arduino學習日記跟大家一起重新學習。最開始的入門學習,我選擇跟B站太極創客的學習視頻,因為有基礎,選擇二倍速觀看學習。
  • 學編程不止是為做程式設計師,編程貓小火箭學員家長:學編程,是培養思維...
    學編程不止是為做程式設計師,編程貓小火箭學員家長:學編程,是培養思維的好方式 2020年03月25日 10:26作者:網絡編輯:王動   國家之爭的內核是經濟之爭
  • [新課推薦]人工智慧科普活動資源包配套課程Micro:bit+ Arduino...
    人工智慧科普活動資源包配套課程-Micro:bit 課程《人工智慧科普活動資源包配套課程-Micro:bit 課程》一共分為兩個章節20個小節,每個小節5-10分鐘,課程內容包括外部結構搭建和編程演示。
  • Arduino使用光敏電阻實驗
    板子上的微控制器可以通過Arduino的程式語言來編寫程序,編譯成二進位文件,燒錄進微控制器。對Arduino的編程是通過 Arduino程式語言 (基於 Wiring)和Arduino開發環境(基於 Processing)來實現的。
  • Github霸榜:從零開始學3D著色器編程
    著色器編程不光是對開發技能的考驗,更是對程式設計師想像力的挑戰,以至於有說法稱會寫Shader的程式設計師是站在食物鏈頂端的人。想成為遊戲開發高手,著色器編程是必備技能。有興趣在3D遊戲中添加紋理,光照,陰影,法線貼圖,環境光遮蔽了嗎?好極了!今天新智元為大家帶來一個Github項目,從零開始教會大家進行3D遊戲著色。
  • 從零開始學電路基礎- -從零開始學電路基礎,初學者們看這裡~~~
    導讀:從零開始學電路基礎,這篇文章志在讓親們快速掌握電路基礎知識,為以後學習更深入的知識打下基礎,從零開始學電路基礎是專門針對初學者的,大神們請自覺飄過~~~本文引用地址:http://www.eepw.com.cn/article/268472.htm  電路的概念
  • 從零開始學習ST/SCL程式語言
    首先看下什麼是SCL語言:SCL語言是一種結構化文本,類似於計算機高級語言的編程方式,他的語言規範解決計算機的PASCAL語言。S7-SCL(Structured Control Language 結構化控制語言) 具有以下特點:· 1、是一種類似於PASCAL的高級程式語言· 2、符合國際標準IEC 61131-3· 3、PLCopen基礎級認證· 4、適用於 S7-300 (推薦CPU314以上), S7-400,S7-1200,S7-1500, C7
  • 十個中文例程教會你輕鬆上手製作Arduino智能小車
    Arduino簡介本文引用地址:http://www.eepw.com.cn/article/201706/348117.htmArduino 是一款便捷靈活、方便上手的開源電子原型平臺,包含硬體(各種型號的arduino板)和軟體(arduino IDE)。
  • 如何系統地從零開始學習PLC?
    PLC在現在的人懂的人看來,的確是比較簡單的東西,畢竟它屬於應用類型的二次編程開發。但是作為一個零基礎初學者,要學PLC,還是要付出一定的時間來摸索的。先要明白PLC本質是繼電器電路的軟體化,也就是在電腦上畫畫繼電器電路圖,這個是它的根本,所以在學習PLC之前,你一定要有點電工基礎,理解和實操過繼電器電路的使用,這個是非常重要的,畢竟PLC軟體的東西都是在模擬硬體電路,請關注:容濟點火器作為一個過來人,我當年也是從零開始學PLC的中國的大學教育,因為很多原因,往往比較重視理論教育,而在學校裡邊的動手機會是沒有那麼多的,特別是
  • 如何使用Qt為arduino製作圖形界面
    如何使用Qt為arduino製作圖形界面 網絡整理 發表於 2019-11-13 11:11:39 步驟1:安裝Qt
  • 信息學奧賽太原市集訓隊零基礎選拔活動通知
    【信息學奧賽暑期一個月衝獎】 關於信息學奧賽太原市集訓隊、 預備隊隊員零基礎選拔活動的通知楊老師有豐富的信息學奧賽選材和培訓經驗,在短短的三個月中就讓零基礎的學員拿到一等獎。在青少年編程普及的工作中,採用國際信息學奧賽金牌教學體系,讓零奧數、零編程基礎的孩子,在短時間內掌握C++語言,算法,數據結構知識和思維結構,衝擊信息學奧賽小學普及組、初高中提高組獎牌。
  • 不用從零學android入門編程,這款傻瓜式開發工具,快速製作App
    現在,不需要從零開始學android編程技術,任何人都可以輕鬆製作手機APP。國外的網際網路巨頭:比如谷歌的輕代碼 H5 應用開發工具——App Maker,微軟的PowerApps,就是通過拖拽式的進行應用開發。
  • LabVIEW+Arduino之四位數碼管顯示
    charScan[] = {0x08, 0x04, 0x02, 0x01}; //位選所對應的掃描碼,對應從pin11掃描到pin8;voidsetup() {DDRB =0xff; // 設置 PORTB為輸出,對應arduino
  • 開課吧:學習編程,該學什麼語言?Python如何?
    編程編程如果是興趣方面的可以選擇比較簡單的入門語言入手,然後再慢慢切入到新的程式語言,目前相對來說比較好入門的程式語言是python,這門語言的集成度非常高,適合零基礎的入門學習,集成度高的語言在短時間能看到很不錯的效果,能在短時間內讓自己有成就感,但真要深入的學習還得腳踏實地的學習內在的東西。
  • 為什麼要學計算機編程?
    因為「編程是件很有趣的事兒」酷叮貓老師覺得,編程並不是一個學習的科目,而是一個興趣的萌芽。編程會為大家帶來很多:編程能夠訓練思維。編程體現了一種抽象交互關係、 形式化方法執行的思維模式,稱為「計算思維」。
  • 孩子要不要學編程 幾歲學編程比較好?詳述三大編程課試課經歷
    編程是下一個十年的英語,世界各國已將編程教育作為基礎學科……,讓家長覺得不送孩子學編程,孩子的未來就會跟世界脫軌一樣,不由自主的就會焦慮,一焦慮就會急著給孩子試課挑課上課。當然,也會有理性的家長問,孩子一定要學編程嗎?孩子要不要學編程,學編程有什麼價值?孩子要不要學編程?
  • 數碼管與ARDUINO 開發板的連接使用
    數碼管模塊與arduino連接示意圖接線說明:數碼管的VCC –arduino上的5V數碼管的GND -- arduino上的GND數碼管的DS -- arduino上的A0數碼管的ST_CP -- arduino上的A1數碼管的SH_CP -- arduino上的A2
  • 【由零開始學路亞】路亞釣法的對象魚種
    【由零開始學路亞】路亞釣法的對象魚種