把台灯改造为可以通过手机控制,解决躺下后不想起来关灯的烦恼。

前面通过自制环境监测仪的项目,对于使用 esp32 开发板,还有 arduino IDE 集成开发环境来做一些电子方面 DIY 已经有了一定经验。那么接下来进一步用这种能力来让生活变得更美好。这里就是尝试使用继电器模块,将台灯改造为可以使用手机来控制。

对照着网上查到的资料,先把线连好。非常需要注意的是,连线的时候千万不要有任何模块部件通电。虽然我这个台灯是 5V USB 台灯,也不要这样,主要是养成用电安全的习惯。

我这里是直接把台灯上的 USB的线剥开,然后只剪断其中的黑色线,分别接到 NO 和 COM 端子就行了。千万不要把整个 USB线剪断了。继电器控制端接线,VCC接ESP32开发板上的供电引脚 3.3V,GND接 GND,IN接到4 号GPIO引脚就行。

然后 arduino 中的对应代码如下:

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

// LED连接的GPIO引脚
const int ledPin = 4;  

// WiFi settings
const char *ssid = "CMCC-test";             // Replace with your WiFi name
const char *password = "12345678";   // Replace with your WiFi password

// MQTT Broker settings
const char *mqtt_broker = "fef.ala.cn-hangzhou.emqxsl.cn";  // EMQX broker endpoint
const char *mqtt_topic = "fef/light";     // MQTT topic  此为主题, 其它客户端订阅请使用 "env/#"
const char *mqtt_username = "fef";  // MQTT username for authentication
const char *mqtt_password = "fef123456";  // MQTT password for authentication
const int mqtt_port = 8883;  // MQTT port (TLS)

// WiFi and MQTT client initialization
WiFiClientSecure espClient;
PubSubClient mqtt_client(espClient);

// SSL certificate for MQTT broker
static const char ca_cert[]
PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQufeffewfv wewgb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMefEFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHfVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmwefrecKCfUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfewfv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
)EOF";

// Function declarations
void connectToWiFi();

void connectToMQTT();

void mqttCallback(char *topic, byte *payload, unsigned int length);

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
  connectToWiFi();
  mqtt_client.setServer(mqtt_broker, mqtt_port);
  mqtt_client.setCallback(mqttCallback);
  connectToMQTT();
}

void connectToWiFi() {
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Connecting to WiFi...");
    }
    Serial.println("Connected to WiFi");
}

void connectToMQTT() {
    espClient.setCACert(ca_cert);
    while (!mqtt_client.connected()) {
        String client_id = "esp32-client-" + String(WiFi.macAddress());
        Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str());
        if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Connected to MQTT broker");
            mqtt_client.subscribe(mqtt_topic);
            // Publish message upon successful connection
            mqtt_client.publish(mqtt_topic, "Hi EMQX I'm ESP32 ^^");
        } else {
            // espClient.getLastSSLError(err_buf, sizeof(err_buf));
            Serial.print("Failed to connect to MQTT broker, rc=");
            Serial.println(mqtt_client.state());
            delay(5000);
        }
    }
}

void  mqttCallback(char* topic, byte* payload, unsigned int length) {  
  // 注意:这里我们将 topic 的类型也改为了 char*,因为 MQTT 主题本质上是字符串  
  // 如果你的 PubSubClient 库版本中的 topic 是 const char*,那么你应该保持原样  
  
  // 将 byte* 转换为 char* 并创建一个 String 对象  
  char payloadStr[length + 1]; // 分配一个字符数组,+1 用于存放 null 结尾符  
  memcpy(payloadStr, payload, length); // 复制 payload 数据到字符数组  
  payloadStr[length] = '\0'; // 添加 null 结尾符  
  
  String message(payloadStr); // 现在可以安全地创建一个 String 对象  
  
  // 接下来,你可以使用 message 变量了  
  Serial.print("Message arrived [");  
  Serial.print(topic);  
  Serial.print("] ");  
  Serial.println(message);  
  
  // 根据消息内容控制 LED  
  if (message == "on") {  
    digitalWrite(ledPin, HIGH);  
  } else if (message == "off") {  
    digitalWrite(ledPin, LOW);  
  }  
}

void loop() {
  // put your main code here, to run repeatedly:
    if (!mqtt_client.connected()) {
        connectToMQTT();
    }
    mqtt_client.loop();
}

手机中使用一个可以支持 MQTT的客户端,订阅到这个代码中写好的 broker 以及 topic,然后创建 widget,发送 on 或者 off 字符串,就能实现对台灯的开关。实际效果如下,感觉不到延迟:

最后修改:2024 年 08 月 04 日
请大力赞赏以支持本站持续运行!