Envoi de variables avec plusieurs ESP8266 vers un Arduino UNO W5100

Bonjour,

Je désire dans un premier temps enregistrer les températures dans ma maison. A cause du WAF je ne peut pas passer de câble partout...
Apres étude je pense installé 2 ESP8266 D1 WiFI qui relèverais chacun un nombre de sonde DS18B20 et de DHT22.
Les 2 ESP8266 enverrais les données à intervalle fixe (ou sur demande...) à un Arduino UNO équipé d'un W5100 qui inscrirais lui même à intervalles défini les valeurs reçu sur la SD + ses valeurs relevés à lui.

Je pense récupéré les valeurs physiquement ou les récupéré via une page web si c'est possible.

Je cherche une piste pour la communication entre les 2 ESP8266 et l'arduino, je pensais via une page web ? en HTTP. ou alors les ESP8266 enverrais les donnés comme ça sur l'IP de l'UNO. si vous avez de meilleurs idée (j'en suis sûr) je suis preneur.

J'ai déjà commencer a voir du coté d'une réponse à une requête en HTTP ( si c'est la bonne voie), mais ça coince entre l'ESP8266 et le Onewire :

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

#include <OneWire.h> 
#include <DallasTemperature.h> 

#ifndef STASSID
#define STASSID "Livebox-****"
#define STAPSK "*****************"
#endif

#define ONE_WIRE_BUS 8

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

DeviceAddress sonde0 =
{
	0x28, 0xAA, 0x89, 0x92, 0x3C, 0x14, 0x01, 0xBF
};

DeviceAddress sonde1 =
{
	0x28, 0xAA, 0x79, 0x8E, 0x3C, 0x14, 0x01, 0x33
};

DeviceAddress sonde2 =
{
	0x28, 0xAA, 0xE5, 0xA8, 0x3C, 0x14, 0x01, 0xDC
};

const char * ssid = STASSID;
const char * password = STAPSK;

float s1, s2, s3;

void setup()
{
	Serial.begin(9600);

	WiFi.mode(WIFI_STA);
	WiFi.begin(ssid, password);

	while (WiFi.status() != WL_CONNECTED)
	{
		delay(500);
		Serial.println(".");
	}
	Serial.println(WiFi.localIP());

	server.on("/", handleRoot);
	server.begin();

	sensors.begin();
	sensors.setResolution(sonde0, 12);
	sensors.setResolution(sonde1, 12);
	sensors.setResolution(sonde2, 12);
}

void loop()
{
	s1 = sensors.getTempC(sonde0);
	s2 = sensors.getTempC(sonde1);
	s3 = sensors.getTempC(sonde2);

	server.handleClient();
	
	delay(10000);
}

String getPage()
{
	String page = "<html lang=fr-FR><head><meta http-equiv='refresh' content='10'/>";
	page += "s1";
	page += s1;
	page += ",";
	page += "s2";
	page += s2;
	page += ",";
	page += "s3";
	page += s3;
	page += "</body></html>";
	return page;
}

void handleRoot()
{
	server.send(200, "text/html", getPage());
}

le terminal me renvoi une série de signe érratique et la page web ne s'affiche plus

0dn,⸮`llE⸮lb8Y⸮⸮?)⸮5!⸮⸮D⸮!⸮?)⸮⸮⸮t⸮DHŸ⸮⸮)⸮⸮⸮⸮⸮DHŸ

Si je commente tout se qui est lié à OneWire et DallasTemperature la page s'affiche sans soucis.

Merci pour vos lumières. :slight_smile:

Bonsoir,

ta problématique semble être de la domotique et il existe déjà plein de protocoles (ouverts) et d'applis (libres) tous fait qui t'éviteront d'avoir a tout développer. Regardes peut-être de ce coté là (perso je ne connais pas mais cherche dans le forum avec le mot clé domotique, ils y a des forumeurs ici qui utilisent, et qui développent, ce genre de solutions).

Maintenant si la curiosité te pousse à vouloir développer ta couche réseau et que tu trouves cela intéressant (c'est mon cas ;-)) alors mes quelques conseils qui valent ce qu'ils valent :wink:

tu évoques de nombreuses possibilités et elles sont toutes possibles :wink: mais je pense qu'il faut séparer les problèmes :

  1. communication entre la UNO et les ESP(s).

La UNO est serveur : le service rendu est de sauvegarder les valeurs

Les ESP sont clients : ils balancent à intervalle réguliers (et/ou leur réveil) une trame qui décrit l'état de leur capteurs (genre une ligne : "esp-1 temp=23.3 hum=82.2")

Là ou cela se complique c'est à cause de ta parenthèse : (ou sur demande...). Cette fois il faut inverser les rôles:

La UNO est client : elle demande aux esp leur état

Les ESP sont serveurs : ils répondent à la UNO.

Ce sont 2 codes différents mais c'est tout à fait faisable. Le second est assez incompatible avec des esp en mode "veille" même si je crois avoir vu qu'on pouvais réveiller un ESP avec une trame.

Bon, après vient le choix de comment faire cela. Tu peux le faire en UDP, en TCP, en HTTP, en MQTT, ...

Dans ce cas là perso j'utilise le multicast UDP (pas testé sur la UNO, seulement sur des ESP). C'est une solution très sympa (pas de notion d'adresse IP individuelle, tout le monde parle à tout le monde en utilisant qu'un seul port UDP). Il y a juste à écouter et agir en fonction de ce qu'on entend. On peut facilement être client et serveur, .... Bon après il y a théoriquement un gros désavantage à se servir d'UDP :

  • si un message est perdu, ni l'émetteur, ni le destinataire ne sont prévenus.

Ce problème est cependant à relativiser dans un réseau local (pas de routeur à traverser) si tu n'es pas en limite de portée wifi cela se passe très bien (les couches Wifi et Ethernet se chargent des retransmission en cas de perte). Dans le pire des cas, faire une reprise sur erreur en cas de non réception d'un acquittement reste programmable.

  1. communication entre le PC et la UNO

Là de nouveau tous les choix sont possibles même si l'idée de ton serveur web (bien couvert sur Internet) hébergé par ta UNO est peut-être la plus simple.

Bon choix :wink:

Bonjour

Si je commente tout se qui est lié à OneWire et DallasTemperature la page s'affiche sans soucis.

#define ONE_WIRE_BUS 8

D8 (GPIO15) est une entrée sortie à éviter, elle sert à définir le mode de fonctionnement lors de la mise sous tension et doit être à l'état bas pour un usage normal.
La résistance de tirage (pull-up) du bus One Wire vient probablement contrarier le bon démarrage.

Je pense récupéré les valeurs physiquement ou les récupéré via une page web si c'est possible.

supercc:
ta problématique semble être de la domotique et il existe déjà plein de protocoles (ouverts) et d'applis (libres) tous fait qui t'éviteront d'avoir a tout développer. Regardes peut-être de ce coté là (perso je ne connais pas mais cherche dans le forum avec le mot clé domotique, ils y a des forumeurs ici qui utilisent, et qui développent, ce genre de solutions).

Il existe pas mal de solutions à base de RASPBERRY PI (Domoticz, Jeedom, HomeGenie, etc.).
Ces serveurs possèdent déjà des fonctionnalités de présentation graphique des températures.

Dans ce cas, les ESP8266 sont clients (en mode veille la plupart du temps donc) et envoient des requêtes JSON au serveur.

Pour Domoticz : Domoticz API/JSON URL's - Domoticz

Oui TCP c'est bien ;-). Teste des petits exemples, les plus simples possibles. On est d'accord, tu laisses tomber le mode veille des esp alors ?

Bonjour

Merci pour ces réponses.

La solutions domotique à base de RASPBERRY PI (Domoticz, Jeedom, HomeGenie, etc.) ne m'intéresse pas pour le moment, je préfère avoir une page html brut avec les données pour le moment.

Petites précision : les ESP8266 seront branchés en permanence sur le 230v.

supercc:
Là ou cela se complique c'est à cause de ta parenthèse : (ou sur demande...).

Je ne savais pas dans qu'elle sens j'allais exécuter les programmes...

Dans le principe :

  • ESP8266 à 7 DS18B20 et 2 DHT22
  • ESP8266 à 4 DS18B20
  • UNO à 3 DS18B20

l'UNO envoi des requêtes aux 2 ESP8266 l'un après l'autre.
il enregistre les variables .
puis
il écrit les variables sur la SD. toutes les xmin.

Ensuite quand j'ai envie de récupéré les données enregistré je les récupère :
-soit physiquement
-soit en c/c sur la page web qui m'aura sortit les data à la ligne.

Petit précision dans un second temps, je raccorderais des relais sur les ESP pour activé des relais mais c'est l'UNO qui décidera en fonction des données reçu par les 2 ESP.

(J’espère avoir été clair dans mes explications)

supercc:
La UNO est client : elle demande aux esp leur état

Les ESP sont serveurs : ils répondent à la UNO.

Je pense partir sur ce style de communication, on interroge l'ESP8266 et il nous réponds avec les valeurs des variables à l'instant T.

Mode TCP ?

je vais m'inspiré de cette page .

Toujours une bonne idée ?

@+

supercc:
Oui TCP c'est bien ;-). Teste des petits exemples, les plus simples possibles. On est d'accord, tu laisses tomber le mode veille des esp alors ?

Oui ils seront branché en permanence

Il y a plus qu'à alors :wink:

Bizarre, ma réponse à ton post #5 est placé avant, en #4 ?!? Tu as effacé ton message et tu l'as recréé ? Pas grave mais cela me donne l'impression d'être devin :wink:

supercc:
Il y a plus qu'à alors :wink:

Bizarre, ma réponse à ton post #5 est placé avant, en #4 ?!? Tu as effacé ton message et tu l'as recréé ? Pas grave mais cela me donne l'impression d'être devin :wink:

Je me suis connecté d'un autre PC et il ma loguer avec google... donc j'ai sup, remis mon identifiant et vous avez poster entre temps. vala vala, vie ma vie :smiley:
je test d'ici peut :slight_smile:
@+

;-). Petite remarque : le code dont tu part est un serveur TCP pour ton shield UNO, or comme c'est lui le client part plutôt sur le code d'un client TCP Ethernet :

Pour les esp (serveurs) part sur un exemple de serveur :

(j'ai pris les premiers exemples trouvés sur le net).

Bonsoir,

Ayant eu un peu de temps j'ai essayer de faire afficher la valeur de 3 sondes de température sur une page web avec succès :

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
#include <OneWire.h>
#include <DallasTemperature.h>

#ifndef STASSID
#define STASSID ""
#define STAPSK  ""
#endif

#define ONE_WIRE_BUS 5
#define TEMPERATURE_PRECISION 12



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

DeviceAddress sonde0 = {0x28, 0xAA, 0x89, 0x92, 0x3C, 0x14, 0x01, 0xBF};
DeviceAddress sonde1 = {0x28, 0xAA, 0x79, 0x8E, 0x3C, 0x14, 0x01, 0x33};
DeviceAddress sonde2 = {0x28, 0xAA, 0xE5, 0xA8, 0x3C, 0x14, 0x01, 0xDC};

const char* ssid = STASSID;
const char* password = STAPSK;

float s1, s2, s3;

void setup() {

  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println(".");
  }
  Serial.println(WiFi.localIP());

  server.on ( "/", handleRoot );
  server.begin();
  sensors.begin();
  sensors.setResolution(sonde0, 12);
  sensors.setResolution(sonde1, 12);
  sensors.setResolution(sonde2, 12);
}

void loop() {

  server.handleClient();


}

String getPage() {
  sensors.requestTemperatures();
  s1 = sensors.getTempC(sonde0);
  s2 = sensors.getTempC(sonde1);
  s3 = sensors.getTempC(sonde2);
  String page = "A"; //"<html lang=fr-FR><head><meta http-equiv='refresh' content='10'/>";
  page += s1;
  page += ",";
  page += s2;
  page += ",";
  page += s3;
  page += "</body></html>";
  return page;
}

void handleRoot() {

  server.send ( 200, "text/html", getPage() );
}

Puis j'ai essyer de le faire afficher sur un Uno avec un sketch client:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 49);

// Enter the IP address of the server you're connecting to:
IPAddress server(192, 168, 1, 48);



EthernetClient client;

void setup() {

  Ethernet.init(10);  // Most Arduino shields


  // start the Ethernet connection:
  Ethernet.begin(mac, ip);

  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  while (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
    delay(500);
  }

  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }

}

void loop() {

  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.connect(server, 80)) {
    char c = client.read();
    Serial.print(c);
  }

  // as long as there are bytes in the serial queue,
  // read them and send them out the socket if it's open:
  while (Serial.available() > 0) {
    char inChar = Serial.read();
    if (client.connected()) {
      client.print(inChar);
    }
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    // do nothing:
    while (true) {
      delay(1);
    }
  }

}

Mais il me retourne dans le terminal

connecting...
connected
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

Je pense que le sketch client n'est pas bon

Bonsoir,

bravo pour le serveur.

Cependant tu n'aurais pas changé les règles du jeu ? :wink:

Car là tu viens de créer un serveur HTTP sur les ESP. Tu laisses tomber TCP ?

Pour le client (la UNO) tu parlais qu'il soit serveur HTTP et là il est client HTTP (normal pour récupérer les valeurs des ESP), mais il sera également à terme serveur HTTP ou ... ? Je demande parce que pour l'instant ton code cherche à écrire sur le port série (première étape ?). De plus il cherche a établir une communication bidirectionnelle sur ce port. Pourquoi pas mais je ne comprends pas pourquoi (pour moi, les requêtes viennent du réseau, pas du port série ?

Que doit faire exactement le client (algorithme ?) ?

supercc:
Bonsoir,

bravo pour le serveur.

Cependant tu n'aurais pas changé les règles du jeu ? :wink:

Car là tu viens de créer un serveur HTTP sur les ESP. Tu laisses tomber TCP ?

Bonjour j'ai du me mélanger les pinceaux ^^
Je me suis dit que si les valeurs de l'ESP apparaisse sur une page web on peut les récupérés avec l'UNO ? non ? ou y'a plus simple, j'ai pas piger vos liens et mes recherche avec le TCP, sur le site d'eskimon.fr avec le site perdu.com il en parle mais j'ai essayer de modifier pour mon cas sans succès, du coup je me rapatrie sur le HTTP.

supercc:
Pour le client (la UNO) tu parlais qu'il soit serveur HTTP et là il est client HTTP (normal pour récupérer les valeurs des ESP), mais il sera également à terme serveur HTTP ou ... ? Je demande parce que pour l'instant ton code cherche à écrire sur le port série (première étape ?). De plus il cherche a établir une communication bidirectionnelle sur ce port. Pourquoi pas mais je ne comprends pas pourquoi (pour moi, les requêtes viennent du réseau, pas du port série ?

Que doit faire exactement le client (algorithme ?) ?

Dans l'idée L'UNO ( en mode client) fait une demande à l'ESP ( en mode serveur) récupère les valeurs des 3 sondes et les enregistre en tant que variable, pour le moment je voulais les faire affiché dans le terminal de l'UNO ( j'avance étape par étape :slight_smile: ).
@+

j'ai du me mélanger les pinceaux ^^

Tu t'attaques à une partie assez complexe : Multi cartes (UNO/ESP), multi rôles (client/serveur) et protocole multiples (Wifi/Ethernet + TCP/HTTP).

Comme je l'ai déjà dit, tu peux théoriquement tout faire avec n'importe lequel des protocoles mais la solution serveur TCP coté ESP te simplifiera, par rapport à un serveur HTTP, l'analyse de la réponse HTTP pour extraire l'information. Maintenant ce n'est que mon point de vue.

j'ai pas piger vos liens et mes recherche avec le TCP,

Voici un code serveur TCP (écoutant sur le port 1234) pour l'ESP qui retournera au client (dès sa connexion sans même qu'il demande quoi que se soit) une température et une humidité fictive. Il affiche son adresse IP sur la liaison série (19200 bauds).

#include "ESP8266WiFi.h"
 
const char* ssid = "tonSSID";
const char* password = "tonMDP";
 
WiFiServer wifiServer(1234);

float temp=23.4, hum=80.0;

void setup() {

  Serial.begin(19200);
  
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) delay(100);
    
  Serial.print("Connected to WiFi. IP:");
  Serial.println(WiFi.localIP());
 
  wifiServer.begin();
}

void loop() {
	WiFiClient client = wifiServer.available();
 
	if (client) {
			char message[80];
			sprintf(message,"temp=%.1f hum=%.1f\n", temp, hum);
			client.println(message);
    }
}

Voici le code client TCP (coté UNO). Il faudra que tu renseignes l'IP du serveur dans la variable du serveur. Je l'ai écrit pour ESP car je n'ai pas de shield Ethernet. Normalement (pas testé) il faut justes que tu adaptes la connexion (au réseau filaire).

#include "ESP8266WiFi.h"
 
const char* ssid = "tonSSID";
const char* password = "tonMDP";

WiFiClient client;
IPAddress server(192, 168, 2, 131); // <- mettre l'IP du serveur

// Pour UNO (enfin je pense)
EthernetClient client;
byte server[] = { 192, 168, 2, 131 }; // <- mettre l'IP du serveur


void setup()
{
  Serial.begin(19200);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(100)
 
  Serial.print("Connected to WiFi. IP:");
  Serial.println(WiFi.localIP());
}

void loop() {
	if (client.connect(server, 1234)) {
		char response[80];
		int len;
		if((len=client.readBytesUntil( '\n', response, 80))) {
			response[len]=0; // remplace l'\n final par une fin de chaîne (0 = '\0')
			Serial.printf("Response:%s\n", response);
		}
		client.stop();
	}
	else Serial.println("NOT connected !");

	delay(1000);
}

Comme tu peux le voir le code est court. A mon avis, vouloir simplifier en ne gardant que de l'HTTP n'est pas optimale dans ton cas.

Super !
j'ai adapter le sketch pour le code serveur pour envoyer la valeur des 3 sondes ,
et modifier le tcp client pour recevoir les infos dans le terminal.

Et ça fonctionne parfaitement

s1=23.2 s2=31.6 s3=24.1

:slight_smile:

Maintenant pour extraire les données reçu pour les séparé et les enregistrés dans des variables distinctes, j'ai pigé que :

   if((len=client.readBytesUntil( '\n', response, 80))) {
      response[len]=0; // remplace l'\n final par une fin de chaîne (0 = '\0')
      Serial.println(response);
    }

que "client.readBytesUntil" et '\n' imprime toute la chaine de caractère reçu mais pas "un extrait " soit j'extrait tout avant une chaine ou tout apres ...

tu peux "décortiquer" ligne de la façon suivante:

char line[]="s1=23.2 s2=31.6 s3=24.1";  // pour l'exemple
float s1, s2, s3;
sscanf(line,"s1=%f s2=%f s3=%f", &s1, &s2, &s3);

La ligne scanf décode les flottants (%f) et les place dans les variables dont on précise l'adresse.

Petit précision dans un second temps, je raccorderais des relais sur les ESP pour activé des relais mais c'est l'UNO qui décidera en fonction des données reçu par les 2 ESP.

Je vais m'absenter quelques jours alors voici une solution pour avoir, en TCP, un client récupérant des variables sur un serveur (port 1234), et étant aussi capable de fixer les valeurs d'une variable (sur le serveur).

Dans l'exemple les variables à récupérer sont hum et temp, et la variable à récupérer et à fixer est relais (un entier).

Comme précédemment il faudra que tu renseignes l'IP du serveur et que tu adaptes la connexion filaire pour ta UNO.

Ces codes sont dans un style "à la C". Les messages sont codés/décoder à l'aide des fonctions de la famille printf/scanf (très bien documentées sur Internet). Mais rien n'empêche de véhiculer autre chose et de coder/décoder autrement (je pense à du JSON) tout en utilisant le flux TCP (cf. fonction request).

Bonne chance.

Code du serveur :

#include "ESP8266WiFi.h"

#define MAX_LEN 80 // Taille max des questions/réponses
#define DEBUG // a décommenter pour tracer les échanges TCP sur Serial.

const char* ssid = "tonSSID";
const char* password = "tonMDP";
 
WiFiServer wifiServer(1234);

float temp=23.4, hum=80.0;
int relais; // état du relais

void setup() {

  Serial.begin(19200);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) delay(100);
   
  Serial.print("Connected to WiFi. IP:");
  Serial.println(WiFi.localIP());
 
  wifiServer.begin();
}

void loop() {
	
	// attend un client, analyse sa requête et réponds
	
	WiFiClient client = wifiServer.available();
 
	if (client) {
			
			char message[MAX_LEN];
			char response[MAX_LEN]="";
			int len;
			
			if((len=client.readBytesUntil('\n', message, MAX_LEN))) {
				
				message[len]=0; // force la fermeture de la chaîne
				
				// retire l'\n final s'il existe
				
				if(message[strlen(message)-1]=='\n') 
					message[strlen(message)-1]=0;
				
				#ifdef DEBUG
				Serial.printf("server recv:%s\n", message);
				#endif

				// relais
				
				 if(!strncmp(message,"relais=",7)) {
					sscanf(message, "relais=%d", &relais);
					sprintf(response,"ok");
				}
				
				// dump
								
				else if(!strcmp(message,"dump")) {
				
					// peut être le moment de mettre à jour les valeurs des capteurs
					// ...
					sprintf(response,"relais=%d temp=%.1f hum=%.1f", relais, temp, hum);
				}
				
				
				// Other
				
				else 
					Serial.printf("ERROR : %s !\n", message);
			}
			
			client.printf("%s\n", response);
    }
}

Code du client :

#include "ESP8266WiFi.h"
 
#define MAX_LEN 80 // Taille max des questions/réponses
#define DEBUG // a décommenter pour tracer les échanges TCP sur Serial.

const char* ssid = "tonSSID";
const char* password = "tonMDP";

IPAddress server(192, 168, 2, 129); // <- mettre l'IP du serveur

// Pour UNO (enfin je pense)
//EthernetClient client;
//byte server[] = { 192, 168, 2, 129 }; // <- mettre l'IP du serveur


int relais; 		// état du relais qu'il faut récupérer et fixer
float hum, temp;    // reflet des capteurs du serveur.

void setup()
{
  Serial.begin(19200);
 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(100);
 
  Serial.print("Connected to WiFi. IP:");
  Serial.println(WiFi.localIP());
}

// Fonction pour un échange de type question/réponse avec un serveur TCP.
// Cette fonction émet message et attend la réponse qu'elle placera dans la chaine response.
// len est la taille allouée pour la réponse (la taille de la chaîne response).

int request(IPAddress server, uint16_t port, char *message, char *response, unsigned len) {
	
	WiFiClient client;
	
	if (client.connect(server, 1234)) {
		
		#ifdef DEBUG
		Serial.printf("Client : send : %s\n", message); 
		#endif
		
		// retire l'\n final s'il existe
		if(message[strlen(message)-1]=='\n') 
			message[strlen(message)-1]=0;
		
		client.printf("%s\n", message);
		
		// attente de la réponse (voir Stream.setTimeout())
		if((len=client.readBytesUntil('\n', response, MAX_LEN))) {
			response[len]=0; // force la fermeture de la chaîne
			// retire l'\n final s'il existe			
			if(response[strlen(response)-1]=='\n') 
				response[strlen(response)-1]=0;
			#ifdef DEBUG
			Serial.printf("Response for %s : %s.\n", message, response); 
			#endif
		}
		client.stop();
		return 1; // true
	}
	
	return 0; // false
}

void loop() {
	char message[MAX_LEN];
	char response[MAX_LEN];
	int len;
	
	// Dump	
	sprintf(message, "dump", relais);
	if(!request(server, 1234, message, response, MAX_LEN)) 
		Serial.printf("ERROR client : no response for : %s\n", message);	
	else {
		//Serial.printf("dump response:%s.\n", response);
		if(sscanf(response,"relais=%d temp=%f hum=%f", &relais, &temp, &hum) != 3)
			Serial.printf("ERROR client : bad response for dump : : %s\n", response);	
		else Serial.printf("relais=%d temp=%.1f hum=%.1f\n", relais, temp, hum);
	}			
	
	// les variables relais, temp et hump reflètent l'état des variables du serveur.
    // En fonction de leurs valeurs on détermine la nouvelle valeur du relais
	
	int relaisNew=0;
	//if(temp>30 || hum>80) relaisNew=1;
	// ou,  pour forcer un changement d'état du relais (test)
	relaisNew=!relais; 
	
	if(relaisNew != relais) {
		sprintf(message, "relais=%d", relaisNew);
		if(!request(server, 1234, message, response, MAX_LEN)) 
			Serial.printf("ERROR client : no response for : %s\n", message);
		else if(strcmp(response, "ok"))
			Serial.printf("ERROR client : bad response for %s : %s\n", message, response);	
	}
	delay(1000);
}

EDIT : ajout du loop du client.

supercc:
tu peux "décortiquer" ligne de la façon suivante:

char line[]="s1=23.2 s2=31.6 s3=24.1";  // pour l'exemple

float s1, s2, s3;
sscanf(line,"s1=%f s2=%f s3=%f", &s1, &s2, &s3);




La ligne scanf décode les flottants (%f) et les place dans les variables dont on précise l'adresse.

Bonjour,
J'ai vu que le sscanf ne supporte pas les float sur arduino :
LOCODUINO - Trucs, astuces et choses à ne pas faire ! erreur #24

J'ai essayer en int :

int *ps1, *ps2, *ps3;
int s1, s2, s3;

void setup()
{
 Serial.begin(9600);

  ps1 = &s1;
  ps2 = &s2;
  ps3 = &s3;

  char line[] = "s1=23.2 s2=31.6 s3=24.1"; // pour l'exemple

  sscanf(line, "s1=%f s2=%f s3=%f", &s1, &s2, &s3);

  Serial.print(*ps1);
  Serial.print(*ps2);
  Serial.println(*ps3);
}

void loop() {
}

Sans succes ...

@+

Bonjour,

Comme tu l'as dit %f ne fonctionne pas.
Tu peux passer par des chaines de caractères puis les convertir.

float s1, s2, s3;

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

  char line[] = "s1=23.2 s2=31.6 s3=24.1"; // pour l'exemple

  char buf1[8],buf2[8],buf3[8];

  sscanf(line, "s1=%s s2=%s s3=%s", buf1, buf2, buf3);

  s1=atof(buf1);
  s2=atof(buf2);
  s3=atof(buf3);
  
  Serial.print(s1); Serial.print("  ");
  Serial.print(s2); Serial.print("  ");
  Serial.println(s3);
}

void loop() {
}

Nickel

Merci supercc et kamill !

Je continu ...

@+