简体   繁体   English

拆分 BLE 结果并使用 ESP32 逐行发送到 MQTT

[英]Splitting BLE findings and sending out to MQTT line by line using an ESP32

So I have two ESP32s for this project, one sending BLE scanned device info and the other ESP32 sending the scan results to an MQTT broker.所以我有两个用于这个项目的 ESP32,一个发送 BLE 扫描的设备信息,另一个 ESP32 将扫描结果发送到 MQTT 代理。 I am currently facing the issue where I cannot break the results up into multiple JSON lines and send them out to the MQTT broker line by line.我目前面临的问题是我无法将结果分解为多个 JSON 行并将它们逐行发送到 MQTT 代理。 Please do let me know if you have any solutions.如果您有任何解决方案,请告诉我。 Thank you!!谢谢!!

#include <WiFi.h>                                                                    //Remove when not MQTT-ing using WiFi
#include <PubSubClient.h> 

const char* ssid = "--------";         
const char* password  = "+++++++++++";  

#define RXD2 16
#define TXD2 17

 
WiFiClient espClient;
PubSubClient client(espClient);

// MQTT Broker
const char* mqtt_broker = "broker.hivemq.com";
const char* topic = "**********";
const int mqtt_port = 1883;

void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);
  WiFi.begin(ssid, password);  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");
  //connecting to a mqtt broker
  client.setServer(mqtt_broker, mqtt_port);
  while (!client.connected()) {
    String client_id = "esp32-client-";
    client_id += String(WiFi.macAddress());
    Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
    if (client.connect(client_id.c_str())) {
      Serial.println("Public hivemq broker connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }

  }
}

void loop() {
  // put your main code here, to run repeatedly:
  String msg = "";
  msg = Serial2.readString();
  //String msg = "test MQTT";
  // publish
  int index = msg.lastIndexOf('}');
  int length = msg.length();
  String subMsg = msg.substring(index, length);
  client.publish(topic,subMsg.c_str());
  Serial.println("Message has been sent is: ");
  Serial.println(subMsg.c_str();
  delay(5000);
}

This is the output that I have:这是我的 output:

{"Device Name":"GXHGA22CF3B9","EDID":"d4:0b:dd:2c:f3:b9","RTID":"FF005802600001F","RSSI":"-77"}

{"Device Name":"","EDID":"d7:9c:0e:1d:e6:a2","RTID":"FF005802600001F","RSSI":"-71"}

{"Device Name":"Buds2","EDID":"d8:4d:72:1f:80:15","RTID":"FF005802600001F","RSSI":"-75"}

{"Device Name":"KBPro_185309","EDID":"dd:34:02:06:33:a8","RTID":"FF005802600001F","RSSI":"-87"}

{"Device Name":"GXHGA2DAEC2A","EDID":"de:1e:da:da:ec:2a","RTID":"FF005802600001F","RSSI":"-86"}

{"Device Name":"","EDID":"e9:c7:1b:79:e1:41","RTID":"FF005802600001F","RSSI":"-76"}

{"Device Name":"","EDID":"e9:f5:80:7f:c8:ea","RTID":"FF005802600001F","RSSI":"-89"}

{"Device Name":"","EDID":"ef:e0:22:b2:c6:d0","RTID":"FF005802600001F","RSSI":"-84"}

{"Device Name":"GXHGA20A5D4A","EDID":"f6:4e:4d:0a:5d:4a","RTID":"FF005802600001F","RSSI":"-84"}

{"Device Name":"","EDID":"ff:65:fa:78:7f:c1","RTID":"FF005802600001F","RSSI":"-93"}

{"Device Name":"","EDID":"00:64:0f:26:92:09","RTID":"FF005802600001F","RSSI":"-90"}

Your current code finds the last } in the message and then takes that as the starting point for a substring to the end of the message.您当前的代码找到消息中的最后一个} ,然后将其作为 substring 到消息末尾的起点。 So you will always get a } character.所以你总是会得到一个}字符。 You need to loop through the messages in a single read and find the start and end braces, pulling out each message.您需要在一次读取中循环遍历消息并找到开始和结束大括号,提取每条消息。

Something like this:是这样的:

void loop() {
    // put your main code here, to run repeatedly:
    String msg = "";
    msg = Serial2.readString();

    int start_idx = 0 ;
    while( start_idx >= 0 )
    {
        start_idx = msg.indexOf('{',start_idx);
        if ( start_idx >= 0 )
        {
            int end_idx = msg.indexOf('}',start_idx+1); 
      
            String subMsg = msg.substring(start_idx, end_idx+1); 

            client.publish(topic,subMsg.c_str());
            Serial.println("Message has been sent is: ");
            Serial.println(subMsg.c_str();
      
            start_idx = end_idx + 1; 
        }
    }
}

Note - this assumes that the JSON doesn't contain any objects - since the internal braces will also be separated.注意 - 这假设 JSON 不包含任何对象 - 因为内部大括号也将被分开。 It also assumes you get complete JSON messages with each Serial read (ie they're not truncated).它还假定您在每次串行读取时获得完整的 JSON 消息(即它们没有被截断)。 So you may need to handle these cases - but this should give you a start.所以你可能需要处理这些情况——但这应该给你一个开始。

I've also removed the delay - I don't know why you'd want to delay for 5 seconds between reads - unless this was just for testing.我还删除了延迟 - 我不知道为什么你想在读取之间延迟 5 秒 - 除非这只是为了测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM