237|0

132

帖子

2

TA的资源

一粒金砂(高级)

【Follow me第二季第2期】+ 进阶任务 :通过Wi-Fi,利用MQTT协议接入HA [复制链接]

本帖最后由 御坂10032号 于 2024-9-8 18:39 编辑

前言

 

        在前两章我们已经学习到了如何基础的使用R4, 那么本章节我们将学习一下如何使用R4的 Wifi功能将R4接入HA

 

正文

    

    在我们开始之前我希望你已经在部署好了以下服务(无论本地或者云端)。

       1-  HomeAssistant

       2-  MQTT服务

 

我的这两个服务是跑的本地的一块99元的香橙派上的,如下是容器示例

 

image.png  

通过8123端口我们可以正确的访问到HomeAssistant的管理端

 

image.png  

同时进行MQTT连接测试

image.png  

前置工作已经准备好了,那么现在我们就可以开始我们的任务了。 那么这个任务一共分为以下两点

        1- 连接WIFI

        2- 连接MQTT并且发送消息

 

对于WIFI的连接比较简单, 我们可以参考S3的wifi连接示例,如下所示

 

image.png  

 

我们仅仅需要的是代码中的 ssid 和 pass (我这里尝试连接5G的信号失败, 正常的2.4G没问题)

 

代码如下所示

#include <WiFiS3.h>

char ssid[] = "ImmortalWrt";        
char pass[] = "mazha1997";  
int status = WL_IDLE_STATUS;   


void setup() {
  Serial.begin(9600);
  while (!Serial) {

  }

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();


}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}



void loop() {

}


 

我们将代码烧录到开发板之后呢,打开串口助手便可以看到正确的控制台输出

 

image.png   

 

现在我们便开始处理我们的第二个任务, 使用MQTT连接到HA(也就是MQTT服务器,使其HA中集成的MQTT自动发现我们的配置服务)。

 

参考Arduino的官方文档,我们得知,可以使用ArduinoMqttClient的库来连接MQTT。 我们在上述的代码上稍作修改。

 

#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>

char ssid[] = "ImmortalWrt";        
char pass[] = "mazha1997";  
int status = WL_IDLE_STATUS;   

const char broker[] = "192.168.1.113";
int        port     = 1883;
const char topic[]  = "/aht10/test";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

void setup() {
  Serial.begin(9600);
  while (!Serial) {

  }

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You are connected to MQTT");

}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}



void loop() {
    mqttClient.beginMessage(topic);
    mqttClient.print("Hello EEworld and Digikey!");
    mqttClient.endMessage();
    delay(500);
}


 

将程序烧录到开发板上后,我们打开MQTTX, 查看我们MQTT的目标主题.

 

image.png  

 

此时我们已经可以正确的接收来自Arduino发送的消息。 接下来我们要做的就是解析数据,使其HA可以根据MQTT的格式自动识别为HA中的实体。根据HA的官方文档我们得知,可以分为自动发现或者配置configuration.yml. 我这里选择是后者。同时配置了一个灯(Switch)

 

image.png  

根据上述配置文件得知,我们可以往两个主题内发送消息,从而控制HA的中实体的状态

 

1- home/bedroom/switch1 状态主题

2- home/bedroom/switch1/set 命令主题

 

当我们想要关闭灯的时候,只需要向命令主题中发送OFF即可, 如果想要开灯则发送ON. 但是尽管它已经可以正常的控制灯的开关。但是HA中实体的状态并不会发生变化。 如果想要实体的状态也发送变化的话,则需要向状态主题中也发送一个OFF

 

我们简单的修改一下代码,使其每秒切换灯的状态。

 

#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>

char ssid[] = "ImmortalWrt";        
char pass[] = "mazha1997";  
int status = WL_IDLE_STATUS;   

const char broker[] = "192.168.1.113";
int        port     = 1883;
const char command_topic[]  = "home/bedroom/switch1/set";
const char state_topic[]  = "home/bedroom/switch1";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

bool index = true;

void setup() {
  Serial.begin(9600);
  while (!Serial) {

  }

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You are connected to MQTT");

}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 0; i < 6; i++) {
    if (i > 0) {
      Serial.print(":");
    }
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}



void loop() {
  if(index)
  {
    mqttClient.beginMessage(command_topic);
    mqttClient.print("ON");
    mqttClient.endMessage();
    mqttClient.beginMessage(state_topic);
    mqttClient.print("ON");
    mqttClient.endMessage();
  }else {
    mqttClient.beginMessage(command_topic);
    mqttClient.print("OFF");
    mqttClient.endMessage();
    mqttClient.beginMessage(state_topic);
    mqttClient.print("OFF");
    mqttClient.endMessage();
  }
  index = !index;
  delay(1000);

}


实验现象如下:

 

9月8日

 

代码如下:

wifi.ino (2.9 KB, 下载次数: 3)

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表