通過這篇文章,可以了解到以下內容:
- 利用 Arduino 使用 5050全彩 LED 和 DTH11 溫濕度傳感器
- 利用 USB 與 Arduino,實現電腦與 Arduino 串口通訊
- 通過發送特定指令,控制 LED 變色以及獲取溫濕度數據
Arduino 與傳感器接線方法
在這個 Arduino 微項目實踐中,我們用到的傳感器有兩個:
- DTH11 溫濕度傳感器
- 5050 RGB LED 彩燈
DTH 溫濕度傳感器的使用方法很簡單,可以參考購買傳感器時商家提供的資料,或者參考我的另外一篇文章 《Arduino使用DHT11溫濕度傳感器獲取環境溫濕度》 來了解 DTH11 的使用。
5050 RGB 彩色 LED 燈,是一種把彩燈封裝好的一個彩燈模塊,模塊上有 4 個引腳,分別是 GND
R
G
B
,使用時,將模塊上的 GND
與 Arduino 的 GND
相連接,然后 RGB引腳分別接到 Arduino 的三個數字輸出 Pin 引腳,然后在 Arduino 中通過PWM驅動即可。
注意 由于 Frizing 的元件庫中并沒有找到國內網上常見的那種 5050 RGB LED 模塊原件,因此找了一個類似的替代,在具體實踐的時候,應根據自己購買的模塊說明連接使用。
以下是 Arduino 電路連接示意圖:
我們將 Arduino 的 Pin 9 ~ 11
分別連接 LED 模塊的 G
B
R
引腳,Arduino GND
連接到 GND
模塊上。DHT11模塊 VCC
與 Arduino 5V
相連,GND
與 Arduino GND
相連,DATA
與 Arduino Pin 2
相連。這樣,我們即完成了 Arduino 電路的連接。注意 實際實踐的時候,需要根據自己購買的模塊不同響應調整。
Arduino 代碼編寫
Arduino 程序主要有幾個難點,分別是:
- 如何處理 Serial 輸入,識別不同的命令進行處理
- LED 燈控制的技巧
- 獲取溫濕度數據
處理 Serial 輸入
使用 Serial 傳輸數據,主要用到以下幾個方法:
下面簡單介紹以下這三個方法的使用。
Serial.read()
用于返回 Serial 中的一個字節,如果沒有可以返回的數據,則返回 -1
,我們將會使用這個方法來獲取 Serial 中的內容。
Serial.available()
用于檢查 Serial 中剩余的數據,我們可以通過這個方法來檢測是否由數據在 Serial 中。
Serial.parseInt()
用于解析 Serial 中的數值數據,將其轉換為 int
,在這個項目中,我們將用這個方法來獲取 LED 燈的顏色參數值。
接下來,我們面前有兩個問題需要解決:
- Arduino 要如何判斷我們的命令意圖
- 如何返回程序的返回值
要使得 Arduino 能夠處理 LED 燈變色,或者返回溫濕度傳感器的測量數據,首先要給 Arduino 發出不同的指令,然后 Arduino 通過判斷不同的指令來作出相應的處理才能實現我們想要的結果。
因此,我們可以選擇使用指令的第一個字母來判別不同的功能,在這個項目中,我們可以用 L
來表示進入 LED 燈控制模式,D
表示進入溫濕度數據讀取模式。除此之外,我們還需要識別出命令的尾部,從而結束一行命令的解析,這里我們用換行 \n
來標記一條命令的結束。
這樣,我們就基本解決了如何判斷命令意圖的問題,到這一步為止,我們的程序大致如下:
while(Serial.available() > 0){
char incomeByte = Serial.read();
if (incomeByte == 'L') {
// 進入 LED 控制部分
if (Serial.read() == '\n') {
// 命令結束,處理
} else {
// 不符合指令輸入要求,返回錯誤處理
}
} else if (incomeByte == 'D') {
// 溫濕度數據讀取處理
}
}
我們現在已經解決了指令的識別,但還存在一個問題,就是加入輸入的命令既不是 LED 控制,也不是溫濕度數據獲取,那么理想狀態下應該會返回一個錯誤值。我們這里將采取通過判斷 \n
來識別出指令的尾部,如果沒有成功進入 LED 控制或者溫濕度獲取,而且 Serial 讀取到指令尾部,那么我們就返回一個錯誤的返回值。程序實例如下:
while(Serial.available() > 0){
char incomeByte = Serial.read();
if (incomeByte == 'L') {
// 進入 LED 控制部分
if (Serial.read() == '\n') {
// 命令結束,處理
} else {
// 不符合指令輸入要求,返回錯誤處理
}
} else if (incomeByte == 'D') {
// 溫濕度數據讀取處理
} else if (incomeByte == '\n') {
// 返回錯誤
}
}
到這里為止,我們就已經完成指令識別的功能。
LED 燈控制的技巧
我們所使用的 5050 RGB LED 模塊,通過 PWM 驅動從而實現變色的,我們可以為 LED 變色編寫一個方法,輸入三個 0 ~ 255 的顏色參數,然后實現變色,方法代碼如下:
boolean setLedColor(int red, int green, int blue)
{
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
return true;
}
這里有一點需要注意,因為用戶的輸入未必是 0 ~ 255 的數值,因此我們在使用這個變色方法之前,需要先對用戶的輸入進行過濾,代碼示例如下:
// 獲取 R G B 用戶輸入
int red = Serial.parseInt();
int green = Serial.parseInt();
int blue = Serial.parseInt();
// 過濾用戶輸入
redVal = constrain(red, 0, 255);
greenVal = constrain(green, 0, 255);
blueVal = constrain(blue, 0, 255);
這樣,我們就完成了對 LED 燈的控制部分程序編寫了。
溫濕度數據獲取
溫濕度數據獲取也比較簡單,我們首先要檢查溫濕度傳感器是否正常,然后再進行獲取數據,檢查傳感器的示例代碼如下:
int chk = DHT11.read(dth11Pin);
if (chk == DHTLIB_OK) {
// 傳感器正常
} else {
// 傳感器出現問題
}
接下來,我們像控制 LED 變色一樣,編寫一個獲取并輸出溫濕度數據的方法,示例代碼如下:
void printHT()
{
Serial.print("Status: 1, Data: {");
Serial.print((float)DHT11.humidity, 2);
Serial.print(',');
Serial.print((float)DHT11.temperature, 2);
Serial.print("}\n");
}
我們這里選擇直接通過 Serial 輸出,其中輸出信息包括 Status: 1 的正確標識,然后 Data 中返回第一個返回值是濕度,第二個返回值是溫度。
到這里為止,我們的 Arduino 程序就基本完成了,完整的代碼入下:
/*
File : ComLEDHtSenSer.ino
Date : 2017-9-13
Author : Yan Wong (speculatecat)
Description : The program is a demo for using com serial to control the LED color and get the tempture and humidity form DHT11 senser.
*/
#include <dht11.h>
dht11 DHT11;
// Define RGB pin
const int redPin = 11;
const int bluePin = 10;
const int greenPin = 9;
// Define DTH11 pin
const int dth11Pin = 2;
// Store LED color, default RGB - 255,255,255
int redVal = 255;
int blueVal = 255;
int greenVal = 255;
void printStatus(boolean flag)
{
Serial.print("Status:");
Serial.print(flag);
Serial.print('\n');
}
void printHT()
{
Serial.print("Status: 1, Data: {");
Serial.print((float)DHT11.humidity, 2);
Serial.print(',');
Serial.print((float)DHT11.temperature, 2);
Serial.print("}\n");
}
boolean setLedColor(int red, int green, int blue)
{
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
return true;
}
void setup()
{
// Set Serial port - 9600
Serial.begin(9600);
// Set LED pin model
pinMode(redPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
}
void loop()
{
boolean flag = false;
while(Serial.available() > 0){
char incomeByte = Serial.read();
if (incomeByte == 'L') {
// The first byte from serial is 'L', mean enter LED color change model.
int red = Serial.parseInt();
int green = Serial.parseInt();
int blue = Serial.parseInt();
if (Serial.read() == '\n') {
// The end of command is '\n'.
redVal = constrain(red, 0, 255);
greenVal = constrain(green, 0, 255);
blueVal = constrain(blue, 0, 255);
if (setLedColor(redVal, greenVal, blueVal)) {
flag = true;
printStatus(flag);
}
} else {
printStatus(flag);
}
} else if (incomeByte == 'D') {
// Get humidity and temperature from dht11.
int chk = DHT11.read(dth11Pin);
if (chk == DHTLIB_OK) {
printHT();
} else {
printStatus(false);
}
} else if (incomeByte == '\n') {
// Error command, return false.
printStatus(flag);
}
}
}
接下來,我們將程序編譯好上傳到 Arduino 即可。
項目演示
Arduino 和各個模塊正確連接,并上傳好 Arduino 程序后,我們就可以通過串口監視器來與 Arduino 進行通信。以下是串口監視器的部分通信截圖:
可以看到,如果我們輸入預設沒有的指令,會返回 Status: 0
的錯誤信息,如果發送更改 LED 顏色的指令,可以看到 Status: 1
成功的返回值,發送溫濕度數據獲取的指令,可以看到溫濕度數據的返回。
下面是我的 Arduino 與各個模塊的連接以及運行時的照片,可供參考:
小結
到此為止,我們這個微項目實踐已經完成。我們隨后還可以在這個基礎上,改造成通過藍牙控制和獲取數據,或者添加程序,使得 LED 等可以根據環境的不同溫濕度來呈現不同的顏色。
如果你對這個微項目實踐有疑問,可以在本文回復,我會盡力回答。
如果你覺得這篇文章對你有幫助,歡迎點擊喜歡收藏,或者關注我。