Udp packetBuffer verarbeiten

Hallo allerseits,
mein Name ist Torsten und ich hab mich gerade erst angemeldet.
Ich bin dabei, mit einem ESP32 und einem Nextion-Display mir eine Art Smarthomezentrale zu bauen.
Anfangen wollte ich damit, erstmal ein paar Umweltdaten zu sammeln und anzuzeigen.
An einem ESP8266 habe ich einen GY-21 angeschlossen und sende Temperatur und Luftfeuchtigkeit über UDP.
Beim Empfänger, im seriellen Monitor werden die Daten angezeigt, aber ich weiss nicht, wie ich die Daten, die ja im packetBuffer ständig überschrieben werden, weiter verarbeiten soll.

Langer Text, sorry!

Kann mir da jemand weiter helfen?

VG

Hier der Code des "Senders"

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
//#include <WiFiUdp_Generic.h>
#include <OneWire.h>  // https://github.com/PaulStoffregen/OneWire Version 2.3.5
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_HTU21DF.h>
//#include <SHT2x.h>
//#include <SHT2x.h>
#include <Adafruit_Si7021.h>
//#include <GY21.h>



const char* ssid = "xxx";                      // Darf bis zu 32 Zeichen haben.
const char* password = "xxx";  // Mindestens 8 Zeichen jedoch nicht länger als 64 Zeichen.

IPAddress IP(192, 168, 178, 43);
IPAddress mask = (255, 255, 255, 0);

//#define I2C_SDA 19
//#define I2C_SCL 20

//float temperature = 0;
//float humidity = 0;

//Adafruit_HTU21DF (I2C_SDA, I2C_SCL);



//Adafruit_HTU21DF sht21 = Adafruit_HTU21DF();
//Adafruit_HTU21DF htu = Adafruit_HTU21DF();
Adafruit_Si7021 Sensor = Adafruit_Si7021();
//HTU21DF Sensor;





WiFiUDP Udp;
IPAddress unicastIP(192, 168, 178, 40);  // Adresse des Esp, welcher als Empfänger der Nachricht dient, eintragen.
//constexpr uint16_t PORT = 8266;                          // UDP Port an welchen gesendet wird.
constexpr uint16_t PORT = 32;  // UDP Port an welchen gesendet wird.


void setup() {
  Serial.begin(115200);
  Sensor.begin();

  delay(100);
  Serial.printf("\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n%s\n\n",
                (__FILE__), (__TIMESTAMP__), ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10, ESP.getFullVersion().c_str());



  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("._");
  }
  Serial.println("\nVerbunden mit: " + WiFi.SSID());
}

void loop() {
  float temp = Sensor.readTemperature();
  float rel_hum = Sensor.readHumidity();

  Serial.print("Temperatur: ");
  Serial.print(temp);
  Serial.println("°C");
  // Serial.print("\t\t");          //Platzhalter; 2 Tabs
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(rel_hum);
  Serial.println("%");
  delay(5000);


  static unsigned long previousMillis;
  constexpr unsigned long INTERVAL(5000);  // Aller 5 Sekunden wird die Temperatur gemessen und anschliesend gesendet.
  if (millis() - previousMillis >= INTERVAL) {
    previousMillis += INTERVAL;
    Sensor.readTemperature();
    sendUdp1(Sensor.readTemperature());

    Sensor.readHumidity();            // Sendet einen Befehl für alle Geräte am Bus, um eine Temperaturumwandlung durchzuführen.
    sendUdp2(Sensor.readHumidity());  // Holt die Temperatur vom Sensor und übergibt diese an die Funktion zum senden.
  }
}

void sendUdp1(float tempC) {
  Udp.beginPacket(unicastIP, PORT);
  Udp.printf("SZ: %.1f°C", tempC);
  Udp.endPacket();
  //delay(1000);
}

