Ich habe ein paar empfangene Integer Werte, die ich über MQTT publishen möchte. Es funktioniert soweit hervorragend. Da man aber mit Strings stark den Arbeitsspeicher beansprucht, wollte ich fragen, ob es so gut ist. Oder ob der Speicher irgendwann voll läuft. Oder andere Probleme in längerer Laufzeit auftreten könnten.
Das Topic, wo die Daten veröffentlicht werden, erstelle ich mir zum Teil aus einem Integer der Empfangen wird. Dieser beinhaltet die Sensor-ID. Somit kann ich die Werte dann später auch prima zuordnen.
Zum Topic erstellen habe ich mir ein paar Char-Array Zeichenketten erstellt
const char* topicBegin = "nRF24/";
const char* topicTemp = "/Temp";
const char* topicHumi = "/Humi";
const char* topicDruck = "/Druck";
const char* topicVcc = "/Vcc";
const char* topicWert1 = "/Wert1";
const char* topicWert2 = "/Wert2";
char topicSend[20];
Die ich dann zum senden zusammensetze
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicTemp);
mqttclient.publish(topicSend,String(payload.Temp/10.0,1).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicHumi);
mqttclient.publish(topicSend,String(payload.Humi/10.0,1).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicDruck);
mqttclient.publish(topicSend,String(payload.Druck).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicVcc);
mqttclient.publish(topicSend,String(payload.Vcc/1000.0,2).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicWert1);
mqttclient.publish(topicSend,String(payload.Wert1).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicWert2);
mqttclient.publish(topicSend,String(payload.Wert2).c_str());
Und damit es sich auch kompileren lässt, der ganze Code.
#include <ESP.h>
#include <ESP8266WiFi.h> // ESP8266 WLAN Bibliothek
#include <PubSubClient.h> // MQTT Bibliothek https://github.com/knolleary/pubsubclient
#include "RF24.h" // nRF24l01+ Bibliothek https://github.com/nRF24/RF24
struct PaketStruktur{
uint16_t ID; // (0..65535) - Eindeutige ID des Senders
int16_t Temp; // Wert für die Temperatur * 10
uint16_t Humi; // Wert für die Luftfeuchtigkeit % * 10
uint16_t Druck; // Wert für den Druck hPa
uint16_t Vcc; // Wert der Batteriespannung in mV
uint16_t Wert1; // Zusätzlicher Wert 1
uint16_t Wert2; // Zusätzlicher Wert 2
};
PaketStruktur payload;
RF24 radio(D2,D8); // CE, CSN
uint8_t address[][6] = {"xxxxx"}; // Adressen der Kanäle, sollten bei den beteiligten Modulen gleich sein
const char* ssid = ""; // WLAN Name (SSID)
const char* password = ""; // WLAN Passwort
const char* mqtt_server = "xxx.xxx.xxx.xxx"; // IP des MQTT Brokers (z.b. IP des Raspberry PI)
const uint16_t port = xxx; // Port des MQTT Brokers
const char* clientName = "nRF24 Zentrale";
const char* topicBegin = "nRF24/";
const char* topicTemp = "/Temp";
const char* topicHumi = "/Humi";
const char* topicDruck = "/Druck";
const char* topicVcc = "/Vcc";
const char* topicWert1 = "/Wert1";
const char* topicWert2 = "/Wert2";
char topicSend[20];
WiFiClient espClient; // WLAN initialisieren
PubSubClient mqttclient(mqtt_server,port,0,espClient); // MQTT initialisieren
void setup() {
Serial.begin(9600);
delay(200);
pinMode(D4,OUTPUT); // LED an D4
// WLAN einstellungen
IPAddress ip(xxx, xxx, xxx, xxx); // IP Adresse des ESPs
IPAddress gateway(xxx, xxx, xxx, xxx); // Gateway für den ESP
IPAddress subnet(xxx, xxx, xxx, xxx); // Subnet für den ESP
IPAddress dns(xxx, xxx, xxx, xxx); // DNS für den ESP
WiFi.config(ip, dns, gateway, subnet); // WLAN am ESP einsellen
WiFi.persistent(false); // auskommentieren wenn Netzwerkname oder Passwort in den Flash geschrieben werden sollen
WiFi.mode(WIFI_STA);
WiFiStart();
//nRF24 Einstellungen
if(radio.begin()){ // Stellt SPI Verbindung zum nRF24-Modul her
radio.setChannel(84); // Sendekanal (zwischen 0 - 125), untere Kanäle oft von WIFI belegt, 0 - 84 in Europa erlaubt
radio.setPayloadSize(sizeof(payload)); // Sende nur so viele Daten, wie nötig
radio.setAutoAck(true); // Automatische Bestätigung bei Empfang Daten
radio.setPALevel(RF24_PA_MAX); // Sendeleistung definieren (RF24_PA_MAX), (RF24_PA_HIGH), ...
radio.setDataRate(RF24_1MBPS); // Übertragungsgeschwindigkeit definieren
radio.setRetries (3, 8); // Abstand von 1ms (X+1 steps of 250μs) 8x wiederholen
radio.openWritingPipe(address[1]); // Erstellt Sendekanal mit Addresse
radio.openReadingPipe(0, address[0]); // Erstellt Empfangskanal mit Nummer (0-5) mit Addresse
radio.startListening(); // Setzt das Modul in den Empangsmodus-Modus
Serial.println("nRF24 Ready");
}
else
{
digitalWrite(D4,HIGH);
}
// MQTT starten
mqttclient.connect(clientName);
}
void loop() {
uint8_t pipe;
if (radio.available(&pipe)) empfSend();
}
void empfSend(){
radio.read(&payload, sizeof(payload)); // Lesen des Payloads
//uint32_t Zeitstempel=micros();
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicTemp);
mqttclient.publish(topicSend,String(payload.Temp/10.0,1).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicHumi);
mqttclient.publish(topicSend,String(payload.Humi/10.0,1).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicDruck);
mqttclient.publish(topicSend,String(payload.Druck).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicVcc);
mqttclient.publish(topicSend,String(payload.Vcc/1000.0,2).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicWert1);
mqttclient.publish(topicSend,String(payload.Wert1).c_str());
strcpy(topicSend,topicBegin);
strcat(topicSend,String(payload.ID).c_str());
strcat(topicSend,topicWert2);
mqttclient.publish(topicSend,String(payload.Wert2).c_str());
//Serial.print("ID: "); Serial.println(payload.ID);
//Serial.print("Temp: "); Serial.println(payload.Temp);
//Serial.print("Humi: "); Serial.println(payload.Humi);
//Serial.print("Druck: "); Serial.println(payload.Druck);
//Serial.print("mVCC: "); Serial.println(payload.Vcc);
//Serial.print("Reed1: "); Serial.println(payload.Wert1);
//Serial.print("Reed2: "); Serial.println(payload.Wert2);
//Serial.print("Micros: ");Serial.println(micros()-Zeitstempel);
//Serial.println();
}
void WiFiStart(){ // wird zum verbinden bzw. wiederverbinden zum WLAN ausgeführt
WiFi.begin(ssid, password);
int i = 20; // Max Verbindungsversuchszeit i*0,5s
while (WiFi.status() != WL_CONNECTED && i > 0) {
delay(500);
i--;
}
Serial.println("Wifi Ready");
}
Muss ich mir bei den Strings sorgen um den Arbeitsspeicher machen? Viel mehr wird nicht dazu kommen. Der ESP8266 dient eigentlich nur als Gateway um die Daten vom nRF24 ins MQTT zu bringen.