截圖:?

代碼:
unsigned long t[20]; // 定義一個數組t,用于存儲20個LED的上次狀態切換時間(單位:毫秒)void setup() {pinMode(13, OUTPUT); // 將引腳13設置為輸出模式(此行代碼在本實驗中未實際使用,可忽略)for(int ledid = 0; ledid < 20; ledid++) // 循環遍歷0到19的引腳,初始化每個LED的控制引腳{pinMode(ledid, OUTPUT); // 將當前引腳(ledid)設置為輸出模式t[ledid] = millis(); // 將當前時間(毫秒)記錄到數組t中,對應當前LED的上次切換時間}
}void ledblink(int ledid, int ledhz) // 定義函數ledblink,用于控制指定LED的閃爍
{if (millis() - t[ledid] >= ledhz) { // 如果當前時間與上次切換時間的差值大于等于閃爍周期(ledhz)digitalWrite(ledid, !digitalRead(ledid)); // 切換當前LED的狀態(亮變滅,滅變亮)t[ledid] = millis(); // 更新當前LED的上次切換時間為當前時間}
}void loop() {for(int ledid = 0; ledid < 20; ledid++) // 循環遍歷0到19的引腳,逐個控制LED{ledblink(ledid, random(ledid, 2000 * ledid)); // 調用ledblink函數,為當前LED生成一個隨機閃爍周期并控制其閃爍// random(ledid, 2000*ledid) 生成一個范圍在 [ledid, 2000*ledid) 的隨機整數作為閃爍周期}
}
以下是逐行添加中文注釋的代碼:
cpp復制代碼
unsigned long t[20]; // 定義一個數組t,用于存儲20個LED的上次狀態切換時間(單位:毫秒) | |
void setup() { | |
pinMode(13, OUTPUT); // 將引腳13設置為輸出模式(此行代碼在本實驗中未實際使用,可忽略) | |
for(int ledid = 0; ledid < 20; ledid++) // 循環遍歷0到19的引腳,初始化每個LED的控制引腳 | |
{ | |
pinMode(ledid, OUTPUT); // 將當前引腳(ledid)設置為輸出模式 | |
t[ledid] = millis(); // 將當前時間(毫秒)記錄到數組t中,對應當前LED的上次切換時間 | |
} | |
} | |
void ledblink(int ledid, int ledhz) // 定義函數ledblink,用于控制指定LED的閃爍 | |
{ | |
if (millis() - t[ledid] >= ledhz) { // 如果當前時間與上次切換時間的差值大于等于閃爍周期(ledhz) | |
digitalWrite(ledid, !digitalRead(ledid)); // 切換當前LED的狀態(亮變滅,滅變亮) | |
t[ledid] = millis(); // 更新當前LED的上次切換時間為當前時間 | |
} | |
} | |
void loop() { | |
for(int ledid = 0; ledid < 20; ledid++) // 循環遍歷0到19的引腳,逐個控制LED | |
{ | |
ledblink(ledid, random(ledid, 2000 * ledid)); // 調用ledblink函數,為當前LED生成一個隨機閃爍周期并控制其閃爍 | |
// random(ledid, 2000*ledid) 生成一個范圍在 [ledid, 2000*ledid) 的隨機整數作為閃爍周期 | |
} | |
} |
代碼邏輯說明:
-
數組
t[20]
:
用于記錄每個LED的上次狀態切換時間,確保每個LED的閃爍是獨立的。 -
setup()
函數:
初始化每個LED的控制引腳為輸出模式,并記錄當前時間作為初始切換時間。 -
ledblink()
函數:
根據當前時間與上次切換時間的差值,決定是否切換LED的狀態。如果差值大于等于閃爍周期,則切換狀態并更新上次切換時間。 -
loop()
函數:
循環遍歷每個LED,調用ledblink()
函數,并為每個LED生成一個隨機閃爍周期。隨機數范圍隨ledid
增大而增大,導致高編號LED的閃爍頻率較低。
注意事項:
-
隨機數范圍:
random(ledid, 2000*ledid)
生成的隨機數范圍較大,高編號LED的閃爍頻率可能過低,肉眼難以察覺閃爍。可根據需要調整隨機數范圍。 -
引腳13:
pinMode(13, OUTPUT);
在本實驗中未實際使用,可刪除或保留作為備用。 -
非阻塞式控制:
使用millis()
函數實現非阻塞式控制,確保所有LED的狀態切換獨立且實時。
項目仿真網址:
https://wokwi.com/projects/415863028802020353
實驗報告:基于Wokwi Arduino Mega 2560 的多LED隨機閃爍實驗
實驗名稱
基于Arduino Mega 2560的多LED隨機閃爍實驗
實驗目的
- 學習使用Arduino Mega 2560控制多個LED。
- 掌握
millis()
函數實現非阻塞式LED閃爍。 - 理解隨機數生成在LED閃爍頻率控制中的應用。
- 熟悉Wokwi仿真平臺的使用。
實驗器材
- Wokwi在線仿真平臺。
- Arduino Mega 2560開發板(仿真)。
- 20個LED(仿真)。
- 20個電阻(220Ω,仿真)。
- 面包板和若干連接線(仿真)。
實驗原理
-
非阻塞式編程:
使用millis()
函數記錄時間,通過比較當前時間與上次LED狀態切換時間的差值,決定是否切換LED狀態。這種方式避免了使用delay()
函數導致的程序阻塞。 -
隨機數生成:
使用random(min, max)
函數生成一個范圍在[min, max)
的隨機整數,用于控制每個LED的閃爍頻率。 -
多LED控制:
通過數組t[20]
記錄每個LED的上次狀態切換時間,結合循環實現對20個LED的獨立控制。
實驗電路連接
- 將Arduino Mega 2560的引腳0~19分別連接到20個LED的負極(通過電阻接地)。
- LED的正極連接到5V電源。
- 仿真中可直接在Wokwi平臺拖拽元件完成連接。
實驗代碼分析
cpp復制代碼
unsigned long t[20]; // 用于存儲每個LED的上次狀態切換時間 | |
void setup() { | |
pinMode(13, OUTPUT); // 示例代碼中的冗余設置(未使用引腳13) | |
for (int ledid = 0; ledid < 20; ledid++) { | |
pinMode(ledid, OUTPUT); // 將引腳0~19設置為輸出模式 | |
t[ledid] = millis(); // 初始化每個LED的上次切換時間為當前時間 | |
} | |
} | |
void ledblink(int ledid, int ledhz) { | |
// 如果當前時間與上次切換時間的差值大于等于閃爍周期,則切換LED狀態 | |
if (millis() - t[ledid] >= ledhz) { | |
digitalWrite(ledid, !digitalRead(ledid)); // 切換LED狀態 | |
t[ledid] = millis(); // 更新上次切換時間 | |
} | |
} | |
void loop() { | |
for (int ledid = 0; ledid < 20; ledid++) { | |
// 為每個LED生成一個隨機閃爍周期,并調用ledblink函數 | |
ledblink(ledid, random(ledid, 2000 * ledid)); | |
} | |
} |
實驗步驟
-
搭建電路:
在Wokwi平臺中,將Arduino Mega 2560的引腳0~19分別連接20個LED(通過電阻接地)。 -
編寫代碼:
將上述代碼復制到Wokwi的代碼編輯器中。 -
運行仿真:
點擊“Start Simulation”按鈕,觀察LED的閃爍情況。 -
記錄現象:
觀察每個LED的閃爍頻率是否隨機,且是否獨立工作。
實驗結果
- 現象描述:
- 20個LED以不同的頻率隨機閃爍。
- 每個LED的閃爍頻率在程序運行期間動態變化。
- 所有LED獨立工作,互不干擾。
- 結果分析:
random(ledid, 2000 * ledid)
生成的隨機數范圍隨ledid
增大而增大,導致高編號LED的閃爍頻率較低。millis()
函數實現了非阻塞式控制,確保所有LED的狀態切換獨立且實時。
實驗問題與改進
- 問題:
- 高編號LED的閃爍頻率過低,可能導致肉眼難以察覺閃爍。
- 隨機數生成范圍過大,導致閃爍頻率差異顯著。
- 改進建議:
- 調整隨機數范圍,例如
random(100, 500)
,使所有LED的閃爍頻率更接近。 - 增加一個全局變量控制閃爍頻率范圍,便于動態調整。
- 調整隨機數范圍,例如
改進后的代碼示例
cpp復制代碼
unsigned long t[20]; | |
int minHz = 100; // 最小閃爍周期(毫秒) | |
int maxHz = 500; // 最大閃爍周期(毫秒) | |
void setup() { | |
for (int ledid = 0; ledid < 20; ledid++) { | |
pinMode(ledid, OUTPUT); | |
t[ledid] = millis(); | |
} | |
} | |
void ledblink(int ledid, int ledhz) { | |
if (millis() - t[ledid] >= ledhz) { | |
digitalWrite(ledid, !digitalRead(ledid)); | |
t[ledid] = millis(); | |
} | |
} | |
void loop() { | |
for (int ledid = 0; ledid < 20; ledid++) { | |
ledblink(ledid, random(minHz, maxHz)); | |
} | |
} |
實驗總結
- 通過本實驗,掌握了使用
millis()
函數實現非阻塞式LED控制的方法。 - 理解了隨機數生成在動態控制中的應用。
- 學會了在Wokwi平臺中搭建多LED電路并調試代碼。
- 改進后的代碼實現了更均勻的閃爍頻率,提升了實驗效果。
附錄
-
Wokwi仿真鏈接:
(此處可附上實驗仿真鏈接,若需分享) -
參考文獻:
- Arduino官方文檔
- Wokwi在線仿真平臺教程
實驗報告撰寫人:XXX
日期:XXXX年XX月XX日
課程要點:
在 Wokwi 平臺上使用 Arduino Mega 2560 進行 IO 口簡單應用的學習,可以涵蓋硬件基礎、編程入門以及實際應用等多個方面。以下是詳細的課程內容概述:
一、Arduino Mega 2560 硬件基礎
-
核心特性
- 微控制器:基于 ATmega2560 芯片,具有 256KB 的 Flash 程序內存、8KB 的 SRAM 和 4KB 的 EEPROM。
- IO 端口:提供 54 個數字 I/O 引腳(其中 15 個支持 PWM 輸出)、16 個模擬輸入引腳。
- 通信接口:4 個硬件串行端口、1 個 USB 接口、1 個 ICSP 接口,支持 SPI、I2C 等通信協議。
- 電源管理:可通過 USB、外部直流電源或電池供電,自動選擇供電方式。
-
引腳布局與功能
- 數字 I/O 引腳:如引腳 0-13 可用于數字輸入/輸出和串行通信,引腳 2-13、44-46 支持 PWM 輸出。
- 模擬輸入引腳:如 A0-A15 可用于模擬信號輸入,部分引腳也可用作數字 I/O。
- 特殊功能引腳:如 AREF(模擬參考電壓)、Reset(復位按鈕)、GND(地線)、VIN(外部電源輸入)等。
二、Wokwi 平臺使用入門
-
平臺簡介
- Wokwi 是一個在線的 Arduino 模擬器,支持多種 Arduino 型號,包括 Mega 2560。
- 無需硬件即可進行 Arduino 編程和仿真,適合初學者快速上手。
-
基本操作
- 創建項目:在 Wokwi 平臺上選擇 Arduino Mega 2560 型號,創建新的項目。
- 編寫代碼:使用內置的代碼編輯器編寫 Arduino 代碼。
- 仿真運行:點擊“運行”按鈕,觀察仿真結果。
三、IO 口簡單應用編程
-
數字 I/O 控制
- LED 閃爍:通過控制數字 I/O 引腳的電平高低,實現 LED 的閃爍。
- 按鈕控制:讀取數字 I/O 引腳的狀態,實現按鈕控制 LED 的亮滅。
-
模擬輸入讀取
- 電位器調光:通過讀取模擬輸入引腳的值,控制 LED 的亮度。
- 傳感器數據讀取:如使用光敏電阻、溫度傳感器等模擬傳感器,讀取環境數據。
-
PWM 輸出控制
- 電機調速:通過 PWM 輸出控制電機的轉速。
- LED 調光:通過 PWM 輸出實現 LED 的亮度調節。
-
串行通信
- 串口打印:通過串行端口向計算機發送數據,實現調試信息的輸出。
- 串口通信協議:如使用串口與其他設備進行數據交換。
四、實際應用案例
-
智能家居控制
- 使用 Arduino Mega 2560 控制燈光、窗簾、空調等家居設備。
- 通過串行通信或無線通信模塊與手機 APP 進行交互。
-
環境監測系統
- 使用各種傳感器監測環境溫度、濕度、光照等參數。
- 通過串行通信將數據上傳到計算機或云服務器進行分析和處理。
-
機器人控制
- 使用 Arduino Mega 2560 控制機器人的電機、舵機等執行機構。
- 通過傳感器獲取環境信息,實現機器人的自主導航和避障。
五、課程總結與展望
-
課程總結
- 回顧 Arduino Mega 2560 的硬件基礎和 Wokwi 平臺的使用方法。
- 總結 IO 口簡單應用編程的關鍵點和注意事項。
-
未來展望
- 介紹 Arduino Mega 2560 在更復雜項目中的應用前景。
- 鼓勵學生繼續深入學習 Arduino 編程和電子技術。