void sendUdp2(float rel_hum) {
  Udp.beginPacket(unicastIP, PORT);
  Udp.printf("SZ: %.1f%%", rel_hum);       //Zwei Prozentzeichen, um eins zu zeigen?????.
  Udp.endPacket();
}

Hier der Code des "Empfängers"
Wahrscheinlich viel unnützes Zeug drin, aber ich hab eben schon viel probiert.



#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <iostream>
#include <string>

const char* ssid = "xxx";                      // Darf bis zu 32 Zeichen haben.
const char* password = "xxx";  // Mindestens 8 Zeichen jedoch nicht länger als 64 Zeichen.

IPAddress IP(192, 168, 178, 40);
IPAddress mask = (255, 255, 255, 0);

SoftwareSerial nextion(22, 21);

#define UDP_TX_PACKET_MAX_SIZE 8192

constexpr uint16_t PORT = 32;  // Lokaler UDP Port.
//constexpr uint16_t PORT = 8266;                          // Lokaler UDP Port.
char packetBuffer[30];  //orig. 21                         // Puffer für eingehendes Paket.
 



//float packetBuffer ("Schlafzimmer: %.1f°C")
//float var ("Schlafzimmer: %.1f°C")
//float var (udp1)
/*const int SERIAL_BUFFER_SIZE = 20;
char serialBuffer[SERIAL_BUFFER_SIZE];

const int NUMBER_OF_VALUES = 8;
unsigned int values[NUMBER_OF_VALUES];*/

WiFiUDP Udp;


void setup() {
  Serial.begin(115200);
  delay(100);
 
  nextion.begin(115200);  // start software serial with Nextion Display
  Serial.printf("\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n%s\n\n",
                (__FILE__), (__TIMESTAMP__), ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10, ESP.getFullVersion().c_str());

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
   Serial.print('.');
   delay(500);
  }
  Serial.println("\nVerbunden! Esp8266 IP: " + WiFi.localIP().toString());
  Serial.printf("UDP Server lauscht am Port: %d\n\n", PORT);
  Udp.begin(PORT);
  float packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //Puffer zum Speichern eingehender Pakete,
  float Udp1();

}

void loop() {

  uint16_t packetSize = Udp.parsePacket();         // Eingehende UDP-Pakete empfangen.
  if (packetSize) {                                // Prüfen ob UDP-Pakete empfangen wurden.
    Udp.read(packetBuffer, sizeof(packetBuffer));  // Einlesen des UDP Paket in den Buffer.
    packetBuffer[packetSize] = 0;                  // String Ende hinzufügen.

    Serial.println(packetBuffer);                  // Visualisierung des empfangenen Packets
    
    float packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //Puffer zum Speichern eingehender Pakete,
    //Udp.read(packetBuffer);

    //Serial.println(packetBuffer);                  // Visualisierung des empfangenen Packets
    //Serial.println(Udp);


    }
}        



Hallo und willkommen.
Warum sendest du die Daten nicht direkt an den ESP32, wo du diese auf dem Nextion anzeigen möchtest.
Oder liege ich da falsch.
Und bedenke, die ESP vertragen nur 3,3V auf den Pins. Nextion liefert aber 5Volt.

Danke für die schnelle Antwort.
Im"Sende ESP" stht doch die IP des Empfängers (40).
Die Kommunikation mit dem Display sollte seriell erfolgen, aber da bin ich noch meilenweit entfernt.
VG

Dann solltest du erstmal aufräumen. So wird man nich schlau draus.
Was hat das dann mit einem ESP32 zutun ?
Und klar, das Nextion versteht nur seriell.
Hier gibt es reichlich Infos zum Nextion.

Was meinst Du mit aufräumen?
Das Auskommentierte löschen?
Ich vermute, dass im Empfänger viel Müll drin ist, aber wie schon gesagt, ich hab viel rumprobiert.
Danke für den Link.
Ich schau es mir an.

VG

