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


    1.主要思想

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

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

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

    2.代码设计

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

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

     nodeMCU的代码如下:

    1. #include <ESP8266WiFi.h>
    2. #include <PubSubClient.h>
    3. #include <ArduinoJson.h>
    4. const char* ssid = "iPhone"; //WIFI名称 自己补上你的WIFI
    5. const char* password = "12345678"; //WIFI密码 自己补上你的密码
    6. const char* mqtt_server = "broker-cn.emqx.io"; //mqtt服务器地址 (IP/域名) 不改
    7. const char *pubTopic="my_pubtopic";
    8. const char *subTopic="my_subtopic";
    9. WiFiClient espClient;
    10. PubSubClient client(espClient);
    11. char information[80]="";
    12. int value = 0;
    13. void setup_wifi() {
    14. delay(10);
    15. // We start by connecting to a WiFi network
    16. Serial.println();
    17. Serial.print("Connecting to ");
    18. Serial.println(ssid);
    19. WiFi.mode(WIFI_STA);
    20. WiFi.begin(ssid, password);
    21. while (WiFi.status() != WL_CONNECTED) {
    22. delay(500);
    23. Serial.print(".");
    24. }
    25. randomSeed(micros());
    26. Serial.println("");
    27. Serial.println("WiFi connected");
    28. Serial.println("IP address: ");
    29. Serial.println(WiFi.localIP());
    30. }
    31. void callback(char* topic, byte* payload, unsigned int length) {
    32. String cmd="";
    33. for (int i = 0; i < length; i++) {
    34. cmd+=(char)payload[i];
    35. }
    36. const size_t capacity = JSON_OBJECT_SIZE(1) + 10; //计算buffer的大小 ...SIZE1)表明buffer中只有一个对象
    37. DynamicJsonBuffer jsonBuffer(capacity); //创建动态的jsonbuffer
    38. JsonObject& root = jsonBuffer.parseObject(cmd); //解析Json对象字符串
    39. Serial.println("get");
    40. if(root.containsKey("led")) //判断是否包含某个键
    41. {
    42. int led = root["led"];
    43. if(led==1)
    44. {
    45. Serial.println("1");
    46. }
    47. else
    48. Serial.println("2");
    49. }
    50. if(root.containsKey("beep")) //判断是否包含某个键
    51. {
    52. int beep = root["beep"];
    53. if(beep==1)
    54. {
    55. Serial.println("3");
    56. }
    57. else
    58. Serial.println("4");
    59. }
    60. }
    61. void reconnect() {
    62. // Loop until we're reconnected
    63. while (!client.connected()) {
    64. Serial.print("Attempting MQTT connection...");
    65. // Create a random client ID
    66. String clientId = "ESP8266Client-";
    67. clientId += String(random(0xffff), HEX);
    68. // Attempt to connect
    69. if (client.connect(clientId.c_str())) {
    70. Serial.println("connected");
    71. // Once connected, publish an announcement...
    72. client.publish(pubTopic, "hello world");
    73. // ... and resubscribe
    74. client.subscribe(subTopic);
    75. } else {
    76. Serial.print("failed, rc=");
    77. Serial.print(client.state());
    78. Serial.println(" try again in 5 seconds");
    79. // Wait 5 seconds before retrying
    80. delay(5000);
    81. }
    82. }
    83. }
    84. void setup() {
    85. Serial.begin(9600);
    86. setup_wifi();
    87. client.setServer(mqtt_server, 1883);
    88. client.setCallback(callback);
    89. }
    90. void loop() {
    91. if (!client.connected()) {
    92. reconnect();
    93. }
    94. client.loop();
    95. value=0;
    96. while(!Serial.available()); //等待数据传送过来,若没有数据,一直等待,即执行到本行不向下执行
    97. while(Serial.available())
    98. {
    99. information[value]=(char)Serial.read();
    100. value++;
    101. delay(3);
    102. }
    103. client.publish(pubTopic, information);
    104. Serial.print(information);
    105. // }
    106. }

    3.注意实现

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

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

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

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

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

    4.最终效果 

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

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

  • 相关阅读:
    Collections.addAll()和list.addAll()不同之处说明
    带头双向循环链表的增删查改(C语言实现)
    极智AI | 图像处理中对掩膜 mask 和 ROI 的理解
    三个“清洁代码”技巧将使您的开发团队效率提高 50%
    AotuDL中Linux环境下运行pix2pix-tensorflow的环境配置(tensorflow==1.8.0 python==3.6)
    嵌入式开发:使用Doxygen记录嵌入式代码的7个技巧
    十几年稳坐“大哥”位,搞Java的程序员就是这么“牛x”!
    Python的2042小游戏及其详解
    Win11系统设置自动关机的方法分享
    使用mod_rewrite时常用的服务器变量: RewriteRule规则表达式的说明:
  • 原文地址:https://blog.csdn.net/guangali/article/details/136245154