| 
 | 
 
    接触HomeAssistant大概一周了,在论坛找到了很多教程学习。现在特发一个使用攀藤G5通过WidoraAIR(EPS32)接入HomeAssistant教程以回报论坛。 
    一、硬件介绍: 
           1.攀藤G5是一款可以同时监测空气中颗粒物浓度和甲醛浓度的二合一传感器。其中颗粒物浓度的监测基于激光散射原理,可连续采集并计算单位体积内空气中不同粒径的悬浮颗粒物个数,即颗粒物浓度分布,进而换算成为质量浓度。甲醛浓度的监测基于电化学原理,具有高精度、高稳定性的特点。颗粒物浓度数值和甲醛浓度数值合并以通用数字接口形式输出。 
              检测出来的数据通过串口发出来,波特率:9600kbps 校验位:无 停止位:1位 
攀藤数据输出格式1 
 
攀藤数据输出格式2 
 
 
        2.WidoraAIR是一款ESP32板子。把攀藤G5接到WidoraAIR第2号串口上,也就是16、17号IO口上。(16:RX,17:TX)。注意攀藤的RX接WidoraAIR的TX,攀藤的TX接WidoraAIR的RX。其实我们只要接收攀藤发送的数据,所以只接攀藤的TX到WidoraAIR的RX也是可以的。攀藤需要5V供电,这个直接接到WidoraAIR的Vin,当然别忘了共地(GND接GND) 
  二、软件部分: 
      1.HomeAssistant的配置: 
##################################### 
sensor: 
 
  - platform: mqtt 
    state_topic: 'stat/kqzl' 
    name: 'Jia Quan' 
    unit_of_measurement: 'mg/m3' 
    value_template: '{{ value_json.jiaquan }}' 
  - platform: mqtt 
    state_topic: 'stat/kqzl' 
    name: 'PM2.5' 
    unit_of_measurement: 'μg/m3' 
    value_template: '{{ value_json.pm2p5 }}' 
  - platform: mqtt 
    state_topic: 'stat/kqzl' 
    name: 'PM1.0' 
    unit_of_measurement: 'μg/m3' 
    value_template: '{{ value_json.pm1p0 }}' 
  - platform: mqtt 
    state_topic: 'stat/kqzl' 
    name: 'PM10' 
    unit_of_measurement: 'μg/m3' 
    value_template: '{{ value_json.pm10 }}' 
 
######################################## 
新手可能面对这一堆配置不能理解,下面我截取一段讲解一下: 
sensor: 
  - platform: mqtt 
    state_topic: 'stat/kqzl' 
    name: 'Jia Quan' 
    unit_of_measurement: 'mg/m3' 
    value_template: '{{ value_json.jiaquan }}' 
 
 
