Remote Port WIFI UDP

Bonjour à tous,
je suis (toujours) bien débutant dans le code Arduino, mais cela me passionne beaucoup.
J'ai découvert la puissante carte ESP8266 il y a 3 mois et depuis je l'utilise beaucoup dans mon travail pour gérer des leds à distance, et en temps réel, pour du spectacle vivant. Cela en passant par le protocole UDP. J'avais réussi à mettre en oeuvre mon code grâce aux aides de ce Forum !
A ce jour je voudrais passer à l'étape supérieur et pouvoir intéragir dans les deux sens. Donc équiper mes microcontrolleurs avec des capteurs et recevoir les données toujours par UDP.
J'ai passé pas mal de temps à regarder ce code:

/*
  UDPSendReceive.pde:
  This sketch receives UDP message strings, prints them to the serial port
  and sends an "acknowledge" string back to the sender

  A Processing sketch is included at the end of file that can be used to send
  and received messages for testing with a computer.

  created 21 Aug 2010
  by Michael Margolis

  This code is in the public domain.

  adapted from Ethernet library examples
*/


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

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif

unsigned int localPort = 8888;  // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged\r\n";        // a string to send back

WiFiUDP Udp;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(STASSID, STAPSK);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
  Serial.printf("UDP server on port %d\n", localPort);
  Udp.begin(localPort);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.printf("Received packet of size %d from %s:%d\n    (to %s:%d, free heap = %d B)\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort(), Udp.destinationIP().toString().c_str(), Udp.localPort(), ESP.getFreeHeap());

    // read the packet into packetBufffer
    int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    packetBuffer[n] = 0;
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
}

/*
  test (shell/netcat):
  --------------------
    nc -u 192.168.esp.address 8888
*/

mais ce que je voudrais c'est de lui dire exactement sur quel adresse IP et quel port il doit envoyer mes données, et pas forcement recevoir le packet envoyé.
Par exemple j'ai essayé de rajouter ce code:

    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("hello");
    Udp.endPacket();

et déclaré au début

unsigned int remotePort = 7777; 
   IPAddress remote = Udp.remoteIP();

et enfin dans le setup:

IPAddress remote(192, 168, 1, 136);

Mais cela ne marche pas. Le port de retour est un port toujours différent et en plus à 5 chiffres ...
Bref, j'ai essayé de chercher un peu partout avant de poster ce message, mais j'ai rien trouvé.

Merci d'avance de votre aide.

Claudio

Udp.remoteIP est valide dans le cas d'une connection UDP déjà active, c'est l'adresse sur laquelle vous êtes connecté

de plus vous avez le même nom de variable

mais si la seconde est dans le setup, c'est une variable locale qui est donc perdue après le setup et la variable globale reprend la main (lisez la doc sur la portée des variables scope)


expliquez plus précisément ce que vous voulez faire et postez le code que vous avez écrit pour cela

Merci beaucoup Jackson pour votre retour rapide.
Voici le code avec des petits changements suite à votre message:



/*
  UDPSendReceive.pde:
  This sketch receives UDP message strings, prints them to the serial port
  and sends an "acknowledge" string back to the sender

  A Processing sketch is included at the end of file that can be used to send
  and received messages for testing with a computer.

  created 21 Aug 2010
  by Michael Margolis

  This code is in the public domain.

    https://github.com/kitesurfer1404/WS2812FX


*/

#include "SPI.h"
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#ifndef STASSID
#define STASSID "F4IDM_2T2L"
#define STAPSK "1234567890@"
#endif


unsigned int localPort = 7777;  // local port to listen on
unsigned int remotePort = 8888;  // local port to listen on


// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,

WiFiUDP Udp;
// Set your Static IP Address Settings
IPAddress Claudio(192, 168, 1, 136);
IPAddress local_IP(192, 168, 1, 110);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8); // this is optional
IPAddress secondaryDNS(8, 8, 4, 4); // this is optional

void setup() {
  Serial.begin(115200);
  // Print feedback if the settings are not configured
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
  Serial.println("STA Failed to configure");
}
  
  WiFi.begin(STASSID, STAPSK);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    
    delay(500);
  }
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
    Udp.begin(localPort);

   IPAddress Claudio = Udp.remoteIP();
}

void loop() {

 
    //print out the remote connection's IP address
    Serial.print(Claudio);
   // print out the remote connection's IP address
    Serial.print ("remote");
    Serial.println (remotePort);
      
  
  Serial.printf("UDP server on port", remotePort);

 

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("hello");
    Udp.endPacket();
  
delay (3000);
}



  
String splitString(String str, char sep, int index)
{
 int found = 0;
 int strIdx[] = { 0, -1 };
 int maxIdx = str.length() - 1;

 for (int i = 0; i <= maxIdx && found <= index; i++)
 {
    if (str.charAt(i) == sep || i == maxIdx)
    {
      found++;
      strIdx[0] = strIdx[1] + 1;
      strIdx[1] = (i == maxIdx) ? i+1 : i;
    }
 }
 return found > index ? str.substring(strIdx[0], strIdx[1]) : "";
}

