//MQTT-裝置#2 蜂鳴器與風扇(Wokwi尚無提供風扇)
#include <WiFi.h> //WIFI
#include <PubSubClient.h> //MQTT
#define buzzer 23 //警報蜂鳴器
#define FAN_PIN 22 //散熱風扇
//溫度超過閾值,啟動風扇與警報
float temperatureThreshold = 32.0;
const int freq = 5000; //頻率
const int resolution = 8; //解析度
const char* ssid = "Your SSID";
const char* password = "Your Passwd";
const char* mqttServer = "mqttgo.io";//免註冊MQTT伺服器
const int mqttPort = 1883; //MQTT Port
const char* mqttUser = ""; //不須帳密
const char* mqttPassword = ""; //不須帳密
//訂閱主題:裝置5溫度
char* MQTTSubTopic1 = "MQTT/Device5/temperature";
WiFiClient wifiClient; //WIFIClient
PubSubClient client(wifiClient); //MQTTClient
void Callback(char* topic,byte* message,unsigned int length){
Serial.print("裝置2訂閱:");Serial.println(topic);
String receivedMessage;
for (int i = 0; i < length; i++) {
receivedMessage += (char)message[i];
}
Serial.print("訊息內容: ");
Serial.println(receivedMessage); //顯示收到訊息
float t = atof(receivedMessage.c_str()); //轉換為浮點數
if (String(topic) == MQTTSubTopic1) { //核對訂閱主題?
Serial.print(" Temp: "); //是
Serial.println(t); // 顯示溫度數
if(t>temperatureThreshold){ //若超標t
FanAction(t); //啟動散熱風扇,轉速依T而變
BuzAction(t); //啟動警報
}
}
}
void setup() {
Serial.begin(115200);
WifiConnecte(); //連接WIFI
MQTTConnecte(); //開始MQTT連線
pinMode(buzzer,OUTPUT); //蜂鳴器
//設置 PWM通道 : IO腳, 頻率f, 解析度r ,通道0
ledcAttachChannel(FAN_PIN, freq, resolution, 0);
}
void loop() {
//如果WiFi連線中斷,則重啟WiFi連線---------------------
if (WiFi.status() != WL_CONNECTED) { WifiConnecte(); }
//如果MQTT連線中斷,則重啟MQTT連線--------------------
if (!client.connected()) { MQTTConnecte(); }
client.loop(); //MQTT更新訂閱狀態
}
//開始WiFi連線---------------------------------------
void WifiConnecte() {
WiFi.mode(WIFI_STA); //STA模式
WiFi.disconnect(); //重置網路
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.printf("Connecting to %s ...\n",ssid);//連線中…
}
Serial.println("已連線成功:ip=" + WiFi.localIP().toString());
}
//開始MQTT連線----------------------------------------
void MQTTConnecte() {
client.setServer(mqttServer, mqttPort);//連線設定
client.setCallback(Callback); //收到訂閱資料時,要處理CallBack
while (!client.connected()) { //若未連上就重連
//以亂數為clietID,不重覆id
String clientid = "esp32-receiver-" + String(random(100000, 999999));
if (client.connect(clientid.c_str(), mqttUser, mqttPassword)) {
Serial.println("MQTT已連線");
client.subscribe(MQTTSubTopic1); //訂閱SubTopic1主題
} else {
Serial.print("MQTT連線失敗,狀態碼=");
Serial.println(client.state());
Serial.println("五秒後重新連線");
delay(5000);
}
}
}
void FanAction(int y){ //y為溫度值,控制轉速
//例:風扇控制 : 溫度值(25~50),控制轉速0~255
int fanSpeed =map(y,28,33,0,255); //依溫度
ledcWrite(FAN_PIN, fanSpeed); //控制轉速
Serial.printf("現在轉速:%d \n",fanSpeed);
delay(5000); // 令風扇轉動一段時間,繼續觀察
}
//警報音響
void BuzAction(int m){
int C6=1047+5*m; //依溫度變調
int D5=587-2*m;
tone(buzzer,C6,500);
tone(buzzer,D5,500);
delay(200);
tone(buzzer,C6,500);
tone(buzzer,D5,500);
delay(200);
tone(buzzer,C6,500);
tone(buzzer,D5,500);
delay(200);
tone(buzzer,0,1000); //靜音
}