物联那点事儿之nodemcu连接emqx自建服务器(arduino+esp8266)

本文档详细介绍了如何使用 Arduino 的 ESP8266 模块连接自建的 EMQX MQTT 服务器进行物联网通信。内容包括硬件准备、连接 WiFi 和 MQTT 服务器、数据上行与下行处理,以及代码实现。通过这个教程,读者可以了解如何构建自己的物联网平台,并实现设备的远程控制。
摘要由CSDN通过智能技术生成

前言

之前总是没时间整理这一部分的内容,现在抽空整理一下arduino使用esp8266连接自己搭建的emqx服务器的内容吧!关于如何自建emqx服务器,可以自己百度百度,抽空我再整理一下如何连接emqx服务器!敬请期待。
为什么要连接emqx呢?优点如下:
(1)大部分的物联网平台对设备连接数量或者消息转发数量是有限制的,比如blinker是设备连接有限,而阿里云IOT平台的消息转发数量有限,还收到阿里云IOT的很多限制。那不如尝试一下自己购买一个云服务器,然后搭建一个自己的emqx服务器!
(2)自己搭建一个物联网服务器不酷吗?

硬件准备

  • nodemcu 开发板一块! 当然也可以使用esp01!用做联网。
  • DHT11温湿度传感器(其他传感器也可以),数据上行。
  • WIFI继电器一个(不用继电器用LED灯也可以),数据下行。
  • 其他硬件若干。

硬件连线

nodemcu系统外设
D7DHT11
D0LED1
D5LED2
D10继电器 (LED3)

硬件程序

说明:由于时间原因,该代码没有使用smartConfig技术一键配网,感兴趣的同学可以尝试修改连接wifi部分的代码!

(1)首先必不可少头文件,老规矩,一定要把需要用到的第三方头文件放到文档->arduino->libraries下,否则程序源码读不到该头文件的内容, 白费了就!具体的头文件这里就不再给出。

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
//系统外设
#include <DHT.h>//包含DHT头文件

(2)宏定义,为了方便一些引脚编号和变量的后期修改!

#define DHTPIN 13 //D7
#define LED1   16 //D0
#define LED2   14 //D5
#define jidianqi 1  //D10

#define DHTTYPE DHT11   // 使用温度湿度模块的类型为DHT11
#define wifi_ssid "*****"   //wifi名称
#define wifi_password "******" //wifi密码
#define mqtt_server "changyuan.store"  // EMQX服务器的域名
#define publish_topic "/client2/pub"   //发布消息主题
#define subscribe_topic "/client2/sub"  //订阅消息的主题

(3)连接emqx服务器的最首先也是需要连接wifi的,这里不再描述smartConfig一键配网,如果有用安信可一键配网的同学,最好把手机热点的AP频段设置为2.4HZ,目前不支持5GHZ。

void setup_wifi() {
    delay(10);
    WiFi.begin(wifi_ssid, wifi_password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print("."); 
    }
}

(4)连接emqx服务器首先需要自己的emqx服务器的域名,mqtt_server为自己的域名,一定要连接1883端口,这是emqx默认的端口号,其他端口无效。

 client.setServer(mqtt_server, 1883);

(5)上行数据的上报。数据上行数据的上报一般是上报JSON字符串类型的数据,通过JSON字符串的拼接,代码如下所示。其中sprintf函数可以理解为printf()函数,功能差不多吧,然后通过publish函数上报主题消息。


 #define BODY_FORMAT     "{\"clientId\":\"%s\",\"params\":{\"humi\":\"%d\",\"temp\":\"%d\"}}"
 char jsonBuf[128];//存放payload主题内容
 sprintf(jsonBuf,BODY_FORMAT,clientId.c_str(),humiData,tempData);
 client.publish(publish_topic, jsonBuf);

(6)下行数据的解析。下行数据的解析首先是订阅服务器下发的主题信息,然后客户端监听服务器下发的消息,最后是解析下发消息并做出响应的动作。其中解析JSON的方式和python中键值对的取值方法又差不多。

 client.subscribe(subscribe_topic); //订阅主题
 client.setCallback(callback); //监听服务器下发的消息 
 DynamicJsonBuffer jsonBuffer;
 JsonObject& root = jsonBuffer.parseObject(message);
 String LED1State = root["LED1"];
 String LED2State = root["LED2"];
 String LED3State = root["LED3"];

(7)代码总结!全部代码可以参考如下代码。可包毕设,有意者联系。

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
//系统外设
#include <DHT.h>//包含DHT头文件
#define DHTPIN 13 //D7
#define LED1   16 //D0
#define LED2   14 //D5
#define jidianqi 1  //D10

#define DHTTYPE DHT11   // 使用温度湿度模块的类型为DHT11
DHT dht(DHTPIN, DHTTYPE);    //定义dht

#define wifi_ssid "*****"   //wifi名称
#define wifi_password "******" //wifi密码
#define mqtt_server "changyuan.store"  // EMQX服务器的域名
#define publish_topic "/client2/pub"   //发布消息主题
#define subscribe_topic "/client2/sub"  //订阅消息的主题

#define BODY_FORMAT     "{\"clientId\":\"%s\",\"params\":{\"humi\":\"%d\",\"temp\":\"%d\"}}"
WiFiClient espClient;
PubSubClient client(espClient);
String  clientId="client2";
int  tempData;
int  humiData;
String state;

void setup() { 
  Serial.begin(115200);
  dht.begin();//初始化DHT传感器
  pinMode(jidianqi, OUTPUT);//定义io口为输出
   digitalWrite(jidianqi,HIGH);
   pinMode(LED2, OUTPUT);//定义io口为输出
   digitalWrite(LED2,HIGH);
   pinMode(LED1, OUTPUT);//定义io口为输出
   digitalWrite(LED1,HIGH);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback); //监听服务器下发的消息
}
void loop() { 
   if (!client.connected()) {
        reconnect();
    }
    else{ 
      DHTWORK();
      Serial.print("温度:");
      Serial.print(tempData);
      Serial.print(",湿度:");
      Serial.print(humiData);
      char jsonBuf[128];//存放payload主题内容
      sprintf(jsonBuf,BODY_FORMAT,clientId.c_str(),humiData,tempData,lux,state.c_str());
      client.publish(publish_topic, jsonBuf);
      client.subscribe(subscribe_topic);
  }
  client.loop();
  delay(1000);
}
void setup_wifi() {
    delay(10);
    WiFi.begin(wifi_ssid, wifi_password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print("."); 
    }
}
void DHTWORK(){
   float h = dht.readHumidity();//读取DHT11传感器的湿度 并赋值给h
    float t = dht.readTemperature();//读取传感器的温度   并赋值给t
    if (isnan(h) || isnan(t))//判断是否成功读取到温湿度数据
    {
        Serial.println("error");
    }else{
      tempData=(int)t;
      humiData=(int)h;
     }
}
void reconnect() {
    // Loop until we're reconnected
    while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        if (client.connect("nodeMcuRFID")) {
            Serial.println("connected");
        } else {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
        }
    }
}
void callback(char *topic, byte *payload, unsigned int length) {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    Serial.print("Message:");
    String message;
    for (int i = 0; i < length; i++) {
        message = message + (char) payload[i];  // convert *byte to string
    }
    Serial.print(message);
    //解析json
    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.parseObject(message);
    String LED1State = root["LED1"];
    String LED2State = root["LED2"];
    String LED3State = root["LED3"];
    if(LED1State=="true")
    {
      //读取
      int button1Sate = digitalRead(LED1);
      if(button1Sate==1)//高电平置为低
      {
       digitalWrite(LED1,HIGH);
       delay(200);
       digitalWrite(LED1, LOW);
       }else{//低电平置为高
       digitalWrite(LED1,LOW);
       delay(200);
       digitalWrite(LED1,HIGH);
    }    
    }
    if(LED2State=="true")
    {
      //读取
      int button2Sate = digitalRead(LED2);
      if(button2Sate==1)//高电平置为低
      {
       digitalWrite(LED2,HIGH);
       delay(200);
       digitalWrite(LED2, LOW);
       }else{//低电平置为高
       digitalWrite(LED2,LOW);
       delay(200);
       digitalWrite(LED2,HIGH);
       }    
    }
    if(LED3State=="true")
    {
      //读取
      int button3Sate = digitalRead(jidianqi);
      if(button3Sate==1)//高电平置为低
      {
       digitalWrite(jidianqi,HIGH);
       delay(200);
       digitalWrite(jidianqi,LOW);
       }else{//低电平置为高
       digitalWrite(jidianqi,LOW);
       delay(200);
       digitalWrite(jidianqi,HIGH);
       }    
    }
    Serial.println(); 
}

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜大大的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值