Même si dans le Serial je reçois bien un message comme quoi le port est le 8888 et l'IP celui de la machine, dans mon logiciel je ne reçois aucun message. Pour l'instant j'envoie un message "test" juste pour voir s'il y a de l'activité. L'idée c'est de remplacer ce message par des valeurs de certains capteurs.
J'espère que mon explication est un peu plus claire ....

Son pseudo c'est J-M-L.
Jackson c'est une espèce de "grade" donné par le forum en fonction de l'activité.

en global vous avez

IPAddress Claudio(192, 168, 1, 136);

en variable locale du setup vous avez

  IPAddress Claudio = Udp.remoteIP();

➜ vous n'avez pas remplacé l'adresse de la variable globale, juste créé une variable locale dans le setup qui sera ensuite oublié et dans la loop Claudio vaut toujours 192.168.1.136

si vous voulez modifier la variable globale il faut enlever IPAddress devant (qui fait que vous faites une définition de variable) et juste écrire

 Claudio = Udp.remoteIP();

LOL :face_with_hand_over_mouth:

Merci pour votre patience J-M-L ! Si j'ai bien compris donc, dans la loop , "grâce" à mon erreur, l'adresse 192.168.1.136 sera toujours la même ? Car c'est ce que je voudrais, envoyer toujours à la même adresse et avec le même port le message "hello". Mais je vois dans mon Serial que je reçois un message (Ip unset). Et dans mon logiciel je ne reçois aucun message par le protocole UDP ...

que dit exactement la console série ?

Connected! IP address: 192.168.1.110
Claudio(IP unset)
UDP server on portClaudio(IP unset)
UDP server on port

avec ce dernier code:



/*
  UDPSendReceive.pde:
  This sketch receives UDP message strings, prints them to the serial port
  and sends an "acknowledge" string back to the sender

  A Processing sketch is included at the end of file that can be used to send
  and received messages for testing with a computer.

  created 21 Aug 2010
  by Michael Margolis

  This code is in the public domain.

    https://github.com/kitesurfer1404/WS2812FX


*/

#include "SPI.h"
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#ifndef STASSID
#define STASSID "F4IDM_2T2L"
#define STAPSK "1234567890@"
#endif


unsigned int localPort = 7777;  // local port to listen on
unsigned int remotePort = 8888;  // local port to listen on


// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,

WiFiUDP Udp;
// Set your Static IP Address Settings
IPAddress Claudio(192, 168, 1, 136);
IPAddress local_IP(192, 168, 1, 110);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8); // this is optional
IPAddress secondaryDNS(8, 8, 4, 4); // this is optional

void setup() {
  Serial.begin(115200);
  // Print feedback if the settings are not configured
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
  Serial.println("STA Failed to configure");
}
  
  WiFi.begin(STASSID, STAPSK);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    
    delay(500);
  }
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
    Udp.begin(localPort);


}

void loop() {


   IPAddress Claudio = Udp.remoteIP();
   

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("hello");
    Udp.endPacket();

     
    //print out the remote connection's IP address
    Serial.print ("Claudio");
    Serial.println (Udp.remoteIP());
   // print out the remote connection's IP address
    Serial.printf("UDP server on port", remotePort);
  
delay (3000);
}



  
String splitString(String str, char sep, int index)
{
 int found = 0;
 int strIdx[] = { 0, -1 };
 int maxIdx = str.length() - 1;

 for (int i = 0; i <= maxIdx && found <= index; i++)
 {
    if (str.charAt(i) == sep || i == maxIdx)
    {
      found++;
      strIdx[0] = strIdx[1] + 1;
      strIdx[1] = (i == maxIdx) ? i+1 : i;
    }
 }
 return found > index ? str.substring(strIdx[0], strIdx[1]) : "";
}

votre code configure votre ESP en station à l'adresse 192.168.1.110 d 'un réseau wifi dont le routeur est en 192.168.1.1 avec un subnet à 255.255.0.0

puis vous ouvrez une socket UDP sur le port 7777

qu'attendez vous de cela ?

➜ comme vous n'avez reçu aucune connection entrante, il n'y a pas de client remote.

si vous voulez envoyer un message à Claudio dont l'IP est 192.168.1.136 et qui écouterait sur le port 8888, vous faites

    Udp.beginPacket(Claudio, remotePort);
    Udp.write("hello");
    Udp.endPacket();

Claudio dans son code fera Udp.parsePacket() pour voir s'il a une communication entrante et c'est là qu'il pourra appeler Udp.remoteIP() pour savoir d'où vient (quelle IP) cet appel entrant et Udp.remotePort() pour savoir quel était le port ouvert chez l'appelant

Claudio pourra alors à ce moment répondre en faisant

    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("bien reçu");
    Udp.endPacket();

puisqu'une liaison aura déjà été établie.

J'utilise mon microcontrolleur pour recevoir des données, pour cela je donne un adresse IP et un port pour pouvoir envoyer les informations.

C'est exactement ce que je cherchais de faire !!!! Ça y est j'arrive à communiquer dans le sens ESP8266 -> Ordinateur.
Merci beaucoup à vous J-M-L pour votre patience et pour vos explications très claires.
A partir de cela je vais essayer de construire mon code.
:hand_with_index_finger_and_thumb_crossed:
Vive les forums :star_struck:

parfait :slight_smile:

amusez vous bien

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.