当前位置:   article > 正文

《ESP8266 学习笔记》 TCP实践 之两个ESP8266通过TCP发送Json数据包并进行解析!_tcp传输json包

tcp传输json包

目录

1.简介:

2.硬件:

3.开发平台:

4.需要的库:

5.实验代码:

5.1 TCPClient端(负责JSON接收及解析):

5.2 TCPServer端(负责JSON打包及发送):

6.实验效果:


1.简介:

2019年夏季的全国大学生电子设计大赛中,我们组选择了电磁炮这个题目, 并且确定方案为STM32+OPENMV4(串口通讯),但当时苦于没有一个好的通信协议(毕竟当时还是小白~),只能选择了按位读取的办法,但在玩ESP8266这么久后突然想到各种物联网接入貌似都是用JSON来传输数据的,于是我便想到用各种方式来发送JSON数据(TCP、串口、IIC、UDP、各种你能想到的通信方式~),我们只需要解决Json的数据解析工作即可,令人高兴的是,Arduino方面我们有ArduinoJson库,STM32方面keil5也提供了官方的JSON库——Jansson,就算是其他单片机平台,也不要怕,我们还有开源C++编写的cJSON库,我们只需要简单移植,就可以让你的单片机使用JSON

2.硬件:

两个连接了0.96寸OLED的ESP8266开发板;

3.开发平台:

Arduino (1.8.10)     或     VScode 环境下 PlatformIO 插件

4.需要的库:

U8g2 :https://github.com/olikraus/U8g2_Arduino

ArduinoJson V5版本:https://github.com/bblanchon/ArduinoJson.git

5.实验代码:

5.1 TCPClient端(负责JSON接收及解析):

  1. /**
  2. * @功能 两块ESP8266通过TCP发送Json消息并解析
  3. * @author 刘泽文
  4. * @date 2020/4/13
  5. * @TCP Client客户端
  6. */
  7. #include <ESP8266WiFi.h>
  8. #include <ArduinoJson.h>
  9. #include <U8g2lib.h>
  10. #include <Wire.h>
  11. //以下三个定义为调试定义
  12. #define DebugBegin(baud_rate) Serial.begin(baud_rate)
  13. #define DebugPrintln(message) Serial.println(message)
  14. #define DebugPrint(message) Serial.print(message)
  15. #define DebugPrintf(message) Serial.printf(message)
  16. #define LED D4
  17. const char* ssid = "xxxxxxxx";
  18. const char* password = "xxxxxxxx";
  19. const char* Server = "192.168.31.53";
  20. const int Port = 23;
  21. short Status = 0;
  22. uint8_t apple[60];
  23. WiFiClient client;
  24. //定义OLED型号
  25. U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
  26. void setup() {
  27. DebugBegin(115200);
  28. u8g2.begin();
  29. u8g2.enableUTF8Print();
  30. u8g2.clearBuffer();
  31. u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  32. u8g2.setCursor(40, 40);
  33. u8g2.print("Json解析");
  34. u8g2.sendBuffer();
  35. pinMode(LED,OUTPUT);
  36. digitalWrite(LED,LOW);
  37. WiFi.mode(WIFI_STA);
  38. WiFi.begin(ssid, password);
  39. DebugPrint("\nConnecting to ");
  40. DebugPrintln(ssid);
  41. uint8_t i = 0;
  42. while (WiFi.status() != WL_CONNECTED && i++ < 20) {
  43. delay(500);
  44. DebugPrint(".");
  45. }
  46. if (i == 21) {
  47. DebugPrint("Could not connect to");
  48. DebugPrintln(ssid);
  49. while (1) {
  50. delay(500);
  51. }
  52. }
  53. DebugPrint("Ready! Use 'telnet ");
  54. DebugPrint(WiFi.localIP());
  55. }
  56. void loop() {
  57. if(Status==0 && WiFi.status()==WL_CONNECTED)
  58. {
  59. Status=1;
  60. client.connect(Server, Port);
  61. DebugPrint("连接到服务器~");
  62. }
  63. while(client.available()){
  64. digitalWrite(LED,!digitalRead(LED));
  65. client.read(apple,60);
  66. StaticJsonBuffer<200> jsonBuffer;
  67. JsonObject& root = jsonBuffer.parseObject(apple);
  68. if (!root.success()) {
  69. Serial.println("parseObject() failed");
  70. return;
  71. }
  72. const char* name = root["name"];
  73. int rand = root["rand"];
  74. double data = root["data"][0];
  75. u8g2.clearBuffer();
  76. u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  77. u8g2.setCursor(40, 16*1-2);
  78. u8g2.print("Json解析");
  79. u8g2.setCursor(0, 16*2-2);
  80. u8g2.print("name:");
  81. u8g2.setCursor(40, 16*2-2);
  82. u8g2.print(name);
  83. u8g2.setCursor(0, 16*3-2);
  84. u8g2.print("rand:");
  85. u8g2.setCursor(40, 16*3-2);
  86. u8g2.print(rand);
  87. u8g2.setCursor(0, 16*4-2);
  88. u8g2.print("data:");
  89. u8g2.setCursor(40, 16*4-2);
  90. u8g2.print(data);
  91. u8g2.sendBuffer();
  92. delay(200);
  93. if(!client.status()){
  94. DebugPrint("跳出循环");
  95. Status = 0;
  96. break;
  97. }
  98. }
  99. }

