赞
踩
目录
在2019年夏季的全国大学生电子设计大赛中,我们组选择了电磁炮这个题目, 并且确定方案为STM32+OPENMV4(串口通讯),但当时苦于没有一个好的通信协议(毕竟当时还是小白~),只能选择了按位读取的办法,但在玩ESP8266这么久后突然想到各种物联网接入貌似都是用JSON来传输数据的,于是我便想到用各种方式来发送JSON数据(TCP、串口、IIC、UDP、各种你能想到的通信方式~),我们只需要解决Json的数据解析工作即可,令人高兴的是,Arduino方面我们有ArduinoJson库,STM32方面keil5也提供了官方的JSON库——Jansson,就算是其他单片机平台,也不要怕,我们还有开源C++编写的cJSON库,我们只需要简单移植,就可以让你的单片机使用JSON。
两个连接了0.96寸OLED的ESP8266开发板;
Arduino (1.8.10) 或 VScode 环境下 PlatformIO 插件
U8g2 :https://github.com/olikraus/U8g2_Arduino
ArduinoJson V5版本:https://github.com/bblanchon/ArduinoJson.git
- /**
- * @功能 两块ESP8266通过TCP发送Json消息并解析
- * @author 刘泽文
- * @date 2020/4/13
- * @TCP Client客户端
- */
-
- #include <ESP8266WiFi.h>
- #include <ArduinoJson.h>
- #include <U8g2lib.h>
- #include <Wire.h>
-
- //以下三个定义为调试定义
- #define DebugBegin(baud_rate) Serial.begin(baud_rate)
- #define DebugPrintln(message) Serial.println(message)
- #define DebugPrint(message) Serial.print(message)
- #define DebugPrintf(message) Serial.printf(message)
-
- #define LED D4
-
- const char* ssid = "xxxxxxxx";
- const char* password = "xxxxxxxx";
-
- const char* Server = "192.168.31.53";
- const int Port = 23;
-
- short Status = 0;
- uint8_t apple[60];
- WiFiClient client;
-
- //定义OLED型号
- U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-
- void setup() {
- DebugBegin(115200);
-
- u8g2.begin();
- u8g2.enableUTF8Print();
- u8g2.clearBuffer();
- u8g2.setFont(u8g2_font_wqy16_t_gb2312);
- u8g2.setCursor(40, 40);
- u8g2.print("Json解析");
- u8g2.sendBuffer();
-
- pinMode(LED,OUTPUT);
- digitalWrite(LED,LOW);
-
- WiFi.mode(WIFI_STA);
- WiFi.begin(ssid, password);
- DebugPrint("\nConnecting to ");
- DebugPrintln(ssid);
- uint8_t i = 0;
- while (WiFi.status() != WL_CONNECTED && i++ < 20) {
- delay(500);
- DebugPrint(".");
- }
- if (i == 21) {
- DebugPrint("Could not connect to");
- DebugPrintln(ssid);
- while (1) {
- delay(500);
- }
- }
-
- DebugPrint("Ready! Use 'telnet ");
- DebugPrint(WiFi.localIP());
- }
-
- void loop() {
- if(Status==0 && WiFi.status()==WL_CONNECTED)
- {
- Status=1;
- client.connect(Server, Port);
- DebugPrint("连接到服务器~");
- }
-
- while(client.available()){
- digitalWrite(LED,!digitalRead(LED));
- client.read(apple,60);
- StaticJsonBuffer<200> jsonBuffer;
- JsonObject& root = jsonBuffer.parseObject(apple);
- if (!root.success()) {
- Serial.println("parseObject() failed");
- return;
- }
- const char* name = root["name"];
- int rand = root["rand"];
- double data = root["data"][0];
- u8g2.clearBuffer();
- u8g2.setFont(u8g2_font_wqy16_t_gb2312);
- u8g2.setCursor(40, 16*1-2);
- u8g2.print("Json解析");
- u8g2.setCursor(0, 16*2-2);
- u8g2.print("name:");
- u8g2.setCursor(40, 16*2-2);
- u8g2.print(name);
- u8g2.setCursor(0, 16*3-2);
- u8g2.print("rand:");
- u8g2.setCursor(40, 16*3-2);
- u8g2.print(rand);
- u8g2.setCursor(0, 16*4-2);
- u8g2.print("data:");
- u8g2.setCursor(40, 16*4-2);
- u8g2.print(data);
- u8g2.sendBuffer();
- delay(200);
-
- if(!client.status()){
- DebugPrint("跳出循环");
- Status = 0;
- break;
- }
- }
- }
- /**
- * @功能 两块ESP8266通过TCP发送Json消息并解析
- * @author 刘泽文
- * @date 2020/4/13
- * @TCP Server服务端
- */
- #include <ESP8266WiFi.h>
- #include <ArduinoJson.h>
- #include <U8g2lib.h>
- #include <Wire.h>
-
- //定义最多多少个client可以连接本server(一般不要超过4个)
- #define MAX_SRV_CLIENTS 2
- //以下三个定义为调试定义
- #define DebugBegin(baud_rate) Serial.begin(baud_rate)
- #define DebugPrintln(message) Serial.println(message)
- #define DebugPrint(message) Serial.print(message)
- #define DebugPrintf(message) Serial.printf(message)
-
- #define LED D4
-
- const char* ssid = "xxxxxxxx";
- const char* password = "xxxxxxxx";
-
- //创建server 端口号是23
- WiFiServer server(23);
- //管理clients
- WiFiClient serverClients[MAX_SRV_CLIENTS];
-
- //定义OLED型号
- U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
- long pushtime = 0;
-
- void setup() {
- DebugBegin(115200);
-
- u8g2.begin();
- u8g2.enableUTF8Print();
- u8g2.clearBuffer();
- u8g2.setFont(u8g2_font_wqy16_t_gb2312);
- u8g2.setCursor(40, 40);
- u8g2.print("Json发送");
- u8g2.sendBuffer();
-
- pinMode(LED,OUTPUT);
- digitalWrite(LED,LOW);
-
- WiFi.mode(WIFI_STA);
- WiFi.begin(ssid, password);
- DebugPrint("\nConnecting to ");
- DebugPrintln(ssid);
- uint8_t i = 0;
- while (WiFi.status() != WL_CONNECTED && i++ < 30) {
- digitalWrite(LED,!digitalRead(LED));
- DebugPrint(".");
- delay(500);
- }
- if (i == 21) {
- DebugPrint("Could not connect to");
- DebugPrintln(ssid);
- while (1) {
- delay(500);
- }
- }
- //启动server
- server.begin();
- //关闭小包合并包功能,不会延时发送数据
- server.setNoDelay(true);
-
- DebugPrint("Ready! Use 'telnet ");
- DebugPrint(WiFi.localIP());
- DebugPrintln(" 23' to connect");
- pushtime = millis();
- }
-
- void loop() {
- uint8_t i;
- //检测是否有新的client请求进来
- if (server.hasClient()) {
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- //释放旧无效或者断开的client
- if (!serverClients[i] || !serverClients[i].connected()) {
- if (serverClients[i]) {
- serverClients[i].stop();
- }
- //分配最新的client
- serverClients[i] = server.available();
- DebugPrint("New client: ");
- DebugPrint(i);
- break;
- }
- }
- //当达到最大连接数 无法释放无效的client,需要拒绝连接
- if (i == MAX_SRV_CLIENTS) {
- WiFiClient serverClient = server.available();
- serverClient.stop();
- DebugPrintln("Connection rejected ");
- }
- }
-
- //检测client发过来的数据
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- if (serverClients[i] && serverClients[i].connected()) {
- if (serverClients[i].available()) {
- //get data from the telnet client and push it to the UART
- while (serverClients[i].available()) {
- //发送到串口调试器
- Serial.write(serverClients[i].read());
- }
- }
- }
- }
-
- if (Serial.available()) {
- //把串口调试器发过来的数据 发送给client
- size_t len = Serial.available();
- uint8_t sbuf[len];
- Serial.readBytes(sbuf, len);
-
- //给每个Client客户端发送数据
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- if (serverClients[i] && serverClients[i].connected()) {
- serverClients[i].write(sbuf, len);
- delay(1);
- }
- }
- }
-
- if(millis()-pushtime >= 500){
- digitalWrite(LED,!digitalRead(LED));
- pushtime = millis();
- int num = rand() % 130;
- // Json对象对象树的内存工具 静态buffer
- // 200 是大小 如果这个Json对象更加复杂,那么就需要根据需要去增加这个值.
- StaticJsonBuffer<256> jsonBuffer;
- char json[60];
- // StaticJsonBuffer 在栈区分配内存 它也可以被 DynamicJsonBuffer(内存在堆区分配) 代替
- // DynamicJsonBuffer jsonBuffer;
- //创建最外层的json对象 —— root对象,顶节点
- JsonObject& root = jsonBuffer.createObject();
- //给最外层json对象添加属性
- root["name"] = "liuzewen";
- root["rand"] = num;
- //在root对象中加入data数组
- JsonArray& data = root.createNestedArray("data");
- data.add(48.756080);
- data.add(2.302038);
- //root.printTo(server);
- //root.printTo(serverClients[0]);
- root.printTo(Serial);
- DebugPrintln();
-
- u8g2.clearBuffer();
- u8g2.setFont(u8g2_font_wqy16_t_gb2312);
- u8g2.setCursor(40, 16*1-2);
- u8g2.print("Json发送");
- u8g2.setCursor(0, 16*2-2);
- u8g2.print("name:");
- u8g2.setCursor(40, 16*2-2);
- u8g2.print("liuzewen");
- u8g2.setCursor(0, 16*3-2);
- u8g2.print("rand:");
- u8g2.setCursor(40, 16*3-2);
- u8g2.print(num);
- u8g2.setCursor(0, 16*4-2);
- u8g2.print("date:");
- u8g2.setCursor(40, 16*4-2);
- u8g2.print("48.756080");
- u8g2.sendBuffer();
- sprintf(json, "{\"name\":\"liuzewen\",\"rand\":%d,\"data\":[48.756080,2.302038]}",num);
- int len = sizeof(json);
- //Serial.printf("缓存大小是:%d",sizeof("{\"name\":\"liuzewen\",\"rand\":200,\"data\":[48.756080,2.302038]}"));
- //给每个Client客户端发送数据
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- if (serverClients[i] && serverClients[i].connected()) {
- serverClients[i].write(json, len);
- //root.printTo(serverClients[i]);
- delay(1);
- }
- }
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。