首先yaml格式的配置文件是严格缩进的,所以各位一定要注意各行的缩进。 
  sensor: 
    表示你配置的是传感器。不同的设备,HomeAssistant在表现它们的数据的形式上有所不同。比如说sensor,HomeAssistant显示的数值和数据曲线图;而Light则显示一个开关按钮。 
  - platform: mqtt 表示数据来源平台。这是说明数据是从mqtt协议的消息中来。我们是通过WidoraAIR将数据通过Mqtt发送出去。 
    state_topic: 'stat/kqzl'  表示这个数据状态订阅的主题(Topic),就是哪个主题的mqtt消息是这个传感器关心的。这个跟后面我们的WidoraAIR的代码是对应的。 
    name: 'Jia Quan' 表示传感器的名字,如果要显示汉字,请参考论坛的汉化相关帖子。 
    unit_of_measurement: 'mg/m3'  表示传感器数据的单位。注意相同单位的数据会在“历史”页面显示在同一个曲线表格中,用颜色区分。 
    value_template: '{{ value_json.jiaquan }}'  表示HomeAssistant怎么从mqtt消息中获取数据。我们发送给HomeAssistant的消息看起来像这样子的:{"jiaquan": 22.30,"pm2p5" : 43.70,"pm1p0" : 43.70,"pm10" : 43.70},这里表示获取消息里面的jiaquan这项数据。 
    2.WidoraAIR的代码。 
        开发平台:Arduino core for ESP32 WiFi chip (https://github.com/espressif/arduino-esp32) 
        使用到的库:pubsubclient(https://github.com/knolleary/pubsubclient)  
                            下载地址:https://github.com/knolleary/pubsubclient/archive/v2.6.zip 
        下面贴出代码: 
 
/*ESP32做了两件事: 
1/ 从攀藤G5读取数据 
2/ 通过Mqtt传出数据 
*/ 
 
#include <WiFi.h> 
#include <PubSubClient.h> 
 
/* 改成你自己的wifi信息 */ 
const char* ssid = "muhome2g"; 
const char* password = "KuangShan3"; 
/* 你的MQTT Server地址*/ 
const char* mqtt_server = "192.168.1.151"; 
 
WiFiClient espClient; 
PubSubClient client(espClient); 
 
/*LED GPIO pin*/ 
const char led = 25; 
 
/* topics */ 
#define TOPICMD  "cmnd/light/l1/power" 
#define TOPICST  "stat/light/l1/power" 
#define TOPICKQ  "stat/kqzl"//这就是刚刚给大家说的HomeAssistant订阅的Topic 
 
long lastMsg = 0; 
char msg[80]; 
u8_t timecount = 0;; 
 
HardwareSerial Serial1(2); 
 
int dataSum = 0; 
 
//攀藤G5的数据格式 
struct _panteng { 
        unsigned char len[2]; 
        unsigned char pm1_cf1[2]; 
        unsigned char pm2_5_cf1[2]; 
        unsigned char pm10_0_cf1[2]; 
        unsigned char pm1_0[2]; 
        unsigned char pm2_5[2]; 
        unsigned char pm10_0[2]; 
        unsigned char pml0_3[2]; 
        unsigned char pml0_5[2]; 
        unsigned char pml1_0[2]; 
        unsigned char pml2_5[2]; 
        unsigned char pml5[2]; 
        unsigned char pml10[2]; 
        unsigned char jq[2]; 
        unsigned char check[2]; 
} panteng; 
int pm1_0, pm2_5, pm10_0, jq;        //PM1.0、PM2.5、PM10 
 
//#define DEBUG 
 
void receivedCallback(char* topic, byte* payload, unsigned int length) { 
        Serial.print("Message received: "); 
        Serial.println(topic); 
 
        Serial.print("payload: "); 
        for (int i = 0; i < length; i++) { 
                Serial.print((char)payload); 
        } 
        Serial.println(); 
        if (length > 1) 
  { 
    if ((char)payload[1] == 'N') { 
      Serial.println("Light ON"); 
      digitalWrite(led, HIGH); 
      client.publish(TOPICST, "ON"); 
    } 
    else { 
      digitalWrite(led, LOW); 
      Serial.println("Light OFF"); 
      client.publish(TOPICST, "OFF"); 
    } 
  } 
 
} 
 
void mqttconnect() { 
        /* Loop until reconnected */ 
        while (!client.connected()) { 
                Serial.print("MQTT connecting ..."); 
                /* client ID */ 
                String clientId = "ESP32Client"; 
                /* connect now */ 
                if (client.connect(clientId.c_str())) { 
                        Serial.println("connected"); 
                        /* subscribe topic with default QoS 0*/ 
                        client.subscribe(TOPICMD); 
                } 
                else { 
                        Serial.print("failed, status code ="); 
                        Serial.print(client.state()); 
                        Serial.println("try again in 5 seconds"); 
                        /* Wait 5 seconds before retrying */ 
                        delay(5000); 
                } 
        } 
} 
 
void setup() { 
        Serial1.begin(9600); 
        Serial.begin(115200); 
        // We start by connecting to a WiFi network 
        Serial.println(); 
        Serial.print("Connecting to "); 
        Serial.println(ssid); 
 
        WiFi.begin(ssid, password); 
 
        while (WiFi.status() != WL_CONNECTED) { 
                delay(500); 
                Serial.print("."); 
        } 
        /* set led as output to control led on-off */ 
        pinMode(led, OUTPUT); 
 
        Serial.println(""); 
        Serial.println("WiFi connected"); 
        Serial.println("IP address: "); 
        Serial.println(WiFi.localIP()); 
 
        /* configure the MQTT server with IPaddress and port */ 
        client.setServer(mqtt_server, 1883); 
        /* this receivedCallback function will be invoked 
        when client received subscribed topic */ 
        client.setCallback(receivedCallback); 
} 
void loop() { 
        /* if client was disconnected then try to reconnect again */ 
        if (!client.connected()) { 
                mqttconnect(); 
        } 
        /* this function will listen for incomming 
        subscribed topic-process-invoke receivedCallback */ 
        client.loop(); 
        //读取攀藤G5 数据 
        byte c; 
        char str[100]; 
        static int state = 0; 
        static int count = 0; 
        if (Serial1.available()) { 
                c = Serial1.read(); 
                dataSum += c; 
                switch (state) { 
                case 0: 
                        if (0x42 == c) 
                        { 
                                state = 1; 
                                dataSum = 0; 
                        } 
                        break; 
                case 1: 
                        if (0x4d == c) { 
                                state = 2; 
                                count = 0; 
                        } 
                        break; 
                case 2: 
                        ((unsigned char *)&panteng)[count++] = c; 
 
                        if (count > 30) { 
#ifdef DEBUG 
                                Serial.println(dataSum - panteng.check[0] - panteng.check[1], HEX); 
                                Serial.println(panteng.check[0] * 256 + panteng.check[1], HEX); 
 
#endif 
 
                                state = 0; 
                                if ((dataSum - panteng.check[0] - panteng.check[1]) == (panteng.check[0] * 256 + panteng.check[1])) 
                                { 
#ifdef DEBUG 
                                        Serial.println("Data check ok"); 
                                        //计数 采集5次穿一次 也就是5s                         
#endif 
                                        timecount++; 
                                        pm1_0 = panteng.pm1_0[0] * 256 + panteng.pm1_0[1]; 
                                        pm2_5 = panteng.pm2_5[0] * 256 + panteng.pm2_5[1]; 
                                        pm10_0 = panteng.pm10_0[0] * 256 + panteng.pm10_0[1]; 
                                        jq = panteng.jq[0] * 256 + panteng.jq[1]; 
 
                                        if (timecount > 60) 
                                        { 
                                                timecount = 0; 
                                                //发送空气信息mqtt 
                                                //{ 
                                                //        "jiaquan": 22.30, 
                                                //                "pm2p5" : 43.70, 
                                                //                "pm1p0" : 43.70, 
                                                //                "pm10" : 43.70 
                                                //} 
                                                //{"jiaquan": 22.30,"pm2p5" : 43.70,"pm1p0" : 43.70,"pm10" : 43.70} 
                                                sprintf(msg, "{\"jiaquan\":%d,\"pm2p5\":%d,\"pm1p0\":%d,\"pm10\":%d}",jq,pm2_5,pm1_0,pm10_0); 
                                                Serial.println(msg); 
                                                client.publish(TOPICKQ, msg); 
                                        } 
#ifdef DEBUG 
                                        Serial.print("jq:"); 
                                        Serial.println(jq); 
                                        Serial.print("pm2.5:"); 
                                        Serial.println(pm2_5); 
#endif 
                                } 
                        } 
                        break; 
                default: 
                        break; 
                } 
        } 
} 
 
为了方便大家使用 把代码传附件
 
esp32MqttTest.zip
(2.1 KB, 下载次数: 63)
 
 
最后放出效果图: 
效果1 
 
效果2 
 
效果3 
 
 
 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |