ESP8266智能家居(3)——单片机数据发送到mqtt服务器

1.主要思想

前期已学习如何用ESP8266连接WIFI,并发送数据到服务器。现在只需要在单片机与nodeMCU之间建立起串口通信,这样单片机就可以将传感器测到的数据:光照,温度,湿度等等传递给8266了,然后8266再对数据进行打包,发送到服务器。

51单片机和nodeMCU的连线方式如下

它们串口的两根线交叉连接,二者的USB供电端一起接在电脑的USB口上。如果它们不是用的同一套供电系统,就需要注意共地的问题!

2.代码设计

51单片机的主体代码大致如下;

主要就是测量一些数据,然后通过串口发送到nodeMCU

nodeMCU的代码如下:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
const char* ssid = "iPhone";          //WIFI名称   自己补上你的WIFI
const char* password = "12345678";      //WIFI密码    自己补上你的密码
const char* mqtt_server = "broker-cn.emqx.io";      //mqtt服务器地址 (IP/域名)  不改
const char *pubTopic="my_pubtopic";
const char *subTopic="my_subtopic";


WiFiClient espClient;
PubSubClient client(espClient);

char information[80]="";
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  String cmd="";
  for (int i = 0; i < length; i++) {
    cmd+=(char)payload[i];
  }
  const size_t capacity = JSON_OBJECT_SIZE(1) + 10;   //计算buffer的大小   ...SIZE(1)表明buffer中只有一个对象
  DynamicJsonBuffer jsonBuffer(capacity);           //创建动态的jsonbuffer
 JsonObject& root = jsonBuffer.parseObject(cmd);     //解析Json对象字符串
 Serial.println("get");
 if(root.containsKey("led"))      //判断是否包含某个键
 {
  int led = root["led"]; 
  if(led==1)
  {
     Serial.println("1");
   }
  else
    Serial.println("2");
 }
 if(root.containsKey("beep"))      //判断是否包含某个键
 {
  int beep = root["beep"]; 
  if(beep==1)
  {
     Serial.println("3");
   }
  else
    Serial.println("4");
 }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(pubTopic, "hello world");
      // ... and resubscribe
      client.subscribe(subTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}



void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  value=0;
  while(!Serial.available());    //等待数据传送过来,若没有数据,一直等待,即执行到本行不向下执行
  while(Serial.available())
  {    
    information[value]=(char)Serial.read();  
    value++;  
    delay(3);
  }
    client.publish(pubTopic, information); 
    Serial.print(information);
 // }
}

3.注意实现

51单片机发送给nodeMCU的数据,全部存在了这个数组里面

所以这个数组要足够大,至少要大于你发送的内容。不然就会导致nodeMCU出现堆栈溢出的错误。(本人在这里卡了好几个小时) 希望大家可以避免类似的错误

在nodeMCU将数据发送到服务器的同时,可以使用nodeMCU的串口,将数据打印出来,方便调试,看看是否正确的接收到了数据。如下图所示,这种是正确接收的效果。

如果通信出现错误,没有准确接收,那么它会显示一群乱码,根本看不清楚是什么!!!

如果你发现你接收到的数据总是不准确,或者总是有乱码,可以尝试调整这个延时时间

4.最终效果

如上图所示,服务器已经可以成功接收到单片机发送的数据了!!!

此时,只需要开发一个MQTT协议的手机APP,就可以实现单片机数据在手机上显示的效果!

相关推荐
lihuhelihu1 小时前
第3章 CentOS系统管理
linux·运维·服务器·计算机网络·ubuntu·centos·云计算
山东布谷科技官方1 小时前
布谷直播源码部署服务器关于数据库配置的详细说明
运维·服务器·数据库·直播系统源码·直播源码·直播系统搭建·直播软件开发
爱吃喵的鲤鱼1 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
scan12 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu012 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
荒Huang2 小时前
Linux挖矿病毒(kswapd0进程使cpu爆满)
linux·运维·服务器
九河云3 小时前
如何选择适合的AWS EC2实例类型
服务器·云计算·aws
深圳市青牛科技实业有限公司4 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
其乐无涯4 小时前
服务器技术(一)--Linux基础入门
linux·运维·服务器
写bug的小屁孩4 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3