溫濕度採集與控制(WEB)
# FastWeb之溫濕度採集與控制
- 適用平臺:WEB(桌面)
# 1. 說明
本範例使用ModbusTCP通訊協議,讀取連線至Arduino的溫濕度感測器數據,同時可通過ModbusTCP來控制LED燈以及繼電器開關。可通過視訊直播流檢視正在播放的設備運行情況。
本範例除使用常規的Arduino硬體外,還需要使用到用於進行直播錄像的攝像機,該攝像機錄製的視訊將以視訊直播流的形式發送至指定的RTMP伺服器中,範例從該地址中接收視訊流播放視訊錄像。在使用該範例前需要讀者對視訊直播的流程有一定的瞭解,並使用自行搭建的流媒體伺服器或者第三方的視訊直播服務進行推流直播。自行搭建的流媒體伺服器可使用SRS (opens new window)。
通過本範例學習,可以掌握ModbusTCP的基本通訊原理,實現Arduino設備的綜合控制。
# 2. 零件連線圖
零件連線如下圖所示,其中電動機的部分為製冷與風扇的外圍電路,製冷器與溫濕度感測器緊貼。
# 3. 使用零件
序 | 零件名稱 | 數量 |
---|---|---|
1 | Arduino UNO R3 開發板 | 1 |
2 | W5100網路擴充套件板 | 1 |
3 | USB數據線 | 1 |
4 | 麵包板 | 1 |
5 | 杜邦線 | 若干 |
6 | LED燈 | 1 |
7 | 220歐姆電阻 | 1 |
8 | LCD1602液晶顯示屏(I2C介面) | 1 |
9 | DHT11溫濕度感測器 | 1 |
10 | 繼電器 | 1 |
11 | 半導體制冷片 | 1 |
12 | 電動機 | 1 |
# 4. Arduino流程圖
# 5. Arduino程式
使用Arduino IDE 編譯並上傳以下Arduino程式。
// 使用溫濕度感測器之鏈接庫 https://github.com/adafruit/DHT-sensor-library
// 採用 MyArduinoProjects Modbus TCP 鏈接庫 http://myarduinoprojects.com/modbus.html
// 讀取溫濕度 因為modbus 無法傳遞小數字 所以先乘100 到客戶端取用時要除 100
#include <DHT.h>
#include <SPI.h>
#include <Ethernet.h>
#include <MgsModbus.h> // 引入Modbus TCP 鏈接庫
#include <LiquidCrystal_I2C.h> //引用I2C庫
MgsModbus Mb;
//設定LCD1602設備地址,一般是0x20,或者0x27,具體看模組手冊
LiquidCrystal_I2C lcd(0x27,16,2);
#define dhtPin 8 //讀取DHT11 Data
#define dhtType DHT11 //選用DHT11
DHT dht(dhtPin, dhtType); // Initialize DHT sensor
#define LED_PIN 9 //定義LED PIN為 9
#define COOLER_PIN 7 //定義製冷器PIN為 7
// 設定網路IP地址 (網路擴充卡 MAC 可自行修改 +1 避免衝突)
byte mac[] = {0x90, 0xA2, 0xDA, 0x0E, 0x94, 0xB8 };
IPAddress ip(192, 168, 0, 183);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(9600); //設定鮑率9600
Ethernet.begin(mac, ip, gateway, subnet); // 啟動網路
Serial.println("網路已經開通");
pinMode(LED_PIN, OUTPUT);
pinMode(COOLER_PIN, OUTPUT);
lcd.init(); // 初始化LCD
lcd.backlight(); //設定LCD背景等亮
lcd.setCursor(0,0); //設定顯示指針
lcd.print("IsoFace LiveDemo");
//設定要使用的快取器地址
//0 1 2 3 4 是 Holding 快取器的順序,其地址分別是10000,10001,10002,10003,10004
// 新增快取器 mb.MbData(i);
Mb.MbData[0] = 0; // 地址 0 存放所測得之溫度
Mb.MbData[1] = 0; // 地址 1 存放所測得之濕度
Mb.MbData[2] = 0; // 地址 2 存放LED燈的狀態
Mb.MbData[3] = 0; // 地址 3 存放製冷器的狀態
dht.begin();//啟動DHT
}
void loop() {
// LED燈狀態指示
if (Mb.MbData[2]!=0){
digitalWrite(LED_PIN, HIGH); //PIN 9輸出為HIGH,LED點亮
}
else {
digitalWrite(LED_PIN, LOW); //PIN 9輸出為LOW,LED熄滅
}
// 製冷器狀態指示
if (Mb.MbData[3]!= 0){
digitalWrite(COOLER_PIN, HIGH);
}
else{
digitalWrite(COOLER_PIN, LOW);
}
float h = dht.readHumidity()*100; //讀取濕度 因為modbus 無法傳遞小數字 所以先乘100 到客戶端取用時要除 100
float t = dht.readTemperature()*100; //讀取攝氏溫度
if (isnan(h) || isnan(t)) {
Serial.println("無法從DHT感測器讀取!");
return;
}
Mb.MbData[0] = t; // 地址 0 存放所測得之溫度
Mb.MbData[1] = h; // 地址 1 存放所測得之濕度
//輸出顯示狀態
lcd.clear();
lcd.setCursor(0, 0);
if (Mb.MbData[2] != 0){
lcd.print("LED:ON ");
}
else{
lcd.print("LED:OFF ");
}
if (Mb.MbData[3] != 0){
lcd.print("FAN:ON ");
}
else{
lcd.print("FAN:OFF ");
}
lcd.setCursor(0, 1);
lcd.print("T:" + String(t*0.01)+ " " + "H:" + String(h*0.01));
delay(500); //延時 0.5 秒
Mb.MbsRun(); //呼叫 Modbus
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# 6. 設計明細
開啟FastWeb設計器,分別加入下插圖之控制元件。或者點選左上角的[匯入]
選擇模板檔案來打開對應模板。
①:TUgTimer元件,控制元件名稱為UgTimer
。
②:TUgImage元件,控制元件名稱為UgImage01
。
③:TUgFlvPlayer元件,控制元件名稱為UgFlvPlayer01
。
④:TUgFSToggle元件,控制元件名稱為UgFSToggle01
。
⑤:TUgLabel元件,控制元件名稱為lbTmp
。
⑥:TUgFSToggle元件,控制元件名稱為UgFSToggle02
。
⑦:TUgLabel元件,控制元件名稱為lbHum
。
⑧:TUgModbusTCPClient元件,控制元件名稱為UgModbusTCPClient
。
⑨:TUgTimer元件,控制元件名稱為UgTimer01
。
⑩:TUgTimer元件,控制元件名稱為UgTimer02
。
UgWebRunFrame屬性設定
Height
:設定頁面高度=640
。Width
:設定頁面寬度=883
。
①UgTimer屬性設定
Interval
:設定計數的時間間隔,設定為2000
。Enabled
:設定是否啟用計時器,設定為False
。
②UgImage01屬性設定
Align
:設定對齊方式,設定為alClient
。Stretch
:設定圖片是否與控制元件拉伸對齊,設定為True
。Picture
:設定圖片。點選Picture
屬性右側的[√]
,打開影象編輯器,點選[Load]
按鈕打開檔案上傳界面,點選右側的[Browse...]
打開影象瀏覽界面,選擇影象后,點選[確定]
按鈕返回到檔案上傳界面,點選[Upload]
將檔案上傳至編輯器中,待圖片顯示后,點選[Save]
按鈕即可。
④UgFSToggle01屬性設定
TitleOff
:設定為關閉時顯示的內容,設定為關
。TitleOn
:設定為開啟時顯示的內容,設定為開
。
⑤lbTmp屬性設定
Caption
:設定標籤顯示的內容,設定為False
。Font
:設定標籤文字顯示的字型,此處設定其Color
為需要的顏色,設定Size
為16
。設定Style
中fsBold
為True
。
⑥UgFSToggle02屬性設定
TitleOff
:設定為關閉時顯示的內容,設定為關
。TitleOn
:設定為開啟時顯示的內容,設定為開
。
⑦lbHum屬性設定
Caption
:設定標籤顯示的內容,設定為False
。Font
:設定標籤文字顯示的字型,此處設定其Color
為需要的顏色,設定Size
為16
。設定Style
中fsBold
為True
。
⑧ModbusTCPClient屬性設定
AutoConnect
:設定是否進行自動連線,設定為True
。Host
:設定客戶端的地址,設定為192.168.0.183
。
⑨UgTimer01屬性設定
Enabled
:設定是否啟用計時器,設定為False
。Interval
:設定計時器的時間間隔,設定為30000
。
⑩UgTimer02屬性設定
Enabled
:設定是否啟用計時器,設定為False
。Interval
:設定計時器的時間間隔,設定為50
。
# 7. 指令碼設計
# 7.1. 指令碼初始設定
該程式啟動后,開啟計時器。
//JScript
function UgWebRunFrameOnAfterRunScript(sender)
//啟動定時器
{
UGMM.LC(Self);
UgTimer.Enabled = True;
UgTimer02.Enabled = True;
}
2
3
4
5
6
7
8
//PasScript
procedure UgWebRunFrameOnAfterRunScript(const sender: tobject);
//啟動定時器
begin
UgTimer.Enabled := True;
UgTimer02.Enabled := True;
end;
2
3
4
5
6
7
// Make sure to add code blocks to your code group
在初始化時為直播設定相應的地址。
//JScript
{
//設定直播地址
UgFlvPlayer01.SetSource("http://nas.isoface.cn:1688/live/001.flv", "flv");
}
2
3
4
5
//PasScript
Begin
//設定直播地址
UgFlvPlayer01.SetSource('http://192.168.0.113/live/001.flv', 'flv');
End.
2
3
4
5
// Make sure to add code blocks to your code group
# 7.2. 事件設定
- ①UgTimer-OnTimer事件
計時器定時觸發事件,每隔2秒讀取溫濕度並顯示。
//JScript
function UgTimerOnTimer(sender)
//讀取溫濕度
{
var t,h,tmp,hum;
UgModbusTCPClient.ReadHoldingRegister(1,t);
UgModbusTCPClient.ReadHoldingRegister(2,h);
tmp = FloatToStr(t * 0.01);
hum = FloatToStr(h * 0.01);
LbTmp.Caption = tmp + "℃";
LbHum.Caption = hum + "%RH";
}
2
3
4
5
6
7
8
9
10
11
12
//PasScript
procedure UgTimerOnTimer(sender: tobject);
//讀取溫濕度
Var
tmp: String;
hum: String;
t: Integer;
h: Integer;
begin
UgModbusTCPClient.ReadHoldingRegister(1,t);
UgModbusTCPClient.ReadHoldingRegister(2,h);
tmp := FloatToStr(t * 0.01);
hum := FloatToStr(h * 0.01);
LbTmp.Caption := tmp + '℃';
LbHum.Caption := hum + '%RH';
end;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Make sure to add code blocks to your code group
- ④UgFSToggle01-OnToggle事件
當切換LED燈的開關時,執行LED的開關操作。
//JScript
function UgFSToggle01OnToggled(value)
//LED開關
{
if (UgFSToggle01.Toggled){
UgModbusTCPClient.WriteRegister(3,1);
}
Else{
UgModbusTCPClient.WriteRegister(3,0);
}
}
2
3
4
5
6
7
8
9
10
11
//PasScript
procedure UgFSToggle01OnToggled(const value: boolean);
//LED開關
begin
if UgFSToggle01.Toggled then
UgModbusTCPClient.WriteRegister(3,1)
Else
UgModbusTCPClient.WriteRegister(3,0);
end;
2
3
4
5
6
7
8
9
// Make sure to add code blocks to your code group
- ⑥UgFSToggle01-OnToggle事件
當切換製冷器電源開關時,執行相應的操作。
//JScript
function UgFSToggle02OnToggled(value)
//製冷器、風扇開關
{
UgTimer01.Enabled = True;
if (UgFSToggle02.Toggled){
UgModbusTCPClient.WriteRegister(4,1);
}
Else{
UgModbusTCPClient.WriteRegister(4,0);
}
}
2
3
4
5
6
7
8
9
10
11
12
//PasScript
procedure UgFSToggle02OnToggled(const value: boolean);
//製冷器、風扇開關
begin
UgTimer01.Enabled := True;
if UgFSToggle02.Toggled then
UgModbusTCPClient.WriteRegister(4,1)
Else
UgModbusTCPClient.WriteRegister(4,0);
end;
2
3
4
5
6
7
8
9
10
// Make sure to add code blocks to your code group
- ⑨UgTimer01-OnTimer事件
計時器定時觸發的事件,當啟用后,30秒經過自動關閉製冷器。
//JScript
function UgTimer01OnTimer(sender)
//定時30秒后自動關閉製冷器
{
UgModbusTCPClient.WriteRegister(4,0);
UgFSToggle02.Toggled = False;
UgTimer01.Enabled = False;
}
2
3
4
5
6
7
8
//PasScript
procedure UgTimer01OnTimer(sender: tobject);
//定時30秒后自動關閉製冷器
begin
UgModbusTCPClient.WriteRegister(4,0);
UgFSToggle02.Toggled := False;
UgTimer01.Enabled := False;
end;
2
3
4
5
6
7
8
// Make sure to add code blocks to your code group
- ⑩UgTimer02-OnTimer事件
計時器定時觸發事件,當啟用后初始化讀取相應的開關狀態。
//JScript
function UgTimer02OnTimer(sender)
//初始化讀取開關狀態
{
var led,cooler;
UgModbusTCPClient.ReadHoldingRegister(3,led);
UgModbusTCPClient.ReadHoldingRegister(4,cooler);
if (led == 0){
UgFSToggle01.Toggled = False;
}
Else{
UgFSToggle01.Toggled = True;
}
if (cooler == 0){
UgFSToggle02.Toggled = False;
}
Else{
UgFSToggle02.Toggled = True;
}
UgTimer02.Enabled = False;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//PasScript
procedure UgTimer02OnTimer(sender: tobject);
//初始化讀取開關狀態
Var
led: Integer;
cooler: Integer;
begin
UgModbusTCPClient.ReadHoldingRegister(3,led);
UgModbusTCPClient.ReadHoldingRegister(4,cooler);
if led = 0 Then
UgFSToggle01.Toggled := False
Else
UgFSToggle01.Toggled := True;
if cooler = 0 Then
UgFSToggle02.Toggled := False
Else
UgFSToggle02.Toggled := True;
UgTimer02.Enabled := False;
end;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Make sure to add code blocks to your code group
# 8. 運行結果
使用滑鼠在FastWeb功能表,點選[儲存至資料庫]
按鈕,將其儲存至資料庫,點選[除錯運行]
確認能夠正常打開。
程式啟動后,點選LED燈
或者製冷器
的開關按鈕,對應的元件開啟或關閉,可在直播畫面中看到狀態的顯示。