Ja, genau und passende Kommentare (Dokumentation) schreiben.
Nochmal, was hat der ESP32 damit zu tun ?

Wie meinst Du das, mit dem ESP32?
Der Empfänger ist ein ESP32.

VG

Weil es allles sehr unverständlich ist.

Und warum ist dein Empfängersketch für einen ESP8266 ?

Es hat eben so am Besten funktioniert.
Wahrscheinlich kannich auch die " #include <ESP8266WiFi.h>" auskommentieren.

VG

Unbedingt.
Das irritiert nur alle Helfer, die hat da nix zu suchen.
Und der ESP32 hat noch weitere Hardware Serielle Schnittstellen. Die solltest dufür das Nextion auch verwenden. Ist deutlich stabiler.

Alles klar, danke.
Ich versuche morgen, etwas aufzuräumen, und melde mich wieder.
Und danke, dass ich hier so freundlich empfangen wurde.

VG

Und denke auch an das Problem mit der Spannung an den seriellen Pins.

Das Nextion arbeitet im Lieferzustand mit 9600.

Wozu brauchst du nachfolgende Libraries ?

Hallo,
hier nochmal der bereinigte Code des Empfängers.
Wenn ich die ESP8266WiFi.h auskommentiere kommt folgende Fehlermeldung:

Compilation error: 'WiFi' was not declared in this scope; did you mean 'WiFiUDP'?



#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SoftwareSerial.h>


const char* ssid = "xxx";                      // Darf bis zu 32 Zeichen haben.
const char* password = "xxx";  // Mindestens 8 Zeichen jedoch nicht länger als 64 Zeichen.

IPAddress IP(192, 168, 178, 40);
IPAddress mask = (255, 255, 255, 0);

SoftwareSerial nextion(22, 21);

#define UDP_TX_PACKET_MAX_SIZE 8192

constexpr uint16_t PORT = 32;  // Lokaler UDP Port.

char packetBuffer[30];  //orig. 21                         // Puffer für eingehendes Paket.





WiFiUDP Udp;


void setup() {
  Serial.begin(115200);
  delay(100);

  nextion.begin(115200);  // start software serial with Nextion Display
  Serial.printf("\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n%s\n\n",
                (__FILE__), (__TIMESTAMP__), ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10, ESP.getFullVersion().c_str());

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }
  Serial.println("\nVerbunden! Esp8266 IP: " + WiFi.localIP().toString());
  Serial.printf("UDP Server lauscht am Port: %d\n\n", PORT);
  Udp.begin(PORT);
  float packetBuffer[UDP_TX_PACKET_MAX_SIZE];  //Puffer zum Speichern eingehender Pakete,
  float Udp1();
}

void loop() {

  uint16_t packetSize = Udp.parsePacket();         // Eingehende UDP-Pakete empfangen.
  if (packetSize) {                                // Prüfen ob UDP-Pakete empfangen wurden.
    Udp.read(packetBuffer, sizeof(packetBuffer));  // Einlesen des UDP Paket in den Buffer.
    packetBuffer[packetSize] = 0;                  // String Ende hinzufügen.

    Serial.println(packetBuffer);  // Visualisierung des empfangenen Packets
  }
}


VG

Weil du immer noch ESP8266 und ESP32 durcheinander bringst.
du musst deinen Sketch richtig für einen ESP32 schreiben. Und dazu brauchst du die richtigen Libraries, wie z.B. die "WiFi.h" und nicht die "ESP8266WiFi.h".

Schau dir doch mal die Beispiele bei fips an. Da wirst du alle Infos finden.
Und nochmal, beim ESP32 solltest du kein SoftwareSerial verwenden, der hat weitere Hardware Serielle Schnittstellen.

Hallo und willkommnen

