ich hab das hier gefunden:

server
Code:
// https://www.arduinoforum.de/arduino-Thread-Nodemcu-wie-benutzen?page=4

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
/*
    Befehlsprotokoll
  1.Byte Befehl   2. bis ... Daten  Sender  Inhalt
  0x01            keine             1       Anforderung Temperatur
  0x11            4 Byte (float)    2       Antwort Temperatur
  0x02            1 Byte (0 oder 1) 1       Setze LED Aus = 0 / EIN = 1
  0x03            keine             1       Abfrage Status der LED
  0x12            1 Byte            2       Sende Status der LED (Antwort auf 0x02 und 0x03)
  0xFF            keine             2       unbekannter Befehl
*/

// <= 31 Zeichen
char *ssid = "nodemcu_test";
// >= 8 oder <= 63 Zeichen oder NULL
char *password = "geheim123";

IPAddress remoteIP(192,168,4,2);
WiFiUDP Udp;
unsigned int port = 4210;  // local and remote port to listen on
char incomingPacket[10];  // buffer for incoming packets (255)
char befehl[10];

uint32_t aktMillis;
uint32_t prevMillis;

typedef struct aufgabe {
  uint32_t prevMillis;
  uint32_t intervall;
};

#define ANZAHL_AUFGABEN 3
aufgabe aufgaben[ANZAHL_AUFGABEN] = {{0L,5000L}, {0L, 7000L}, {0L, 10000L}};
boolean gesendet = false;
int aktuelleAufgabe = -1;
boolean ledStatus = false;

void checkAufgaben() {
int len = 1;  
  // da ist noch was unterwegs
  if (gesendet) return;
  if (0 == WiFi.softAPgetStationNum()) {
    // keine Station angemeldet
    // prevMillis auf aktMillis setzen damit die Zeiten nicht schon abgelaufen sind
    for(byte i=0; i < ANZAHL_AUFGABEN; i++) {
      aufgaben[i].prevMillis = aktMillis;
    }
  }
  else {
    for(byte i=0; i<ANZAHL_AUFGABEN; i++) {
      if (aktMillis - aufgaben[i].prevMillis >= aufgaben[i].intervall) {
        aufgaben[i].prevMillis = aktMillis;
        aktuelleAufgabe = i;
        switch (i) {
           case 0:
               befehl[0] = 0x01;
               Serial.println("Aufgabe Temperatur");
              
               break;
           case 1:
               befehl[0] = 0x02;
               befehl[1] = !ledStatus;
               len++;
               Serial.println("Aufgabe LED schalten");
               break;    
           case 2:
               befehl[0] = 0x03;
               Serial.println("Aufgabe LED Status");
               break;
        }
        Udp.beginPacket(remoteIP, port);
        Udp.write(befehl, len);
        Udp.endPacket();
        gesendet = true;
        break;
      }
    }
  }
}

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

  Serial.print("Setting soft-AP ... ");
  boolean result = WiFi.softAP(ssid, password);
  if(result == true)
  {
    Serial.println("Ready");
    Udp.begin(port);
    Serial.print("UDP-Server bereit an Port ");
    Serial.println(port);

  }
  else
  {
    Serial.println("Failed!");
  }
}

void auswerten(int len) {
byte befehl;
float temp;
boolean status;
  befehl = incomingPacket[0];
  gesendet = false;
  // Bytefolge ausgeben
  Serial.print("Incomming: ");
  for(byte i = 0; i<len;i++) {
    Serial.print(incomingPacket[i],HEX); Serial.print(" ");
  }
  Serial.println();
  switch (befehl) {
      case 0x11:
        memcpy(&temp,incomingPacket+1,sizeof(temp));
        Serial.print("Temperatur: "); Serial.println(temp);
        break;
      case 0x12:
        status = incomingPacket[1];
        Serial.print("LED Status: "); Serial.println(status);
        ledStatus = status;
        break;
      case 0xFF:
        Serial.println("Unbekannter Befehl");
        break;
      default:
        Serial.println("Unbekannte Antwort");
  }
}

void loop() {
int packetSize, len;
  aktMillis = millis();
  if (aktMillis - prevMillis >= 3000) {
    prevMillis = aktMillis;
    Serial.printf("Stations connected = %d\n", WiFi.softAPgetStationNum());
  }
  checkAufgaben();
  // UDP
  packetSize = Udp.parsePacket();
  // Da ist was da
  if (packetSize) {
    Serial.print("Empfangen "); Serial.print(packetSize);
    Serial.print(" von IP "); Serial.print(Udp.remoteIP());
    Serial.print(" Port "); Serial.println(Udp.remotePort());
    len = Udp.read(incomingPacket, 255);
    auswerten(len);
  }
}
client
Code:
#include <OneWire.h>

//#include <DallasTemperature.h>
//  https://www.arduinoforum.de/arduino-Thread-Nodemcu-wie-benutzen?page=4

// NodeMCU 2 mit LED an D7 und DS18B20 an D1
// Als UDP-Server, der vom NodeMCU 1 seine Befehle bekommt
/*
    Befehlsprotokoll
  1.Byte Befehl   2. bis ... Daten  Sender  Inhalt
  0x01            keine             1       Anforderung Temperatur
  0x11            4 Byte (float)    2       Antwort Temperatur
  0x02            1 Byte (0 oder 1) 1       Setze LED Aus = 0 / EIN = 1
  0x03            keine             1       Abfrage Status der LED
  0x12            1 Byte            2       Sende Status der LED (Antwort auf 0x02 und 0x03)
  0xFF            keine             2       unbekannter Befehl
*/

/*
  NodeMCU-DallasDS18B20
  Notwendig ist die angepasste Dallas-Lib:
   Download hier: https://github.com/milesburton/Arduino-Temperature-Control-Library
   Eine eventuell vorhandene DallasTemperature-Lib sollte gelöscht werden, damit oben
   genannte von der IDE verwendet wird
*/
#include <DallasTemperature.h> //Siehe Hinweis oben, verwendet wird
//https://github.com/milesburton/Arduino-Temperature-Control-Library
#include <Base64.h>
#include <OneWire.h>
// für UDP-Server
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define ONE_WIRE_BUS D1  //Bestimmt Port an dem der Sensor angeschlossen ist
#define LED D7

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;

// 10 Sekunden Messintervall Temperatur
#define INTERVALL 10000
// 1 Sekunde Wartezeit auf die Messergebnisse
#define WAIT 1000

uint32_t requestMillis;
uint32_t aktMillis;
uint32_t prevMillis = INTERVALL;
boolean isRequested = false;
float temp = 0.0;

WiFiUDP Udp;
unsigned int localUdpPort = 4210;  // local port to listen on
char incomingPacket[255];  // buffer for incoming packets
char antwort[10];
boolean ledStatus = false;
// das bitte ändern
char *ssid = "nodemcu_test";
char *password = "geheim123";

// Auswerten UDP-Befehl und Antwortdaten vorbereiten
// return: Länge der Antwort
int AntwortBilden(int len) {
  byte befehl;
  // Bytefolge ausgeben
  Serial.print("Incomming: ");
  for(byte i = 0; i<len;i++) {
    Serial.print(incomingPacket[i],HEX); Serial.print(" ");
  }
  Serial.println();

  int alaenge = 1; // mindestens das Befehlsbyte
  befehl = incomingPacket[0];
  switch (befehl) {
    case 0x1:
      antwort[0] = 0x11;
      memcpy(antwort + 1, &temp, sizeof(temp));
      alaenge += sizeof(temp);
      break;
    case 0x2:
      ledStatus = incomingPacket[1];
      if (ledStatus) {
        digitalWrite(LED, HIGH);
      }
      else {
        digitalWrite(LED, LOW);
      }
    // hier kommt kein Break, da die Antwort die gleiche ist
    case 0x3:
      antwort[0] = 0x12;
      antwort[1] = ledStatus;
      alaenge += 1;
      break;
    default:
      antwort[0] = 0xFF;
  }
  return alaenge;
}



// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

void initializeSensor() {
  Serial.println("Dallas Temperature IC Control Library Demo");
  // locate devices on the bus
  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: ");
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  // set the resolution to 12 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(insideThermometer, 12);

  Serial.print("Device 0 Resolution: ");
  Serial.println(sensors.getResolution(insideThermometer), DEC);

  // requestTemperatures() blockiert nicht, bis die Messung fertig ist
  sensors.setWaitForConversion(false);
  Serial.print("Wait for conversation: ");
  Serial.println(sensors.getWaitForConversion());
}

void requestTemp() {
  // Messung ist schon angefordert
  if (isRequested) return;
  // Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  requestMillis = millis();
  isRequested = true;
  //Serial.println("DONE");
}

// function to get (and print) the temperature for a device
void printTemperature(DeviceAddress deviceAddress) {
  // keine Messung gestartet
  if (!isRequested) return;
  if (millis() - requestMillis >= WAIT) {
    prevMillis = aktMillis;
    float tempC = sensors.getTempC(deviceAddress);
    temp = tempC;
    Serial.print("Temp C: ");
    Serial.print(tempC);
    Serial.print(" localIP: ");
    Serial.println(WiFi.localIP());
    isRequested = false;
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  digitalWrite(LED, LOW);
  pinMode(LED, OUTPUT);
  initializeSensor();

  Serial.print("Connecting to "); Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" connected");
  Udp.begin(localUdpPort);
  Serial.print("UDP-Server bereit an IP: ");
  Serial.print(WiFi.localIP());
  Serial.print(" Port: ");
  Serial.println(localUdpPort);
}

void loop() {
int packetSize, len, alen;

  aktMillis = millis();
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  if (aktMillis - prevMillis >= INTERVALL) {
    requestTemp();
  }
  // It responds almost immediately. Let's print out the data
  printTemperature(insideThermometer); // Use a simple function to print out the data

  // UDP
  packetSize = Udp.parsePacket();
  // Da ist was da
  if (packetSize) {
    Serial.print("Empfangen "); Serial.print(packetSize);
    Serial.print(" von IP "); Serial.print(Udp.remoteIP());
    Serial.print(" Port "); Serial.println(Udp.remotePort());
    len = Udp.read(incomingPacket, 255);
    /*
       Wenn mit Zeichenketten gearbeitet wird - machen wir hier nicht
      if (len > 0) {
       incomingPacket[len] = 0;
       Serial.print("Inhalt: "); Serial.println(incomingPacket);
      }
    */
    alen = AntwortBilden(len);
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(antwort, alen);
    Udp.endPacket();
  }
}
nachdem ich die lib's nachinstalliert habe (das thermometer brauche ich nachher sicher nicht ), aber immerhin verbinden sich beide ohne zu murren und es gibt auch gegenseitige meldungen. Muss ich noch studieren