5.2 TCPServer端(负责JSON打包及发送):

  1. /**
  2. * @功能 两块ESP8266通过TCP发送Json消息并解析
  3. * @author 刘泽文
  4. * @date 2020/4/13
  5. * @TCP Server服务端
  6. */
  7. #include <ESP8266WiFi.h>
  8. #include <ArduinoJson.h>
  9. #include <U8g2lib.h>
  10. #include <Wire.h>
  11. //定义最多多少个client可以连接本server(一般不要超过4个)
  12. #define MAX_SRV_CLIENTS 2
  13. //以下三个定义为调试定义
  14. #define DebugBegin(baud_rate) Serial.begin(baud_rate)
  15. #define DebugPrintln(message) Serial.println(message)
  16. #define DebugPrint(message) Serial.print(message)
  17. #define DebugPrintf(message) Serial.printf(message)
  18. #define LED D4
  19. const char* ssid = "xxxxxxxx";
  20. const char* password = "xxxxxxxx";
  21. //创建server 端口号是23
  22. WiFiServer server(23);
  23. //管理clients
  24. WiFiClient serverClients[MAX_SRV_CLIENTS];
  25. //定义OLED型号
  26. U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
  27. long pushtime = 0;
  28. void setup() {
  29. DebugBegin(115200);
  30. u8g2.begin();
  31. u8g2.enableUTF8Print();
  32. u8g2.clearBuffer();
  33. u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  34. u8g2.setCursor(40, 40);
  35. u8g2.print("Json发送");
  36. u8g2.sendBuffer();
  37. pinMode(LED,OUTPUT);
  38. digitalWrite(LED,LOW);
  39. WiFi.mode(WIFI_STA);
  40. WiFi.begin(ssid, password);
  41. DebugPrint("\nConnecting to ");
  42. DebugPrintln(ssid);
  43. uint8_t i = 0;
  44. while (WiFi.status() != WL_CONNECTED && i++ < 30) {
  45. digitalWrite(LED,!digitalRead(LED));
  46. DebugPrint(".");
  47. delay(500);
  48. }
  49. if (i == 21) {
  50. DebugPrint("Could not connect to");
  51. DebugPrintln(ssid);
  52. while (1) {
  53. delay(500);
  54. }
  55. }
  56. //启动server
  57. server.begin();
  58. //关闭小包合并包功能,不会延时发送数据
  59. server.setNoDelay(true);
  60. DebugPrint("Ready! Use 'telnet ");
  61. DebugPrint(WiFi.localIP());
  62. DebugPrintln(" 23' to connect");
  63. pushtime = millis();
  64. }
  65. void loop() {
  66. uint8_t i;
  67. //检测是否有新的client请求进来
  68. if (server.hasClient()) {
  69. for (i = 0; i < MAX_SRV_CLIENTS; i++) {
  70. //释放旧无效或者断开的client
  71. if (!serverClients[i] || !serverClients[i].connected()) {
  72. if (serverClients[i]) {
  73. serverClients[i].stop();
  74. }
  75. //分配最新的client
  76. serverClients[i] = server.available();
  77. DebugPrint("New client: ");
  78. DebugPrint(i);
  79. break;
  80. }
  81. }
  82. //当达到最大连接数 无法释放无效的client,需要拒绝连接
  83. if (i == MAX_SRV_CLIENTS) {
  84. WiFiClient serverClient = server.available();
  85. serverClient.stop();
  86. DebugPrintln("Connection rejected ");
  87. }
  88. }
  89. //检测client发过来的数据
  90. for (i = 0; i < MAX_SRV_CLIENTS; i++) {
  91. if (serverClients[i] && serverClients[i].connected()) {
  92. if (serverClients[i].available()) {
  93. //get data from the telnet client and push it to the UART
  94. while (serverClients[i].available()) {
  95. //发送到串口调试器
  96. Serial.write(serverClients[i].read());
  97. }
  98. }
  99. }
  100. }
  101. if (Serial.available()) {
  102. //把串口调试器发过来的数据 发送给client
  103. size_t len = Serial.available();
  104. uint8_t sbuf[len];
  105. Serial.readBytes(sbuf, len);
  106. //给每个Client客户端发送数据
  107. for (i = 0; i < MAX_SRV_CLIENTS; i++) {
  108. if (serverClients[i] && serverClients[i].connected()) {
  109. serverClients[i].write(sbuf, len);
  110. delay(1);
  111. }
  112. }
  113. }
  114. if(millis()-pushtime >= 500){
  115. digitalWrite(LED,!digitalRead(LED));
  116. pushtime = millis();
  117. int num = rand() % 130;
  118. // Json对象对象树的内存工具 静态buffer
  119. // 200 是大小 如果这个Json对象更加复杂,那么就需要根据需要去增加这个值.
  120. StaticJsonBuffer<256> jsonBuffer;
  121. char json[60];
  122. // StaticJsonBuffer 在栈区分配内存 它也可以被 DynamicJsonBuffer(内存在堆区分配) 代替
  123. // DynamicJsonBuffer jsonBuffer;
  124. //创建最外层的json对象 —— root对象,顶节点
  125. JsonObject& root = jsonBuffer.createObject();
  126. //给最外层json对象添加属性
  127. root["name"] = "liuzewen";
  128. root["rand"] = num;
  129. //在root对象中加入data数组
  130. JsonArray& data = root.createNestedArray("data");
  131. data.add(48.756080);
  132. data.add(2.302038);
  133. //root.printTo(server);
  134. //root.printTo(serverClients[0]);
  135. root.printTo(Serial);
  136. DebugPrintln();
  137. u8g2.clearBuffer();
  138. u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  139. u8g2.setCursor(40, 16*1-2);
  140. u8g2.print("Json发送");
  141. u8g2.setCursor(0, 16*2-2);
  142. u8g2.print("name:");
  143. u8g2.setCursor(40, 16*2-2);
  144. u8g2.print("liuzewen");
  145. u8g2.setCursor(0, 16*3-2);
  146. u8g2.print("rand:");
  147. u8g2.setCursor(40, 16*3-2);
  148. u8g2.print(num);
  149. u8g2.setCursor(0, 16*4-2);
  150. u8g2.print("date:");
  151. u8g2.setCursor(40, 16*4-2);
  152. u8g2.print("48.756080");
  153. u8g2.sendBuffer();
  154. sprintf(json, "{\"name\":\"liuzewen\",\"rand\":%d,\"data\":[48.756080,2.302038]}",num);
  155. int len = sizeof(json);
  156. //Serial.printf("缓存大小是:%d",sizeof("{\"name\":\"liuzewen\",\"rand\":200,\"data\":[48.756080,2.302038]}"));
  157. //给每个Client客户端发送数据
  158. for (i = 0; i < MAX_SRV_CLIENTS; i++) {
  159. if (serverClients[i] && serverClients[i].connected()) {
  160. serverClients[i].write(json, len);
  161. //root.printTo(serverClients[i]);
  162. delay(1);
  163. }
  164. }
  165. }
  166. }

6.实验效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/522921
推荐阅读
相关标签
  

闽ICP备14008679号