Warum willst Du aus den zwei Messwerten zwei Pakete machen, dann musst Du jedem Paket eine Kennung mitgeben oder es anhand der Länge oder sonstwie unterscheiden können. Das geht aber auch in einem Paket. Ich hab da mal in meiner Bastelkiste gewühlt und das gefunden.
Dabei werden 5 Werte in einem Paket übertragen. Ich hab jetzt nur die Schnipsel kopiert um zu zeigen wie man das machen kann.

Sender:

//-------------- send UDP Daten----------------
void sendUDP() {
  sprintf(sendPack, "%4d;%4.2f;%4.2f;%4.2f;%4.2f", devAdress, temp, hum, pres, Vcc);
  int len = strlen(sendPack);
  // Serial.println(len);
  Serial.print("local Port :"); Serial.println(localPort);
  Serial.print("host Port :"); Serial.println(hostPort);
  Serial.println(sendPack);

  Udp.begin(localPort);
  Udp.beginPacket(hostIP, hostPort);
  Udp.write(sendPack, len);
  Udp.endPacket();
  Udp.stop();

}

auf der Empfängerseite wird das gesamte Paket in ein CString geladen. Da ich ja weiß welche Daten an welcher Stelle stehen kann man sie dann zerlegen und z.B in einem Array ablegen.
das geht recht einfach mit strtok().

// ---------------- UDP recive -----------------
void UDP_recive() {

  char inPack[100];

  int packetSize = Udp.parsePacket() ;
  if (packetSize) {
    // receive incoming UDP packets
    Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(inPack, 255);
    if (len > 0) {
      inPack[len] = 0;// Ende Kennung
    }
    Serial.printf("UDP Daten-Paket  %s \n", inPack);
    CStringToWert(inPack);
  }
}

// ----------------Daten umladen----------------
int CStringToWert(char *instr) {
  // füllt daten aus einem C-String in Daten

  int devAdress = atoi(strtok(instr, ";"));
  Serial.printf("Dev Adresse %d \n", devAdress);
  if (devAdress == 1) {
    for ( int i = 0; i <= 3; i++) {
      inwert[i] = atoi(strtok(NULL, ";"));
      Serial.println(inwert[i]);
    }
  }
}

Hallo Rentner,
dankeschön für den Code. So hab ich es gesucht.
Ich werde es probieren und anpassen.
Insgesamt sollen es mal acht Messstellen mit je mehreren Werten und Zuständen
(z.B. Gartentürchen) werden, inklusive der Batteriespannung.

Also danke nochmal und viele Grüsse!

Und es interessiert dich nicht, das dein Sketch nicht am ESP32 funktioniert.
OK, dann bin ich raus.

Sorry,
aber bis hier funktioniert er doch.
Ich bin bloß mit der Weiterverarbeitung des packetBuffers nich klar gekommen.

Was ich noch vergessen habe ist, beide Sketches basieren auf der Seite von fipsok.de also von daher auch vielen Dank.

Kann mir noch jemand sagen, was diese Zeichenfolge zu bedeuten hat:

"%4d;%4.2f;%4.2f;%4.2f;%4.2f"

VG

Dann machst du es nicht mit einem ESP32 oder du lieferst uns falsche Infos.

Hallo,
dann musst Du Dir sicher noch was anderes einfallen lassen. Wenn mehrerer UDP Sender einfach drauf los senden dann kann es zu einem Konflikt kommen, und Pakete gehen verloren. Dann wäre noch ein Weg das die Zentrale die Messstellen der Reihe nach anspricht und die antworten mit ihren Messwerten.
UDP hat ja kein richtiges Protokoll. Eventuell hast Du ja einen Teil der Messstellen auch noch im Akku Betrieb und die senden nur ein paar mal in der Stunde. Ansonsten sind sie im deep Sleep , also nicht erreichbar. Wenn ein fehlendes Datenpaket kein Problem ist dann ist sicher UDP am einfachsten ansonsten würde ich TCP nehmen.

Zum Testen nutze ich das Windows Programm Paket Sender, dann hat man es erst mal nur mit einer Seite zu tun.