TCP Verbindung zu Python mit ESP8266 Pretzelboard

Guten Tag,

ich möchte mit meinem Pretzelboard eine TCP - Verbindung zu einem Python Programm herstellen. Folgender Code:

/*
TCP-Server
Change SSID and PASSWORD.
*/

#define SSID "FRITZ_4040"
#define PASSWORD "pwd"

#define DEBUG true

#define LED_WLAN 13

#include <Arduino.h>
#include <NanoESP.h>
#include <SoftwareSerial.h>
char receivedChars[1024];
NanoESP esp8266 = NanoESP();

SoftwareSerial NanoESP(11, 12); // RX, TX

void setup() {
  Serial.begin(19200);
  esp8266.begin(19200);


  if (!espConfig()) serialDebug();
  else digitalWrite(LED_WLAN, HIGH);

}
int rr;
String snd; 
String rec;
int clientId;

void loop() {


 
  if (esp8266.available())
  { 
    rec = esp8266.readString();   
    debug(rec);    
    delay(10);   
  }  

    clientId = esp8266.getId();
    if (clientId >=0) 
    {
      String webpage = "Hello World!";
      esp8266.sendData(clientId, webpage);    
    }


  //debug(sendCom("AT+CIPSTATUS"));
  
}

//-----------------------------------------Config ESP8266------------------------------------

boolean espConfig()
{
  boolean succes = true;
  esp8266.setTimeout(5000);
  succes &= sendCom("AT+RST", "ready");
  esp8266.setTimeout(1000);

  if (configStation(SSID, PASSWORD)) {
    succes &= true;
    debug("WLAN Connected");
    debug("My IP is:");
    debug(sendCom("AT+CIFSR"));
  }
  else
  {
    succes &= false;
  }
  //shorter Timeout for faster wrong UPD-Comands handling
  succes &= sendCom("AT+CIPMODE=0", "OK");  
  succes &= sendCom("AT+CIPMUX=0", "OK");
  configTCPServer();
  return succes;
}

boolean configTCPServer()
{
  boolean succes = true;
  succes &= (sendCom("AT+CIPMUX=1", "OK"));
  succes &= (sendCom("AT+CIPSERVER=1,50006", "OK"));

  return succes;

}

boolean configStation(String vSSID, String vPASSWORT)
{
  boolean succes = true;
  succes &= (sendCom("AT+CWMODE=1", "OK"));
  esp8266.setTimeout(20000);
  succes &= (sendCom("AT+CWJAP=\"" + String(vSSID) + "\",\"" + String(vPASSWORT) + "\"", "OK"));
  esp8266.setTimeout(1000);
  return succes;
}
//-----------------------------------------------Controll ESP-----------------------------------------------------
boolean sendCom(String command, char respond[])
{
  esp8266.println(command);
  if (esp8266.findUntil(respond, "ERROR"))
  {
    return true;
  }
  else
  {
    debug("ESP SEND ERROR: " + command);
    return false;
  }
}

String sendCom(String command)
{
  esp8266.println(command);
  return esp8266.readString();
}

//-------------------------------------------------Debug Functions------------------------------------------------------
void serialDebug() {
  while (true)
  {
    if (esp8266.available())
      Serial.write(esp8266.read());
    if (Serial.available())
      esp8266.write(Serial.read());
  }
}

void debug(String Msg)
{
  if (DEBUG)
  {
    Serial.println(Msg);
  }
}

Das Problem:
Ich empfange daten vom Python - Programm, nur das Senden klappt nicht, weil die clientId = -1 ist.
Woran liegt das?

Hallo @klaus1_234,

ohne allzu tief eingestiegen zu sein:

Auf der Seite https://iot.fkainka.de/diskusion-und-hilfe findet man einen Post vom 13. Juli 2016 (Holger) in dem zwei leider unvollständige Sketche vorhanden sind:

TCP Server:


/*
     Achtung: Unvollständig!!!!!!
     Es fehlen erforderliche includes  
     Quelle: https://iot.fkainka.de/diskusion-und-hilfe
*/
NanoESP esp8266 = NanoESP();

void setup()
{
  Serial.begin(19200);
  esp8266.init();
  esp8266.configWifi(ACCESSPOINT, „NanoESP2“, „“);
  esp8266.startTcpServer(93);
  Serial.println(esp8266.getIp());
}

