Датчик Lora to Mqtt не может быть прочитан

Я пытаюсь передать данные с датчика температуры, расположенного за пределами моей зоны действия Wi-Fi. Я выбрал технологию Lora между ESP32, оснащенным SX1278, и TTGO Lilygo lora. Пока все работает нормально. Но как только я пытаюсь опубликовать данные через mosquitto mqtt, чтобы иметь доступ к домашнему помощнику, все становится еще хуже. Я использую Mqtt Explorer для просмотра обменов с mosquitto. Я также отслеживаю данные на последовательном порту. Все работает правильно, пока я не публикую данные о температуре, но с того момента, как я публикую их после изменения в строке для переключения на mqtt, у меня возникают некоторые проблемы:

  • последовательный порт отображает неправильные значения строки и постоянно прокручивается
  • данные, отправленные на mqtt, хорошо отображаются в соответствии с последовательным портом, но остаются несогласованными, и количество публикаций быстро увеличивается
  • с определенного момента все больше не движется.

Итак, у меня есть по крайней мере две проблемы, и даже если я просмотрел множество примеров, мне трудно все понять... Вы найдете прилагаемый код, загруженный в приемник Lilygo, в надежде, что он поможет решить мою проблему (проблемы):

#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Streaming.h>
#include <Ticker.h>


#define OLED_SDA 21     // Внимание: Брошюры SDA и SCL об устройстве OLED не переворачиваются на дизайне LilyGO и на GitHub.
#define OLED_SCL 22 
#define OLED_RST 12     // Примечание: TTGO Lora32 v2 не использует сигнал сброса, кроме библиотеки Adafruit_SSD1306, или.
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях

const int csPin = 18;          // Выбор радиочипа LoRa-TTGO
const int resetPin = 23;       // Сброс радио LoRa-TTGO
const int irqPin = 26;         // смена для вашей платы; должен быть контакт аппаратного прерывания-TTGO
const int sckPin = 5;          //-ТТГО
const int misosPin = 19;       //-ТТГО
const int mosiPin = 27;        //-ТТГО


const char* ssid = "xxxxxx";      // Имя Wi-Fi
const char* password = "xxxxxx";    // Моментальный Wi-Fi

const char* mqtt_server = "xxx.xxx.x.xx";   // IP-адрес брокера MQTT
const char* mqtt_username = "xxxxx";     // Пользовательский MQTT
const char* mqtt_password = "xxxxxx";    // Пароль MQTT
const char* mqtt_topic = "ESP32/DS18B20/temp_piscine";   // Имя темы MQTT-посланника для домашнего помощника

char incoming ;
char msg[4];

WiFiClient espClient;
PubSubClient client(espClient);

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

void setup() 
{
  Serial.begin(115200);
  while (!Serial);

  // настраиваем Wi-Fi
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  // инициализируем OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) 
  { // Адрес 0x3C для 128x32
    Serial.println(F("SSD1306 allocation failed"));
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORA RECEIVER ");
  display.display();

  Serial.println("LoRa Receiver");

  // переопределить выводы CS, сброса и IRQ по умолчанию (необязательно)
    SPI.begin(sckPin, misosPin, mosiPin, csPin);
    LoRa.setPins(csPin, resetPin, irqPin); // установка CS, сброс, вывод IRQ

  if (!LoRa.begin(433E6)) 
  {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}
//Функция соединения с Wi-Fi приложением в настройках
void setup_wifi() {
  delay(10);
  // Начнем с подключения к сети WiFi
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  display.setCursor(0,0);

  WiFi.begin(ssid, password);

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

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

//Функция соединения с Wi-Fi приложением в настройках
void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
}

//Подключение функции к серверу Mqtt в цикле
void reconnect() {
  // Цикл, пока мы снова не подключимся
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Попытка подключения
    if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Подождите 5 секунд перед повторной попыткой
      delay(5000);
    }
  }
}


void loop() 
{
  client.loop();
  // пытаемся разобрать пакет
  int packetSize = LoRa.parsePacket();
  if (packetSize) 
{
    // получил пакет
    Serial.print("Received packet ");
    // чтение и печать пакета
    display.clearDisplay();
    display.setCursor(0,0);
    while (LoRa.available())
    {
      incoming = ((char)LoRa.read());
      //Serial.print((char) LoRa.read());
      Serial.print(incoming);
      display.print(incoming);  
    }
    // вывести RSSI пакета
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());    
    //display.setCursor(0,0);
    display.print("' with RSSI ");
    display.println(LoRa.packetRssi());
    display.display();
      }
  if (!client.connected()) 
  {
    reconnect();
  }
  dtostrf(incoming, 6, 2, msg);
  Serial.print (msg);
  client.publish(mqtt_topic,msg,false);
  //client.publish(mqtt_topic,dtostrf(LoRa.packetRssi(),6,2,msg),false);
  
}

, 👍1

Обсуждение

Привет, я не вижу ничего явно неправильного - каковы сообщаемые значения использования ОЗУ при сборке программы? Конечно, это может быть связано с тем, что вы столкнулись с переполнением стека или повреждением памяти., @Greycon


2 ответа


0

В вашем dtostrf(incoming, 6, 2, msg); вы хотите сохранить число с плавающей запятой, которое имеет минимальную ширину 6 с точностью до 2 цифр, вам понадобится массив не менее 9 байт (плюс разделитель NULL) для значения типа «12345.78», вы разрешаете только 4 байта для вашего msg[4]; чего определенно недостаточно.

Даже если ваша температура равна 32,45, для msg все равно потребуется массив из 6.

,

2

Здравствуйте и спасибо за вашу поддержку, я, наконец, нашел pb, который заключался в том, что использование входящих сообщений должно храниться в буфере для использования, поскольку оно было отправлено char за char. Я также нашел возможность использовать LoRa.readString(), который позволяет хранить все строки. Я использовал после функции LoRaData.indexOf..., которая позволяет выбрать определенную часть текста с помощью определенных меток, таких как #, *, /, ... Вот пример используемого кода для тех, кому это может быть интересно.

    void loop() 

{ клиент.цикл();

// пытаемся разобрать пакет int packetSize = LoRa.parsePacket(); если (размер пакета) { // получен пакет

Serial.println("Received packet ");
// чтение и печать пакета
display.clearDisplay();
display.setCursor(0,0);
while (LoRa.available()) //>0 удалить
{
  String LoRaData = LoRa.readString();
  Serial.print(LoRaData);   
// Получить текст, температуру и конечный текст: *Temp.piscine #21.56*C*
  int pos1 = LoRaData.indexOf('#');
  int pos2 = LoRaData.indexOf('*');
  Text = LoRaData.substring(0, pos1);
  temperature = LoRaData.substring(pos1 +1, pos2);
  End = LoRaData.substring(pos2+1, LoRaData.length());  
}
// вывести RSSI пакета
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());    

display.print("temperature Piscine = ");
display.print(temperature);
display.print("°C");
display.print("' with RSSI ");
display.println(LoRa.packetRssi());
display.display();

  }

Мне все еще нужно поработать над этим, но, похоже, все работает нормально.

,