void loop() // run over and over
{
  int client = esp8266.getId();
  if (client >= 0) {
    esp8266.find(„: “);
    Serial.println(esp8266.readString());
    esp8266.sendData(client, „Hello UDP Client“);
  }
}

Client:

/*
     Achtung: Unvollständig!!!!!!
     Es fehlen erforderliche includes  
    Quelle: https://iot.fkainka.de/diskusion-und-hilfe

*/

NanoESP esp8266 = NanoESP();

void setup()
{
  Serial.begin(19200);
  if (!esp8266.init())Serial.println(„Error Init“);
  if (!esp8266.configWifi(STATION, „NanoESP2“, „“)) Serial.println(„Error Station“);
  Serial.println(esp8266.getId());
  Serial.println(esp8266.getIp());

  boolean vConnect = true;
  if (!esp8266.newConnection(2, „TCP“, „192.168.4.1“, 93)) Serial.println(„Verbindungsfehler“);
  esp8266.sendData(2, „Hello UDP Server“);
}

void loop() // run over and over
{
  int client = esp8266.getId();
  if (client >= 0) {
    esp8266.find(„: “);
    Serial.println(esp8266.readString());
    esp8266.sendData(2, „Hello UDP Server 2“);
  }
}

Zwei möglicherweise hilfreiche Zeilen:

esp8266.startTcpServer(93);

startet den TCP Server auf Port 93. Das scheint in Deinem Sketch in configTCPServer() mittels sendCom("AT+CIPSERVER=1,50006", "OK") auf Port 50006 erledigt zu werden...

if (!esp8266.newConnection(2, „TCP“, „192.168.4.1“, 93)) Serial.println(„Verbindungsfehler“);

erstellt eine Verbindung zu einem TCP/UDP-Server mit angegebener IP auf dem ebenfalls angegebenen Port.

Der Empfang scheint dann bei Dir über den TCP-Server auf dem Pretzelboard und Port 50006 zu laufen, ist das korrekt? Wenn ja, gehe ich davon aus, dass der NanoESP keine Client-ID erhält, weil es kein Client sondern der Server ist. Die Verbindungsaufnahme geht dann von der Gegenstelle, dem Client, aus.

P S.: In der NanoESP Lib gibt es eine Funktion

bool NanoESP::recvData(int &id,int &len)

Du kannst versuchen, diese Funktion anstelle von . available() zu verwenden und dort die ClientId auszulesen...

Das sähe in der loop() so aus (compiliert, aber nicht getestet! Ob das Setzen von clientId = -1; erforderlich ist, wäre auch zu prüfen ...):

void loop() {
  int len;
  if (esp8266.recvData(clientId, len))
  {
    rec = esp8266.readString();
    debug(rec);
    delay(10);
  }
  if (clientId >= 0)
  {
    String webpage = "Hello World!";
    esp8266.sendData(clientId, webpage);
    clientId = -1;
  }

  //debug(sendCom("AT+CIPSTATUS"));

}

P.P.S: Habe noch etwas gefunden:

void loop() {
 String xBuffer;
 if (esp8266.available()) // check if the esp is sending a message
 {
   if (esp8266.find("+IPD,"))
   {
     debug("Incomming Request");
     int connectionId = esp8266.parseInt();

     if (sendWebsite(connectionId, createWebsite())) debug("Website send OK"); else debug("Website send Error");
   }
  }
}

Quelle: https://www.mikrocontroller-elektronik.de/wifi-board-nanoesp-bzw-pretzel-board/

Hier wird die ID des Clients nach esp8266.available() durch die Funktionen esp8266.find() und dann esp8266.parseInt() ermittelt. Diese ID wäre dann beim Senden zu verwenden.

Viel Erfolg!

Danke, du hast mir sehr geholfen!
Tatsächlich muss erst die Client-ID gelesen werden, dann esp8266.readString(), danach der Schreibbefehl, also:

void loop() // run over and over
{
  int client = esp8266.getId();
  if (client >= 0) {
    esp8266.find(„: “);
    Serial.println(esp8266.readString());
    esp8266.sendData(client, „Hello UDP Client“);
  }
}

Da bin ich gar nicht so sicher, ob ich Dir weitergeholfen habe ... :wink:
Funktioniert das Ganze bei Dir denn jetzt?